パターン数は?

 投稿者:GAI  投稿日:2010年 4月26日(月)20時29分31秒
  次のような問題を解決できるためには、どんな構成のプログラムなのか知りたい。

(1)白2個、赤2個、青2個(見分けが付かないと仮定する。)
を円順列にした場合の違いのパターン数は?
実際の配列と、これを一般化(個数を変えたり、種類を増やしたりできるように・・・)
するにはどんなプログラムなのか?


(2)同じものがそれぞれたくさんある3色のビーズで、腕輪を作るとする。
ビーズをP個使って作るとすれば、腕輪は何通り出来るか?

P:4,5,6,7,8,9での実際の配列を作り出してもらいたい。

またこれを一般化して異なるm色のビーズで合計p個のビーズの腕輪を作ると異なるものは何個になるのでしょうか?
これは式で書けるのでしょうか?(ただし、裏返しは考えないものとします。)
 

Re: パターン数は?

 投稿者:山中和義  投稿日:2010年 4月27日(火)10時37分52秒
  > No.1202[元記事へ]

GAIさんへのお返事です。

> 実際の配列と、これを一般化(個数を変えたり、種類を増やしたりできるように・・・)
> するにはどんなプログラムなのか?

No.1199[元記事へ] または No.1200[元記事へ]では、
(直線)順列が生成できるので、これを元に作成できると思います。
ただ、符号化・復号化、辞書順による生成ができませんので、
「パターンそのもの」を記録して、既出のものかどうかのチェックになると思います。
具体例は以下のプログラムを参考にしてください。

「問題1」は、(1つ前段階ですので)そのサンプルを掲載します。
「エラトステネスの篩い」のように、辞書順(自然数の小さい順)にパターンを生成して、
その対称のもの(倍数)を除いていきます。
「篩い」は、符号化・復号化して「0以上の整数」で管理しています。

!白2個、赤2個、青2個を円順列にした場合の数は?


LET N=3 !異なる色の数
DATA 2,2,2 !(白,赤,青)の個数

!PUBLIC STRING S$
LET S$="白赤青"


DIM C(N) !それぞれの個数
MAT READ C

LET S=0 !総数
FOR i=1 TO N
   LET S=S+C(i)
NEXT i
IF S<R THEN
   PRINT "数が足りません。";S
   STOP
END IF

DIM G(S) !(白,赤,青)の並び
MAT G=ZER

DIM F(0 TO PermFactorialM(C,N)-1) !篩い
MAT F=ZER

LET x=0
FOR i=0 TO PermFactorialM(C,N)-1 !「同じものを含む順列」を円型に並べる

   CALL Num2PermFactorialM(i, G,S,C,N)
   IF F(i)=0 THEN

   !MAT PRINT G;
      FOR k=1 TO S !「素」の並びを表示する
         PRINT S$(G(k):G(k));
      NEXT k
      PRINT
      LET x=x+1 !+1

      !!!CALL FilterNecklace(F,G,S,C,N) !反転(裏返し) ※数珠順列 ←←←←←

      FOR j=1 TO S-1 !篩いにかける
         LET w=G(1) !右シフト ※時計まわりに回転する
         FOR k=1 TO S-1
            LET G(k)=G(k+1)
         NEXT k
         LET G(S)=w

         LET F(PermFactorialM2Num(G,S,C,N))=1 !この並びは対称なため削除する

         !!!CALL FilterNecklace(F,G,S,C,N) !反転(裏返し) ※数珠順列 ←←←←←
      NEXT j

   END IF

NEXT i

PRINT "場合の数=";x

END


EXTERNAL SUB FilterNecklace(F(),G(),S,C(),N) !反転(裏返し)の篩い
DIM GR(S)
MAT GR=G !反転(裏返し)
CALL reverse(GR,S)
LET F(PermFactorialM2Num(GR,S,C,N))=1 !この並びは対称なため削除する
END SUB

EXTERNAL SUB reverse(A(),N) !並びを逆順にする
FOR i=1 TO INT(N/2)
   LET t=A(i) !swap it
   LET A(i)=A(N-i+1)
   LET A(N-i+1)=t
NEXT i
END SUB


EXTERNAL FUNCTION PermFactorialM(B(),M) !同じものを含む順列の「場合の数」 (p+q+ … +r)!/(p!*q!* … *r!)通り
LET s=B(M) !総数 r, … ,q+ … +r,p+q+ … +r
LET t=1 !組合せ comb(r,r), … ,comb(q+ … +r,q),comb(p+q+ … +r,p)
FOR i=M-1 TO 1 STEP -1
   LET s=s+B(i)
   LET t=t*COMB(s,B(i)) !組合せ順列
