モンジュシャッフルの復元回数

 投稿者:GAI  投稿日:2010年 3月14日(日)15時26分6秒
  モンジュシャッフルの復元回数について知りたいのでお願いします。

左手にn枚のカードを持つ。
上から一枚ずつ右手に渡す。
ただし2枚目は右手のカードのトップにのせる。
3枚目は右手カードのボトムに入れる。
4枚目は右手カードのトップにのせる。
という風に、上、下と交互に左手から右手へと順序を入れ替えながら左手のカードが無くなるまで続ける。(この操作を1回とする。)
終わったら再び左手にカードを渡して、これを繰り返す。

この操作を何回繰り返したとき、再び最初の配列が並ぶのが何回目で達成できるのか知りたいのですが、よろしくお願いします。

n:1~52(枚)
の各データが知りたい。
 

Re: モンジュシャッフルの復元回数

 投稿者:山中和義  投稿日:2010年 3月15日(月)13時31分35秒
  > No.1095[元記事へ]

GAIさんへのお返事です。

> モンジュシャッフルの復元回数について知りたいのでお願いします。

10枚のカードの場合、このシャッフルを置換で表すと
┌  1  2  3  4  5  6  7  8  9 10 ┐
└  6  5  7  4  8  3  9  2 10  1 ┘

これを巡回置換の積で表すと
P=( 1  6  3  7  9  10 )( 2  5  8 )( 4 )

長さは、6,3,1なので、その最小公倍数6が求める解である。

実際のカードの並びは、置換の積で求まる。
 E*P*P* … ※Eは、恒等置換
0 回目
 1  2  3  4  5  6  7  8  9  10

 1 回目
 6  5  7  4  8  3  9  2  10  1

 2 回目
 3  8  9  4  2  7  10  5  1  6

 3 回目
 7  2  10  4  5  9  1  8  6  3

 4 回目
 9  5  1  4  8  10  6  2  3  7

 5 回目
 10  8  6  4  2  1  3  5  7  9

 6 回目
 1  2  3  4  5  6  7  8  9  10

●サンプル・プログラム
!「シャッフル」のシミュレーション

LET N=10 !カードの枚数

DIM shuffle(N) !シャッフルに相当する置換
FOR i=1 TO N
   LET shuffle(i)=INT((N-i*(-1)^i-MOD(N,2))/2)+1
   !LET shuffle(i)=MOD(2*i,N+1) !in shuffle ※Nは2の倍数
   !IF i=N THEN LET shuffle(i)=N ELSE LET shuffle(i)=MOD(2*(i-1),N-1)+1 !out shuffle(1,Nは不変) ※Nは2の倍数
NEXT i
CALL PermPrintOut(shuffle)
CALL PermCyclicPrintOut(shuffle)
!!!STOP


DIM C(N) !カードの束
CALL PermIdentity(C) !カードを整列させる
PRINT "0 回目"
MAT PRINT C;


DIM T(N)
LET cMax=500 !最大回数 ※調整が必要
FOR x=1 TO cMax

   CALL PermMultiply(C,shuffle, C) !シャッフル
   PRINT x;"回目"
   MAT PRINT C;

   IF PermIsIdentity(C)<>0 THEN EXIT FOR !元に戻ったら、終了!

NEXT x
IF x>cMax THEN PRINT cMax;"回では元に戻りません。"


END


EXTERNAL SUB PermIdentity(A()) !恒等置換
FOR i=1 TO UBOUND(A)
   LET A(i)=i
NEXT i
END SUB

EXTERNAL FUNCTION PermIsIdentity(A()) !恒等置換か確認する
LET PermIsIdentity=0 !false
FOR i=1 TO UBOUND(A)
   IF A(i)<>i THEN EXIT FUNCTION
NEXT i
LET PermIsIdentity=-1 !true
END FUNCTION

EXTERNAL SUB PermMultiply(A(),B(), AB()) !積AB
DIM T(UBOUND(A))
FOR i=1 TO UBOUND(A)
   LET T(i)=A(B(i)) !※合成写像(AB)(i)=A(B(i))
NEXT i
MAT AB=T
END SUB


!補助ルーチン

EXTERNAL SUB PermPrintOut(A()) !表示する ※標準形(2行n列の行列表記する)
PRINT "┌";
FOR i=1 TO UBOUND(A)
   PRINT USING "###": i;
NEXT i
PRINT " ┐"

PRINT "└";
FOR i=1 TO UBOUND(A)
   PRINT USING "###": A(i);
NEXT i
PRINT " ┘"
END SUB

EXTERNAL SUB PermCyclicPrintOut(A()) !巡回置換の積で表示する ※(,,…,)(,,…,)…(,,…,)
DIM T(UBOUND(A)) !作業用
CALL PermIdentity(T)

FOR i=1 TO UBOUND(A)
   IF T(i)>0 THEN !含まれないなら
      LET L=0 !長さ
      PRINT "(";

      LET k=i !最初の値
      DO !リストを作成する ※(4 4)などの長さ1の置換も含む
         PRINT k;
         LET L=L+1

         LET T(k)=-1 !巡回に含まれる

         LET k=A(k) !次をトレースする
      LOOP UNTIL k=i !一巡するまで

      PRINT ")"; !次の組へ
      PRINT " 長さ=";L
   END IF
NEXT i
PRINT
END SUB
 

戻る