第33講 数独(ナンバープレイス)問題解決ソフトVer.4の制作
(数独(ナンバープレイス)問題作成ソフトに挑戦する人は☆☆)

第7話 
Ver.7コード解説その5=部分構造解析行部分解説その2

さて、3行目の

                                                 h1[g][i]=0;

                                                 if(lst[i][y][a[x][y]-1]==0){

                                                         lst[i][y][a[x][y]-1]=1;

                                                         b[i][y]--;

                                                         h1[g][i]=1;

7行目とセットで役割を果たします。

6 7 3
7

によって、現在対象となっているセルが影響を受けた場合、
h1[g][i]=1;
となります。実は、7が入っていることによって、
影響を受けるとは限らないのです。
今回の問題

1 4
3 9 6
5
6 7 3
1 4 8
2 3 6
5
4 8

では確かに今対象となっている黄色のセルはすべて影響を受けます。
しかし、次のような問題なら

1 4
3 9 6
7
5 7
6 7 3
1 4 8
2 3 6
5
4 8

のセルは

7

の入力によって影響を受けません。
列の条件またはブロックの条件によって、
7は初めからリストから外されているからです。
(尚、上の問題は説明するために適当に入れたので、おそらく問題としては成立していないでしょう。
皆さん、Ver.7の実行ファイルダウンロード用EXE(実行)ファイルで実験してみるとわかりますが、
適当に数字を入れていくと、すぐに解のない問題になってしまいます。
数独の問題を作るとき、①解答が存在すること②別解が存在しないこと、の2条件が必要ですが、
いずれの条件も大変きつい条件であることがわかります。
そこに数独問題作成の難しさがあります。)

                                                 h1[g][i]=0;

                                                 if(lst[i][y][a[x][y]-1]==0){

                                                         lst[i][y][a[x][y]-1]=1;

                                                         b[i][y]--;

                                                         h1[g][i]=1;

影響受けリストを変更したときだけ、h1[g][i]をオンにします。
なぜなら、試行錯誤がうまくいかないとき、次のリストを試しますが、
そのときに、7を入れたことによって変更したリスト構造を元に戻しておかなければなりません。
元に戻すのが逆部構造分解析関数void gyakububunkouzoukaiseki(char g)の任務です。
逆部分構造解析では、h1[g][i]がオンになっているときだけ、元に戻すようになっているのです。



のように影響を受けないときに、逆部分構造構造解析を行って

                                                         lst[i][y][a[x][y]-1]=0;

                                                         b[i][y]++;

                                                         if(b[i][y]==2)chs--;

とすると、リスト構造が壊れてしまいます。
7の入力によって影響を受けて、リスト構造を変更したときだけ、元に戻すようにしているのです。

次の

                                                         if(b[i][y]==1){

                                                                 iz[chs]=i;

                                                                 jz[chs]=y;

                                                                 chs++;

                                                         }
はもうお分かりですね。

1はb[i][y]の最小値ですから、入力順構築関数に判断してもらうまでもなく、通し番号=入力順番号を割り振っていいわけです。

さて、最後の

                                                         if(b[i][y]>0){

                                                                 for(j=0;j<b[i][y];j++){

                                                                         if(rlst[i][y][j]==a[x][y]){

                                                                                 w=rlst[i][y][b[i][y]];

                                                                                 rlst[i][y][b[i][y]]=a[x][y];

                                                                                 rlst[i][y][j]=w;

                                                                                 break;

                                                                         }

                                                                 }

                                                         }

では何をしているのでしょうか。





第6話へ 第8話へ


戻る

VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)