NEXT i
LET PermFactorialM=t
END FUNCTION

EXTERNAL FUNCTION PermFactorialM2Num(A(),N,B(),M) !順列パターンに番号を付ける ※辞書式順序
DIM w(M)
MAT w=B !copy it
LET v=0
FOR i=1 TO N-1 !左端に着目する
   LET t=A(i)
   FOR j=1 TO t-1 !左端を1~A(i)-1として
      IF w(j)>0 THEN !その左端を除いた残りで最大の順列をつくる
         LET w(j)=w(j)-1
         !!!MAT PRINT w; !debug
         LET v=v+PermFactorialM(w,M) !その順列の番号を求める
         LET w(j)=w(j)+1
      END IF
   NEXT j
   LET w(t)=w(t)-1 !左端を消して、次へ
NEXT i
LET PermFactorialM2Num=v
END FUNCTION

EXTERNAL SUB Num2PermFactorialM(h, A(),N,B(),M) !番号から順列パターンを生成する ※辞書式順序
DIM w(M)
MAT w=B !copy it
LET v=h
FOR i=1 TO N
   FOR j=1 TO M !左端を1~Mとして
      IF w(j)>0 THEN !その左端を除いた残りで最大の順列をつくる
         LET w(j)=w(j)-1
         !!!MAT PRINT w;
         LET t=PermFactorialM(w,M) !その順列の番号を求める
         IF v<t THEN EXIT FOR
         LET v=v-t
         LET w(j)=w(j)+1
      END IF
   NEXT j
   LET A(i)=j !次へ
NEXT i
END SUB


> これは式で書けるのでしょうか?

               円順列  数珠順列
異なるn個から
  すべて          (n-1)!  (n-1)!/2
  重複を許さず r個選ぶ  comb(n,r)*(r-1)!  comb(n,r)*(r-1)!/2
  重複を許して r個選ぶ  ?    ? ← 問題2
同じものがp個、q個、…、r個ずつから
         すべて   ?    ? ← 問題1
  重複を許さず r個選ぶ  ?    ?


問題1は、メビウス関数、オイラー関数を使って表現できたと思います。
 

Re: パターン数は?

 投稿者:山中和義  投稿日:2010年 4月27日(火)12時55分56秒
  > No.1204[元記事へ]

>(2)同じものがそれぞれたくさんある3色のビーズで、腕輪を作るとする。
> ビーズをP個使って作るとすれば、腕輪は何通り出来るか?

問題2の方がさらに簡潔に記述できます。
同様に(直線)重複順列から「篩い」を使って対称を排除しています。
!n色の玉からr個使って数珠をつくるとき、その「場合の数」は?

!参考サイト
! 3色 http://www.research.att.com/~njas/sequences/A001867
! 4色 http://www.research.att.com/~njas/sequences/A001868
! 5色 http://www.research.att.com/~njas/sequences/A001869

LET N=3 !異なる色の数
LET R=5 !選ぶ数

!PUBLIC STRING S$
LET S$="白赤青黒黄紫緑"


DIM G(R) !(白,赤,青,…)の並び
MAT G=ZER

DIM F(0 TO N^R-1) !篩い
MAT F=ZER

LET x=0
FOR i=0 TO N^R-1 !「同じものを含む順列」を円型に並べる

   CALL Num2ReptPerm(i, G,N,R)
   IF F(i)=0 THEN

   !MAT PRINT G;
      FOR k=1 TO R !「素」の並びを表示する
         PRINT S$(G(k):G(k));
      NEXT k
      PRINT
      LET x=x+1 !+1

      !CALL FilterNecklace(F,G,N,R) !反転(裏返し) ※数珠順列 ←←←←←

      FOR j=1 TO R-1 !篩いにかける
         LET w=G(1) !右シフト ※時計まわりに回転する
         FOR k=1 TO R-1
            LET G(k)=G(k+1)
         NEXT k
         LET G(R)=w

         LET F(ReptPerm2Num(G,N,R))=1 !この並びは対称なため削除する

         !CALL FilterNecklace(F,G,N,R) !反転(裏返し) ※数珠順列 ←←←←←
      NEXT j

   END IF

NEXT i

PRINT "場合の数=";x

END


EXTERNAL SUB FilterNecklace(F(),G(),N,R) !反転(裏返し)の篩い
DIM GR(R)
MAT GR=G !反転(裏返し)
CALL reverse(GR,R)
LET F(ReptPerm2Num(GR,N,R))=1 !この並びは対称なため削除する
END SUB

