d:id:Nabetani:20070820, d:id:Nabetani:20070822, d:id:Nabetani:20070823, d:id:Nabetani:20070827 の続き。
数式の形で表すのは面倒なので、ruby のソースで:
require 'rational' def dc( people, non, one, twomore ) (@h||={})[[people, non, one, twomore]]||= # cache. if people==0 && one==0 && twomore==0 1 else r = (0..people) if ! r.include?( one ) || ! r.include?( twomore ) || non<0 0 else ( non+1 ) * dc( people-1, non+1, one-1, twomore ) + ( one+1 ) * dc( people-1, non, one+1, twomore-1 ) + ( twomore ) * dc( people-1, non, one, twomore ) end end end N=6 (1..ARGV[0].to_i).each{ |pe| s = (0..N).inject(0){|sum,i| sum += dc(pe,i,0,N-i) } puts( "%3d : %s"%[pe,1-Rational(s)/N**pe] ) }
見ての通り、漸化式になっている。そして、フィボナッチの列と同様、行列の積の形に書き直すことができる。そうすると、先日書いた A(M**n)S という形になる。この式は簡単な式に見えるが、M は30×30の行列(6面ダイスの場合)になる。行列が巨大なので素直に計算すると大変だが、Mはたぶん対角化することができる。指数の線形和みたいな形の一般項も求まるんだと思う。
関数 dc は、dc(人数, まだ出てない目が何個あるか, ひとりグループが何個あるか, 二人以上のグループが何個あるか) ということ。素直に漸化式になっている。
それとは別に、d:id:Nabetani:20070823 で書いた計算。D面ダイスで、n人だと
こんな感じ。
あーこの式は、場合の数。題意の通りの確率にするには D**n で割ればいい。
この式に至る経緯はちょっと説明が面倒なんだが、場合の数の計算そのまんま。A君がひとりグループになる場合、A君とB君がひとりグループになる場合、A君B君C君がひとりグループになる場合……と足したり引いたりした結果である。
で。
どっちが一般項らしいかという話なんだが。
それは私にもよくわからない。