[関数、手続きの一覧]
順列
●異なるn個のものをすべて並べる ※{1,2,3,…,n}上の全順列(n-順列)
FACT(N) 場合の数 ※組み込み関数
FUNCTION PermFactorial2Num(A(),N) パターンに番号を付ける
SUB Num2PermFactorial(h, A(),N) 番号からパターンを生成する
SUB PrevPermFactorial(A(),N, rc) 辞書式順序で1つ前を返す
SUB NextPermFactorial(A(),N, rc) 辞書式順序で1つ次を返す
●異なるn個のものから重複を許さずr個を取り出して並べる ※{1,2,3,…,n}上のr-順列
PERM(N,R) ※組み込み関数
FUNCTION Perm2Num(A(),N,R)
SUB Num2Perm(h, A(),N,R)
SUB PrevPerm(A(),N,R, rc)
SUB NextPerm(A(),N,R, rc)
●同じものをそれぞれp,q,…,r個ずつ含む総数n個(n=p+q+ … +r)のものをすべて並べる
FUNCTION PermFactorialM(B(),M) ※(p+q+ … +r)!/(p!*q!* … *r!)
FUNCTION PermFactorialM2Num(A(),N,B(),M)
SUB Num2PermFactorialM(h, A(),N,B(),M)
SUB PrevPermFactorial(A(),N, rc) ※全順列と同じ
SUB NextPermFactorial(A(),N, rc) ※全順列と同じ
●異なるn個のものから重複を許してr個を取り出して並べる(重複順列)
N^R
FUNCTION ReptPerm2Num(A(),N,R)
SUB Num2ReptPerm(h, A(),N,R)
SUB PrevReptPerm(A(),N,R, rc)
SUB NextReptPerm(A(),N,R, rc)
●異なるn個のものをすべて円形に並べる(円順列)
FACT(N-1) ※組み込み関数
?
?
?
?
●異なるn個のものをすべて円形に並べる(左右対称なものは除く)(数珠順列)
FACT(N-1)/2 ※組み込み関数
?
?
?
?
組合せ
●異なるn個のものから重複を許さずr個を取り出す組合せ
COMB(N,R) ※組み込み関数
FUNCTION Comb2Num(A(),N,R)
SUB Num2Comb(h, A(),N,R)
SUB PrevComb(A(),N,R, rc)
SUB NextComb(A(),N,R, rc)
●異なるn個のものから重複を許してr個を取り出す組合せ(重複組合せ)
COMB(N+R-1,R) ※組み込み関数
FUNCTION ReptComb2Num(A(),N,R)
SUB Num2ReptComb(h, A(),N,R)
SUB PrevReptComb(A(),N,R, rc)
SUB NextReptComb(A(),N,R, rc)
[サンプル・プログラム]
LET N=5
LET R=3
DIM A(R) !最初のパターン
FOR i=1 TO R !初期値 A={1,1,1,…,1} ※重複組合せ
LET A(i)=1
NEXT i
LET s=0 !番号付け 0~
DO
PRINT "No.";s
MAT PRINT A;
PRINT ReptComb2Num(A,N,R) !符号化
DIM AA(R)
MAT AA=ZER
CALL Num2ReptComb(s,AA,N,R) !復号化
MAT PRINT AA;
CALL NextReptComb(A,N,R, rc) !次へ
LET s=s+1
LOOP WHILE rc<>0
PRINT
LET s=COMB(N+R-1,R)-1 !場合の数 nHr=n+r-1Cr
DO
PRINT "No.";s
MAT PRINT A;
CALL PrevReptComb(A,N,R, rc)
LET s=s-1
LOOP WHILE rc<>0
END
!最小完全ハッシュ関数 factoradic
!●異なるn個のものをすべて並べる ※{1,2,3,…,n}上の全順列(n-順列)
!n!通りの順列パターン ⇔ 0~(n!-1)の番号
EXTERNAL FUNCTION PermFactorial2Num(A(),N) !順列パターンに番号を付ける ※辞書式順序
FOR j=1 TO N-1 !階乗進数の各桁の値+1 A[1..N]=(N-1)! … 3! 2! 1! 0!
FOR k=j+1 TO N
IF A(k)>=A(j) THEN LET A(k)=A(k)-1
NEXT k
NEXT j
LET v=0
FOR j=N TO 1 STEP -1 !非負の10進数整数へ
LET v=v*j+A(N-j+1)-1
NEXT j
LET PermFactorial2Num=v
END FUNCTION
EXTERNAL SUB Num2PermFactorial(h, A(),N) !番号から順列パターンを生成する ※辞書式順序
LET v=h !非負の10進数整数を階乗進数へ
FOR j=1 TO N
LET t=INT(v/j)
LET A(N-j+1)=v-t*j +1 !階乗進数の各桁の値+1 A[1..N]=(N-1)! … 3! 2! 1! 0!
LET v=t
NEXT j
FOR j=N-1 TO 1 STEP -1 !順列パターンへ
FOR k=j+1 TO N
IF A(k)>=A(j) THEN LET A(k)=A(k)+1
NEXT k
NEXT j
END SUB
EXTERNAL SUB PrevPermFactorial(A(),N, rc) !辞書式順序で次の順列を返す
LET rc=0 !完了
LET i=N-1 !順列を右から左にみて、増加列から減少列に変わる位置iを探す
DO WHILE i>0 AND A(i)<=A(i+1) !0は番人
LET i=i-1
LOOP
IF i=0 THEN EXIT SUB !A(1)>A(2)>A(3)> … >A(N)なら 例. N=4、4,3,2,1
LET j=N !その位置iより右で、A(i)以上で最小の数A(j)を探す
DO WHILE A(i)<=A(j)
LET j=j-1
LOOP
LET t=A(i) !A(i)とA(j)を交換する
LET A(i)=A(j)
LET A(j)=t
LET i=i+1 !(i+1)からNまでの範囲を逆順にする
LET j=N
DO WHILE i<j
LET t=A(i) !swap it
LET A(i)=A(j)
LET A(j)=t
LET i=i+1
LET j=j-1
LOOP
LET rc=1 !未了
END SUB
EXTERNAL SUB NextPermFactorial(A(),N, rc) !辞書式順序で次の順列を返す
LET rc=0 !完了
LET i=N-1 !順列を右から左にみて、増加列から減少列に変わる位置iを探す
DO WHILE i>0 AND A(i)>=A(i+1) !0は番人
!!!DO WHILE i>0 AND A(i)<=A(i+1) !0は番人 ※前の順列 ←←←←←
LET i=i-1
LOOP
IF i=0 THEN EXIT SUB !A(1)>A(2)>A(3)> … >A(N)なら 例. N=4、4,3,2,1
LET j=N !その位置iより右で、A(i)以上で最小の数A(j)を探す
DO WHILE A(i)>=A(j)
!!!DO WHILE A(i)<=A(j) ! ※前の順列 ←←←←←
LET j=j-1
LOOP
LET t=A(i) !A(i)とA(j)を交換する
LET A(i)=A(j)
LET A(j)=t
LET i=i+1 !(i+1)からNまでの範囲を逆順にする
LET j=N
DO WHILE i<j
LET t=A(i) !swap it
LET A(i)=A(j)
LET A(j)=t
LET i=i+1
LET j=j-1
LOOP
LET rc=1 !未了
END SUB
!●異なるn個のものから重複を許さずr個を取り出して並べる ※{1,2,3,…,n}上のr-順列
!perm(n,r)通りの順列パターン ⇔ 0 ~ perm(n,r)-1 の番号
EXTERNAL FUNCTION Perm2Num(A(),N,R) !順列パターンに番号を付ける ※辞書式順序
FOR j=1 TO R-1 !(階乗)進数の各桁の値+1 A[1..R]=PERM(N-1,R-1) … PERM(N-j,R-j) … PERM(N-R,0)
FOR k=j+1 TO R
IF A(k)>=A(j) THEN LET A(k)=A(k)-1
NEXT k
NEXT j
LET v=0
FOR j=R TO 1 STEP -1 !非負の10進数整数へ
LET v=v*(N-R+j)+A(R-j+1)-1
NEXT j
LET Perm2Num=v
END FUNCTION
EXTERNAL SUB Num2Perm(h, A(),N,R) !番号から順列パターンを生成する ※辞書式順序
LET v=h !非負の10進数整数を(階乗)進数へ
FOR j=1 TO R
LET w=N-R+j
LET t=INT(v/w)
LET A(R-j+1)=v-t*w +1 !(階乗)進数の各桁の値+1 A[1..R]=PERM(N-1,R-1) … PERM(N-j,R-j) … PERM(N-R,0)
LET v=t
NEXT j
FOR j=R-1 TO 1 STEP -1 !順列パターンへ
FOR k=j+1 TO R
IF A(k)>=A(j) THEN LET A(k)=A(k)+1
NEXT k
NEXT j
END SUB
EXTERNAL SUB PrevPerm(A(),N,R, rc) !辞書式順序で前の順列を返す
LET rc=0 !完了
FOR j=1 TO R-1 !(階乗)進数へ
FOR k=j+1 TO R
IF A(k)>=A(j) THEN LET A(k)=A(k)-1
NEXT k
NEXT j
FOR i=R TO 1 STEP -1 !(階乗)進数で-1する
IF A(i)>1 THEN !1~(N-i+1)で更新する
LET A(i)=A(i)-1
FOR k=i+1 TO R !i桁より下の位を「最後の並び」にする
LET A(k)=N-k+1
NEXT k
LET rc=1 !未了
EXIT FOR
END IF
NEXT i
FOR j=R-1 TO 1 STEP -1 !順列パターンへ
FOR k=j+1 TO R
IF A(k)>=A(j) THEN LET A(k)=A(k)+1
NEXT k
NEXT j
END SUB
EXTERNAL SUB NextPerm(A(),N,R, rc) !辞書式順序で次の順列を返す
LET rc=0 !完了
FOR j=1 TO R-1 !(階乗)進数へ
FOR k=j+1 TO R
IF A(k)>=A(j) THEN LET A(k)=A(k)-1
NEXT k
NEXT j
FOR i=R TO 1 STEP -1 !(階乗)進数で+1する
IF A(i)<N-i+1 THEN !1~(N-i+1)で更新する
LET A(i)=A(i)+1
FOR k=i+1 TO R !i桁より下の位を「最初の並び」にする
LET A(k)=1
NEXT k
LET rc=1 !未了
EXIT FOR
END IF
NEXT i
FOR j=R-1 TO 1 STEP -1 !順列パターンへ
FOR k=j+1 TO R
IF A(k)>=A(j) THEN LET A(k)=A(k)+1
NEXT k
NEXT j
END SUB