乱列を関数EUで

1.封筒ちがい・乱列
有名なパズル?がある。[br][br]「n通の封筒に1枚の手紙を入れて出したい。手紙にも、封筒にもn個の宛先がかいてあるのだが、[br]封筒と手紙の宛先がすべて不一致になるような入れ方は何通りか」[br][br]という、[b]封筒違い問題[/b]と言われているものだ。[br]言い換えると、1からnの数を並べるときに、[br]左からどの順番の数を見ても[b][color=#0000ff]番号と数が一致しない並べ方[/color][/b][br][b][size=200][size=150][color=#0000ff]不一致状態、乱れた数列、攪乱順列[/color][/size][/size][/b]になっていることから、[br][b][color=#0000ff][size=150][size=200]乱列[/size][/size][/color][/b]と呼ばれたりもする。[br][br][b]モンモール[/b]さんが1708 年に、n = 13の場合に出題したものを、[br]あの偉大な数学者[b]オイラー[/b]さんが解いたという話も見聞きします。[br]真偽はともかく、オイラー関数の式を展開すると、以下にのべることにつながり、[br]さらに、順列を確率にしたときの値がオイラーとつながりのあるマクローリン級数展開と関連します。[br]。。。。。。[br][br]それはさておき、[br]具体的に調べてみよう。[br]n=1なら0通り。[br]n=2なら「21」の1通り。[br]n=3なら、「231,312」の2通り。[br]n=4なら、「2143,2341,2413,[br]      3142,3412,3421,[br]      4123,4312,4321」の9通り。[br]このくらいならなんとかなるが、n=5以上では神経衰弱になってきそうだ。[br]そこで、救いの神の登場だ。[br][b][color=#0000ff][size=150]包含と排除の原理(包除原理、Principle of Inclusion and Exclusion, 略してPIE)[br][/size][/color][/b]を使って考えてみよう。[br][br]と言ってもPIEって何?[br]という人向けに確認しよう。[br][br][b][size=150]<PIEとは何か>[br][br][/size][/b]全体集合の中に対象の集合がある。[br]それら対象の集合に含まれない要素数を求める原理がPIEだ。[br]・集合が1個のとき[br][color=#0000ff] [b]NotA[/b][b]=|U|-|A|[/b][br][/color] =n(U)-n(A)[br]・集合が2個のとき[br] 集合Uの中のAでもBでもない個数を出すには集合の個数n(集合)を使うと、[br][color=#0000ff] [b]NotAB=|U|-|A∪B|[/b][br][/color] =n(U) - {n(A)+n(B)-n(A∩B)}=[b]n(U)- n(A)-n(B)+ n(A∩B)[/b]となるのは小中で学んでいるね。[br]・集合が3個のとき[br] 集合Cを追加すると、Cのうち、AでもBでもないものdiff=n(not(A∪B)∩C))を取り除く。[br] NotABのUをCに、他を他∩Cに置き換えると、[br][b] diff=n(C) - {n(A∩C)+n(B∩C)-n(A∩B∩C)}=n(C)- n(A∩C)-n(B∩C)+ n(A∩B∩C)だね。 [br][/b][b][color=#0000ff]NotABC=|U|-|A∪B[b]∪C[/b]|[br][/color][/b] =NotAB-diff=n(U)- n(A)-n(B)+ n(A∩B)-(n(C)- n(A∩C)-n(B∩C)+ n(A∩B∩C))[br] [b]=n(U)- n(A)-n(B)-n(C)+ n(A∩B)+ n(A∩C) +n(B∩C)- n(A∩B∩C)[br][/b]・集合が4個のとき[br] 集合Dを追加すると、diff=n(not(A∪B∪C)∩D)を取り除くために、[br] NotABCのUをDに、他を他∩Dに置き換える。[br] [b]diff=n(D)- n(A∩D)-n(B∩D)-n(C∩D)+ n(A∩B∩D)+ n(A∩C∩D) +n(B∩C∩D)- n(A∩B∩C∩D)[br] [color=#0000ff]NotABCD[/color][b][color=#0000ff]=|U|-|A∪B[b]∪C[b][b][color=#0000ff]∪D[/color][/b][/b][/b]|[br][/color][/b][/b] =NotABC-diff=n(U)- n(A)-n(B)-n(C)+ n(A∩B)+ n(A∩C) +n(B∩C)- n(A∩B∩C)[br] -(n(D)- n(A∩D)-n(B∩D)-n(C∩D)+ n(A∩B∩D)+ n(A∩C∩D) +n(B∩C∩D)- n(A∩B∩C∩D)) [br] [b]= n(U)- n(A)-n(B)-n(C)-n(D)+ n(A∩B)+ n(A∩C) +n(B∩C)+n(A∩D)+n(B∩D)+n(C∩D)[br] - n(A∩B∩C)- n(A∩B∩D)- n(A∩C∩D) -n(B∩C∩D)+ n(A∩B∩C∩D))[br] =n(U)- Σn(X) +Σn(X∩Y)-Σn(X∩Y∩Z)+Σn(X∩Y∩Z∩P)[br][/b][br]・集合がN個のときの[br][color=#0000ff][b][size=200] PIEの一般化[/size][/b][/color][br][b][color=#0000ff][size=150][size=200] Notどれか=u(U)+Σ(-1)[sup]p[/sup]Σn(ΠX[sub]p[/sub])[br] [/size][/size][/color][/b](Πはp個の集合の積集合でその組み合わはnCp個ある。符号は−1のp乗。[br]このように、個数を1個ずつ増やしている。[br]これは証明とは言えないが、[b]数学的帰納法で証明できるでしょう[/b]。だから、証明は省略。[br][br]ぜんぜん簡単に見えないかもしれないので、使い方を小さい順に確認しよう。[br][b]全体集合をm個すべての順列 m! [/b]としよう。[br]対象とする集合の要素数は番号と数が一致している順列だ。[br]だから、[br][b][color=#0000ff]n(A)は番号1が一致している順列 = (m-1)!、[br]n(B)は番号2が一致している順列 = (m-1)!、[br]n(A∩B)は番号1と2が一致している順列 = (m-2)!, ..、[br]n(A∩B∩C)は番号1,2,3が一致している順列 = (m-3)!, .....[br][/color][/b]という意味に読み替えよう。[br]すると、集合の重なりが少ないほど、一致する指定が少ないので、その他のけたは,ただの順列になる。[br]このように、[b]集合の個数を順列の個数に読み替えていこう。[br][/b][br]・集合が1個なら「1」の順列。[br] 乱列は、数字1の順列になり、全体の順列も1だから1通りの差は0。[br][b][color=#0000ff]・集合が2個なら「12」の順列。[br] 乱列は数字12の順列から(1が一致する場合数と2が一致する場合数)をひき2つ一致の場合たす。[br] 2!ー(1+1)+1=1通り。[br][/color][/b]・集合が3個なら「123」の順列。[br] 乱列=全順列ー(123のどれか1個一致)+(123のどれか2個一致)ー(123の3個一致)[br] =3!ー3×2!+3×1!ー1=6ー6+3−1=2通り。[br]・集合が4個なら「1234」の順列。[br] 乱列=全順列ー(1個一致)+(2個一致)ー(3個一致)+(4個一致)[br] =4!- 4C1×3! + 4C2×2! - 4C3×1! + 4C4×0! = 24 - 4×6+6×2 - 4 +1=9通り。[br][b] [color=#0000ff] (ここで、(k個一致)はnCk×(n-k)!と気づく。) [br][/color][/b]・[b]集合が5個[/b]なら、[br] 乱列=5! - 5C1×4! + 5C2×3! - 5C3×2! + 5C4×1! - 1 = 5C3×3! - 5C2×2! + 5C1×1!- 1[br][b][color=#0000ff]  (ここで、(k個一致)はnC(n-k)×(n-k)!=nPkと気づく。最初の2項は相殺されることも気づく。)[br][/color][/b] =[b][color=#0000ff]5P3- 5P2+5P1-1[/color][/b]=60 - 20 + 5 -1 = 44通り。 [br]・[b]集合が6個なら、乱列=[color=#0000ff]6P4 - 6P3 + 6P2 - 6P1 + 1[/color] [/b]= 265通り。[br]・[b]集合が7個なら。乱列=[color=#0000ff]7P5 - 7P4 + 7P3 - 7P2 + 7P1 - 1[/color][/b]= 1854通り。[br]・集合がN個の一般化 乱列=nP[sub]n-2[/sub] - nP[sub]n-3[/sub]+....(-1)[sup]n-i[/sup] nP[sub]n-i[/sub] +(-1)[sup]n-1[/sup]nP[sub]1[/sub]+(-1)[sup]n[/sup] = [b]Σ(-1)[sup]n-i[/sup] nP[sub]n-i[/sub] (2 <=i<=n)[/b][br] 乱列= [math]n!\sum_{k=2}^n\frac{\left(-1\right)^k}{k!}[/math] 分配法則でn!でまとめるとこうなる。[br] もともとは、[b][color=#0000ff]数列nP[sub]n-2、[/sub]nP[sub]n-3 [/sub],....., nP[sub]1[/sub],1 にー+を交互つけた和[/color][/b]のことだね。[br] マクローリン展開を知っている人は[br] [math]e^x=1+\frac{x}{1!}+\frac{x^2}{2!}+\frac{x^3}{3!}+..............[/math]を思い出すでしょう。[br] すると、極限としては、[b][size=200][color=#0000ff]乱列→n! e[sup]-1[/sup][/color][/size][sup][/sup][/b][br]となるね。[br]地道に神経衰弱をくり返して書き出す作業の[b]限界突破[/b]ができる。[br]また、乱列数を分子として、n!を分母にすると、[br]乱列になる確率が約e[sup]-1[/sup]=0.367879(約37%)にすぐに近づく![br]すばらしい!
e^xの級数展開を目でみよう
[color=#9900ff][b][size=200]質問:この発想で、nけたの乱列数をもとめるコードはどうすれば作れるでしょうか。[br][/size][/b][/color][br]n!でまとめて、分数形を使ってΣを先にやると分数の和に階乗をかけることになる。[br]あまりプログラミング向きではないですね。[br]permutationsで文字列として作り出すのではなく、ただのnPrの計算だね。[br]だから、itertoolsではなくて、mathパッケージでperm(n,r)でnPrが計算できることを確認しよう。[br]からこれでやろう。[br]pnPn-2からnP0まで符号を入れ替えながら合計したい。[br][b]だから、perm(n,n-x)のxに2からnをいれて符号をつけたリストを作り、それをsumすればよいね。[br][br][size=200][color=#0000ff]オイラーに敬意を表して、nの乱列数は関数Eu(n)としました。[br][/color][/size][/b][br][color=#0000ff]#[In] Python[br]#===============================================[br]# サイズnの乱列関数En(n)[br]from math import perm[br]def Eu(n):[br]return[b] [u]sum([(-1)**x * perm(n,n-x) for x in range(2,n+1)])[br][/u][/b]#==============結果===========[br]for i in range(1,10):[br] print(f"Eu({i}) = {Eu(i)} ",end=",")[br]#===============================================[br][OUT][br]Eu(1) = 0 ,Eu(2) = 1 ,Eu(3) = 2 ,Eu(4) = 9 ,Eu(5) = 44 ,Eu(6) = 265 ,Eu(7) = 1854 ,Eu(8) = 14833 ,Eu(9) = 133496 ,[/color]
乱列とe^(-1)
2.動的にみると
動的にみるとどうなるだろう。[br][br]Eu(1) = 0 ,Eu(2) = 1 ,Eu(3) = 2 ,Eu(4) = 9 ,Eu(5) = 44 ,Eu(6) = 265 ,Eu(7) = 1854 ,Eu(8) = 14833[br]Eu(3)=2=1*3-1[br]Eu(4)=9=2*4+1[br]Eu(5)=44=9*5-1[br]ここから、[color=#0000ff][b][size=200]Eu(n)=Eu(n-1)*n+(-1)[sup]n[/sup][/size][/b][/color]という面白い関係に気づく。[br]実際,[br]Eu(6)=Eu(5)*6+1=44*6+1=265で合ってる。[br][br]でも、これでは、符号が交互になってしまう。[br][br]そこで公差をとってみた。[br]うまくいかない。[br]差ではなく和をやってみよう。[br]Eu(1)+Eu(2)=1[br]Eu(2)+Eu(3)=3[br]Eu(3)+Eu(4)=11[br]おっ44の約数がきたね。44=Eu(5)=11*4=(Eu(3)+Eu(4))*(5-1)となってる。[br]これから、[color=#0000ff][b][size=200]Eu(n)=(Eu(n-2)+Eu(n-1))*(n-1)[/size][/b][/color]が予想できる。[br]実際に、[br]Eu(6)=265=(9+44)*5=53*5=265。よさそうですね。[br][br]
3.漸化式を意味づけする
さっきは[br]動的に考えることで、[br]2種類の漸化式ができた。[br]最後にできた方の意味づけを考えてみよう。[br][br][b][size=150]EU(n)=(EU(n-2)+EU(n-1))*(n-1)[br][/size][/b][br]これはこの式のままではないけれど、中学入試などにもでるストーリー化がある。[br]それを確認しておこう。[br]たとえば、[br][br][color=#0000ff][b][size=200]EU(4)=(EU(2)+EU(3))*3[br][/size][/b][/color][br]箱1から箱4までに玉1から玉4までが番号不一致で入っているとしよう。[br]ここから箱4がない状態に遡ってみる。[br]どうするか?[br]箱4に入っている玉は1,2,3の3通りあるので、とりあえず1番としよう。[br]このとき、1番の箱の中を見たとき、[br][b]箱1に入っている玉の番号は4番か4番でないかの2タイプがあるね。[br][/b][br][b]・箱1が玉4番であるタイプA[br][/b]箱4の玉1と箱1の玉4を入れ替えると[br][b]箱4は玉4でいいけど、箱1が玉1になるので、1個一致パターンになってしまう。[br][/b]しかし、箱4と箱1を撤去すると、のこり2箱は不一致になっているはずだ。[br]つまり、2箱不一致状態には合格している。[br][br][b]・箱1が玉4番でないタイプB[br][/b]箱4の玉1と玉4のある箱x(1でない)の玉4を入れ替えると[br][b]箱4は玉4で、箱x(1でない)が玉1になるので箱1から箱3まで3箱不一致パターンに合格してる。[br][/b][br]つまり、さかのぼると、[br]4箱不一致パターンの先祖は、箱4の玉番号で3分の1に絞り込める。[br]それが箱4の玉の番号の箱に入っている玉の番号で[br]2タイプ(タイプA2箱不一致かタイプB3箱不一致)に絞れる。[br]絞ったとしても場合の数はそれぞの乱列数だけある。[br][br]ということは、EU(4)は(EU(2)+EU(3))*(4-1)でがすべて尽くせることになるね。[br][br]逆に、箱が少ない段階をもとにして、箱4の番号不一致状態がすべて作れるはずだ。[br]タイプA)[br]箱1に玉1を入れて、箱2,3は不一致状態にしたとしょう。[br]ここに箱4に玉4を入れて追加したあと箱1と箱4の玉交換で4箱不一致ができるね。EU(2)個できる。[br]箱1ではなく、箱2,箱3でも同様だから、EU(2)*3の4箱不一致が作れる。[br]タイプB)[br]3箱不一致のときに箱1の玉を取り出して箱4に入れて、玉4を代わりに入れる。EU(3)個できる。[br]取り出す箱を、1番でなはく、2番,3番と変えられるからEU(3)*3の4箱不一致を作ることができる。[br][br]以上をあわせて、EU(2)*3+EU(3)*3がEU(4)になるね。[br]

Information: 乱列を関数EUで