第2講 局所リスト構造解析
第10話 Sub sds(g As Integer) '数独作成プロシージャの解説その3
局所リスト構造解析プロシージャ再掲
Sub klk(g As Integer) '局所リスト構造解析プロシージャ
Dim i As Byte, j As Byte, k As Byte, w As Byte
For i = 0 To n - 1
If p(y(g), i) = 0 Then
For j = 0 To mx(y(g), i)
If p(y(g), x(g)) = rlst(y(g), i, j) Then
w = rlst(y(g), i, j)
rlst(y(g), i, j) = rlst(y(g), i, mx(y(g), i))
rlst(y(g), i, mx(y(g), i)) = w
mx(y(g), i) = mx(y(g), i) - 1
Exit For
End If
Next
End If
Next
For i = 0 To n - 1
If p(i, x(g)) = 0 Then
For j = 0 To mx(i, x(g))
If p(y(g), x(g)) = rlst(i, x(g), j) Then
w = rlst(i, x(g), j)
rlst(i, x(g), j) = rlst(i, x(g), mx(i, x(g)))
rlst(i, x(g), mx(i, x(g))) = w
mx(i, x(g)) = mx(i, x(g)) - 1
Exit For
End If
Next
End If
Next
Dim ybs As Byte, xbs As Byte
Dim isy As Byte, ia As Byte
ybs = rn * Int(y(g) / rn)
xbs = rn * Int(x(g) / rn)
For i = 0 To n - 1
isy = Int(i / rn)
ia = i Mod rn
If ybs + isy <> y(g) And xbs + ia <> x(g) And p(ybs + isy,
xbs + ia) = 0 Then
For j = 0 To mx(ybs + isy, xbs + ia)
If p(y(g), x(g)) = rlst(ybs + isy, xbs + ia, j) Then
w = rlst(ybs + isy, xbs + ia, j)
rlst(ybs + isy, xbs + ia, j) = rlst(ybs + isy, xbs + ia, mx(ybs + isy, xbs + ia))
rlst(ybs + isy, xbs + ia, mx(ybs + isy, xbs + ia)) = w
mx(ybs + isy, xbs + ia) = mx(ybs + isy, xbs + ia) - 1
Exit For
End If
Next
End If
Next
の黄色のセルを例にどのようにリスト構造解析が行われているか、
トレースしてみましょう。
6が入ったときのリスト構造解析ですから、
黄色のセルのは解析は
For i = 0 To n - 1
If p(y(g), i) = 0 Then
For j = 0 To mx(y(g), i)
If p(y(g), x(g)) = rlst(y(g), i, j) Then
w = rlst(y(g), i, j)
rlst(y(g), i, j) = rlst(y(g), i, mx(y(g), i))
rlst(y(g), i, mx(y(g), i)) = w
mx(y(g), i) = mx(y(g), i) - 1
Exit For
End If
Next
End If
Next
の部分が行っています。座標に具体的な数字を代入すると、
If p(8, 8) = 0 Then
For j = 0 To mx(8, 8)
If p(8, 4) = rlst(8, 8, j) Then
w = rlst(8, 8, j)
rlst(8, 8, j) = rlst(8, 8, mx(8, 8))
rlst(8, 8, mx(8, 8)) = w
mx(8, 8) = mx(8, 8) - 1
Exit For
End If
Next
End If
6が入る前の黄色セルのリスト構造は、
{8,2,9,4,5,6,7,1,3}
mx(8, 8) = 6
となっていますから、
For j = 0 To mx(8, 8)
If p(8, 4) = rlst(8, 8, j) Then
は
For j = 0 To 6
If p(8, 4) = rlst(8, 8, j) Then
で、6が何番目にリストされているか探しています。
0から数えることに注意して数えると、jが5の場合です。
w = rlst(8, 8, 5)
rlst(8, 8, 5) = rlst(8, 8, 6)
rlst(8, 8, mx(8, 8)) = w
この3行で行っていることは、6,7の交換です。
{8,2,9,4,5,7,6,1,3}
そして、
mx(8, 8) = mx(8, 8) - 1
によって、mx(8, 8) = 5となり、有効範囲が1つ減って、
{8,2,9,4,5,7,6,1,3}
となります。
このプロシージャでは
この3が入った場合
オレンジのセルについて
{1,2,3,4,5,6,7,8,9}
↓
{1,2,9,4,5,6,7,8,3}
↓
{1,2,9,4,5,6,7,8,3}
としていますが、
{1,2,3,4,5,6,7,8,9}
↓
{1,2,4,5,6,7,8,9,3}
↓
{1,2,4,5,6,7,8,9,3}
とする方法も考えられます。
下の方法を選ばなかったのは、
下の方法だと、
有効範囲の中では、いつでも小さい順になっています。
ランダムに選びますから、
これでも良かったかも知れませんが、
今回の方式は進めば進むほど順番がランダムになります。
すると有効範囲の中からランダムに選びますので、
2重にランダムに選ぶことになります。
上の方式にすれば2重ランダムになり、
ランダム性が上がり、より自然な数独が出来るのではと考えてそうしました。
ただ、プログラミングのおもしろさと難しさは、
実際に試してみると、頭の中で想定していた結果と違っていたりします。
{1,2,3,4,5,6,7,8,9}
↓
{1,2,9,4,5,6,7,8,3}
↓
{1,2,9,4,5,6,7,8,3}
と
{1,2,3,4,5,6,7,8,9}
↓
{1,2,4,5,6,7,8,9,3}
↓
{1,2,4,5,6,7,8,9,3}
のどちらの方式の方が良い結果を導くかは、
やってみなければ分かりません。
今回作成までの時間を計測していませんが、
時間計測を組み込んで、
どちらの方式が勝るのか、
是非ともご自分で試されることをお勧めします。
さて、以上で第2講は終了とします。
次の課題は、
@ 解答が存在する
A 別解が存在しない
の2つを満たさせることです。
@が満たされれば、疑似が1個取れて
疑似数独作成ソフトになりますし、
更にAが満たされれば、疑似が全部取れて、
数独作成ソフトの一応の完成となります。
一応がつくのは、このソフトは残念ながら試行錯誤法で解答を作っていますので、
仮定法を使わなければ解けないクオリティーの低い問題しか作れないからです。
eclipse c++ 入門
魔方陣 数独(ナンプレ)で学ぶ VBA 入門
数独(ナンプレ)のシンプルな解き方・簡単な解法の研究
vc++講義へ
excel 2013 2010 2007 vba入門へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
専門用語なしの C言語 C++ 入門(Visual C++ 2010で学ぶ C言語 C++ 入門)
専門用語なしの excel vba マクロ 入門 2013 2010 2007 対応講義 第1部
eclipse java 入門へ
excel 2016 vba 入門へ
小学生からエンジニアまでのRuby入門へ
本サイトトップへ