第5講 第4講のプログラムエラー原因探索各アイテムの解説
第2話 原因究明プログラム1について
まず、
原因解明プログラムファイル1
を開いて下さい。
実行する前に、コードの
Do While 1
・
If kz = 1000 Then Exit Do
Loop
ピンクの部分を100程度に変更してから、実行ボタンを押して下さい。
すると、
等の画面になるはずです。
乱数が入れてあるので、皆さんの画面は当然異なっています。
しかし、10個に1個程度の割合で×がついているはずです。
このプログラムを
Do While 1
hj1 = Timer
zlk '全体リスト構造解析プロシージャ
y(0) = Int(n * Rnd)
x(0) = Int(n * Rnd)
Call sds(0, 0) '数独作成プロシージャ
sdc '数独のコピー
zlk '全体リスト構造解析プロシージャ
mds '問題作成プロシージャ
tk '全体リスト構造解析Total方式
If kn = 1 Then
Cells(10, 12) = "全体リスト構造解析は正しい!!!!"
Cells(5 + Int(kz / 20), 21 + (kz Mod 20)) = "○"
Else
Cells(10, 12) = "全体リスト構造解析に異常あり!!!!"
Cells(5 + Int(kz / 20), 21 + (kz Mod 20)) = "×"
Cells(4, 15) = "異常発生!!!!!!!!!!!!!!!!"
End If
hyouji '問題表示プロシージャ
hyouji3
' nck (hintosu)
' Call sds(hintosu, 1) '数独作成プロシージャ
kz = kz + 1
If kz = 100 Then Exit Do
Loop
に変更した原因解明プログラムファイル2を開いて、
実行ボタンを押すと、
今度はすべて○になりました。
If kz = 100 Then Exit Do
100を1000に変更してもすべて○になります。
原因解明プログラムファイル1
原因解明プログラムファイル2
この2つのファイルの違いは
tk '全体リスト構造解析Total方式
If kn = 1 Then
Cells(10, 12) = "全体リスト構造解析は正しい!!!!"
Cells(5 + Int(kz / 20), 21 + (kz Mod 20)) = "○"
Else
Cells(10, 12) = "全体リスト構造解析に異常あり!!!!"
Cells(5 + Int(kz / 20), 21 + (kz Mod 20)) = "×"
Cells(4, 15) = "異常発生!!!!!!!!!!!!!!!!"
End If
をDo Whileの2回目の解答を作った後に実行させるか、
1回目の解答作成後に実行させるかの違いです。
ファイル2の方は2回目の解答を作った後に、
全体リスト構造解析Total方式のSubプロシージャtkを稼働させ、
tkで行った全体リスト構造解析と
数独作成ソフトVer.1となるはずであったソフトの全体構造解析が一致しているかを、
検証Functionプロシージャknに調べさせて、
一致しているときは○を表示させ、一致しないときには×を表示させています。
1回目に解答を作成しヒント数に対応する以外のセルを0にして問題を作成した時点では、
すべてが○になっていることから、
数独作成ソフトVer.1となるはずであったソフトの全体構造解析が、
上手くいっていることを示しています。
ところが、ファイル1の2回目の解答作成後、
すなわち、2回目の解答を作り、別解がないことを確認したはずの後の、
同検査では、10回に1回ぐらいの割合で×がついてしまうことから、
数独作成ソフトVer.1となるはずであったソフトの全体構造解析が、
上手くいっていないということがわかります。
問題を作る時点では、1度もSub hukugen(g As Integer)は作動させていません。
それに対して2回目の解答を作るときには、
おそらく何千回も起動させたはずです。
Sub hukugen(g As Integer)を稼働しないときには上手くいって、
実行したときには時々エラーするとしたら、
エラー原因は、
Sub hukugen(g As Integer)にある可能性が非常に高いわけと思われたわけです。
そこで、
Sub hukugen(g As Integer)
Dim i As Byte, j As Byte, ybs As Byte, xbs As Byte, isy As Byte, ia As Byte
For i = 0 To n_1
If i <> x(g) And p(y(g), i) = 0 Then
If hth(g, y(g), i) = 1 Then
For j = 0 To n_1
rlst(y(g), i, j) = crlst(g, y(g), i, j)
Next
mx(y(g), i) = cmx(g, y(g), i)
End If
End If
Next
For i = 0 To n_1
If i <> y(g) And p(i, x(g)) = 0 Then
If hth(g, i, x(g)) = 1 Then
For j = 0 To n_1
rlst(i, x(g), j) = crlst(g, i, x(g), j)
Next
mx(i, x(g)) = cmx(g, i, x(g))
End If
End If
Next
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
If hth(g, ybs + isy, xbs + ia) = 1 Then
For j = 0 To n_1
rlst(ybs + isy, xbs + ia, j) = crlst(g, ybs + isy, xbs + ia, j)
Next
mx(ybs + isy, xbs + ia) = cmx(g, ybs + isy, xbs + ia)
End If
End If
Next
End Sub
と変更したのですが、それでも×は減っても0個にはなりませんでした。
復元が上手くいっていないのだから、
Sub hukugen(g As Integer)に原因があると考えたわけですが、
実際には、このコードは変更する必要はなかったのです。
それで、やっとFunction klk(g As Integer) 側に原因があり、
Function klk(g As Integer) '局所リスト解析プロシージャ
Dim i As Byte, j As Byte, k As Byte, w As Byte
For i = 0 To n_1
For j = 0 To n_1
hth(g, i, j) = 0
Next
Next
For i = 0 To n_1
If p(y(g), i) = 0 Then
For j = 0 To mx(y(g), i)
'この行にあったhth(g, y(g), i) = 1の削除
If p(y(g), x(g)) = rlst(y(g), i, j) Then
・
・
とすれば良いことが分かったのです。
前にも申し上げたとおり、
何故
For i = 0 To n_1
For j = 0 To n_1
hth(g, i, j) = 0
Next
Next
のような無駄をしなければならないのかは、今だに分かってはいませんが、
実験結果からこうしなければならないことが分かったのです。
では、次に原因究明プログラム1の解説その2として、
tk '全体リスト構造解析Total方式
の解説をしましょう。
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入門へ
本サイトトップへ