|
ネット上で大きな話題だそうですね。
> 小さなサイズ(7×7程度)であれば「深さ優先検索(DFS)」というアルゴリズムで解けます。
!問題
!m行n列の格子状の道がある。
!同じ交差点を通らないようにして、左上から右下へ向かうときの道順は何通りか。
!例 m=n=3の場合
! 始点─・─・
! │ │ │
! ・─・─・
! │ │ │
! ・─・─終点
!のとき、
! 始点─・ ・
! │
! ・ ・─・
! │
! ・ ・ 終点
!のような最短経路は条件を満たす。
!また、
! 始点 ・─・
! │ │ │
! ・─・ ・
! │
! ・ ・ 終点
!のような遠回りも条件を満たす。
!求める道順は、12通りある。
!参考サイト http://mathworld.wolfram.com/Self-AvoidingWalk.html
LET t0=TIME
LET M=6 !行
LET N=M !列
PUBLIC NUMERIC C !解の個数
LET C=0
DIM P(0 TO M-1,0 TO N-1) !経路 p(y,x)
MAT P=(-1)*CON
LET P(0,0)=0 !左上がスタート位置
LET P(0,1)=1 !左斜めの対角線で折り返すと対称になる (0,0)→(0,1)
CALL try(0,1,2,P,M,N) !(0,1)
PRINT 2*C;"通り"
PRINT "計算時間=";TIME-t0
END
EXTERNAL SUB try(y,x,s,P(,),M,N) !バックトラック法で検索する
IF x=N-1 AND y=M-1 THEN !ゴール(右下)に到達したなら
LET C=C+1 !経路を表示する
!!PRINT "No.";C
!!MAT PRINT P;
ELSE
IF y=0 OR y=M-1 THEN !上壁沿いか下壁沿いなら、左側は袋小路なので進入禁止とする
ELSE
IF x>0 THEN !左端以外なら左へ
LET xx=x-1
IF P(y,xx)=-1 THEN !未踏なら
LET P(y,xx)=s !仮に進む
CALL try(y,xx,s+1,P,M,N) !次へ
LET P(y,xx)=-1 !戻す
END IF
END IF
END IF
IF x<N-1 THEN !右へ
LET xx=x+1
IF P(y,xx)=-1 THEN
LET P(y,xx)=s
CALL try(y,xx,s+1,P,M,N)
LET P(y,xx)=-1
END IF
END IF
IF x=0 OR x=N-1 THEN !左壁沿いか右壁沿いなら、上側は袋小路なので進入禁止とする
ELSE
IF y>0 THEN !上へ
LET yy=y-1
IF P(yy,x)=-1 THEN
LET P(yy,x)=s
CALL try(yy,x,s+1,P,M,N)
LET P(yy,x)=-1
END IF
END IF
END IF
IF y<M-1 THEN !下へ
LET yy=y+1
IF P(yy,x)=-1 THEN
LET P(yy,x)=s
CALL try(yy,x,s+1,P,M,N)
LET P(yy,x)=-1
END IF
END IF
END IF
END SUB
|
|