EXTERNAL SUB reverse(A(),N) !並びを逆順にする
FOR i=1 TO INT(N/2)
   LET t=A(i) !swap it
   LET A(i)=A(N-i+1)
   LET A(N-i+1)=t
NEXT i
END SUB


!「順列と組合せ」の符号化・復号化などによる列挙」より
! #1088
! #1089

EXTERNAL FUNCTION ReptPerm2Num(A(),N,R) !順列パターンに番号を付ける ※辞書式順序
LET v=A(1)-1
FOR i=2 TO R !N進法R桁の数を10進法へ
   LET v=v*N+A(i)-1
NEXT i
LET ReptPerm2Num=v
END FUNCTION

EXTERNAL SUB Num2ReptPerm(h, A(),N,R) !番号から順列パターンを生成する ※辞書式順序
LET v=h
LET i=R !桁位置
DO UNTIL v=0 !10進法の数をN進法R桁へ
   LET t=INT(v/N)
   LET A(i)=v-t*N+1 !1~N ※剰余
   LET v=t
   LET i=i-1
LOOP
FOR k=i TO 1 STEP -1 !残りの桁を埋める
   LET A(k)=1
NEXT k
END SUB
 

Re: パターン数は?

 投稿者:山中和義  投稿日:2010年 4月27日(火)14時31分39秒
  > No.1205[元記事へ]

つづき

●同じものを含む円順列の「場合の数」
LET N=3 !異なる色の数
DATA 2,2,2 !(白,赤,青)の個数

DIM C(N) !それぞれの個数
MAT READ C


!1/S * Σ[j|L]{φ(j) * FACT(S/j)/( FACT(p/j)*FACT(q/j)* … *FACT(r/j) )}
!ただし、S=p+q+ … +r、L=gcd(p,q,…,r)。
!また、j|Lとは、jはLの約数の意。 φ(j)は、オイラー関数。

LET S=0 !総数
FOR i=1 TO N
   LET S=S+C(i)
NEXT i

LET L=C(1)
FOR i=2 TO N
   LET L=gcd(L,C(i))
NEXT i
LET x=0
FOR j=1 TO L
   IF MOD(L,j)=0 THEN !jはLの約数
      DIM B(N)
      MAT B=(1/j)*C
      LET x=x+eul(j)*PermFactorialM(B,N)
   END IF
NEXT j
LET x=x/S

PRINT "場合の数=";x

END

EXTERNAL FUNCTION PermFactorialM(B(),M) !同じものを含む順列の「場合の数」 (p+q+ … +r)!/(p!*q!* … *r!)通り
LET s=B(M) !総数 r, … ,q+ … +r,p+q+ … +r
LET t=1 !組合せ comb(r,r), … ,comb(q+ … +r,q),comb(p+q+ … +r,p)
FOR i=M-1 TO 1 STEP -1
   LET s=s+B(i)
   LET t=t*COMB(s,B(i)) !組合せ順列
NEXT i
LET PermFactorialM=t
END FUNCTION


!整数論関連 ※UBASICより

EXTERNAL FUNCTION eul(n) !オイラー関数 φ(n)(1からnまでの自然数のうちnと互いに素なものの個数)
LET t=n
IF MOD(n,2)=0 THEN
   LET t=t/2
   DO
      LET n=n/2
   LOOP WHILE MOD(n,2)=0
END IF
LET d=3
DO WHILE n/d>=d
   IF MOD(n,d)=0 THEN
      LET t=t/d*(d-1)
      DO
         LET n=n/d
      LOOP WHILE MOD(n,d)=0
   END IF
   LET d=d+2
LOOP
IF n>1 THEN LET t=t/n*(n-1)
LET eul=t
END FUNCTION

EXTERNAL FUNCTION gcd(a,b) !最大公約数
DO UNTIL b=0
   LET t=b
   LET b=MOD(a,b)
   LET a=t
LOOP
LET gcd=a
END FUNCTION


●n色の玉からr個使って数珠をつくるとき、その「場合の数」は?

参考サイト
 4色 http://www.research.att.com/~njas/sequences/A001868
に式が掲載されています。
LET N=3 !異なる色の数

FOR R=1 TO 10 !選ぶ数

!1/R * Σ[j|R]{φ(j) * N^(R/j)}
!ただし、j|Rとは、jはRの約数の意。 φ(j)は、オイラー関数。

   LET x=0
   FOR j=1 TO R
      IF MOD(R,j)=0 THEN !jはRの約数
         LET x=x+eul(j)*N^(R/j)
      END IF
   NEXT j
   LET x=x/R

   PRINT R;x

NEXT R

END

!eul関数は略(上記参照)
 

戻る