2009年7月8日水曜日

(27) V サーチを追加

Ver12 の激辛2 では 100題中 15題が Not Conquer となった。これは、まだまだ探索法が少なく、A サーチにのみ頼っているためで、人間の思考にははるかに及ばないことの証拠であろう。これからは、人間の思考に近い探索法をマクロにすることに心がけよう。その手始めに、新しい探索法である gloval_victory_search マクロを作成した。現在の V_search に相当し、「VL」と「VC」からなる。

V_search の探索法
① igrp でブロック順に空白セルにいる候補を調べる。
② 数字を numb=1 から 9 まで順番に調べる。ここに、numb はセルに候補として入る数字をあらわす。
③ igrp の中で、numbの候補の数を調べる。もしこれが 一つしかなかったら、Pサーチで求まる決定値に相当する。各ブロックで numbの数を数えて num とする。 num=2 であれば、( i1 , i2 )=a1 , ( j1 ,j2 ) =b1=numb として二つだけの候補が求まる。
④ igrp の同行 i1=j1 または 同列 i2=j2 の他のセルには数字 numb ははいりえないので、もし他のblock の同行、同列に numbがあれば、それを除外する。結果として、除外したセルの属する block で、numb の入るセルが一つあれば、そのセルはnumbとなり、数字が確定する。

 
2006年6月27日にこのマクロが完成し、激辛2の15題あった Not Conquer は96,97,99,103の四つになった。計算時間も 8.7分に短縮された。 

2009年7月6日月曜日

(26) 激辛数独2を購入

SUDOKU_Ver12 のSheet 8 およびSheet9に、2006年6月17日に購入した「激辛数独2」の入力を開始、6月20日までかかった。解けない問題が多々あり、問題を今一度見直して見るとインプットミスが多い。数字は一行ずれていたり、一番多いのは、数字の入れ忘れである。その他 Excel VBA に関していくつかの奇妙な現象に遭遇した。まだまだ未熟な点が多いなあ。

SUDOKU_Ver12 ではいくつかの改良を行った。これまで空白セル毎に i=1 to 9 , j=1 to 9 で回していたのだが、 igrp (ブロック番号)で回すように、block_search を新しく採用した。

Ver12 で決定版数独は、64、70、80、113、116、118 の六つの Not Conquer があり、時間は 8.95分を記録した。また名品100選では、45、54、75、91 の五つの Not Conquer があり、時間は 9.33分に短縮された。
 

2009年7月5日日曜日

(25) P, M サーチに G サーチを追加 (Ver.11)

 2006年6月14日、SUDOKU_Ver11を立ち上げた。このVersionより新しい探索法を取り入れることとし、同時に探索法に名前をつけて、問題をとく次の手順を示すこととした。

(1) Primary と Medium に分けて、一覧表の候補から、その数字が一つしかないのを探索するのが M search, コンピュウターでは、一番分かりやすい解法(とにかくセルに候補が一つしかないのですぐにわかる)であるのに、人間には見つけにくいらしく、名品100選では、上級パターンその②にランクされている。

(2)各Blockにおいて数字を1から9まで当てはめて、該当数字を洗い出す。該当数字が一つしかないもの(つまり candidate が一つのもの)を P search と名付けた。(現在の B search に相当する)

(3)Block 内で同じ二つの候補を持つセルを見つけ出す。どちらかにその候補がはいるので、そのセルの他の候補を消去する。結果として、消去した数字が他のセルでsingle candidate になる。これが G search である。

2006年6月18日、このマクロを備えたVer11において、名品100選のなかで、45、67、75 の三つが Not Conquer であった。消費時間は25.25分を要した。

2009年6月29日月曜日

(24) 補足 search_table

これは(23)search_table マクロの補足である。いま、Sheet1 の(7,2)から(15,10)のRange の81個のセルに数独の問題が書かれている。その中の空白セルのすべて (empty_cell 個) に対してそのセルに入る可能性のある数字の候補を 11列目から (10+empty_cell) 列にわたって選び出す。その空白セルの順番が numj である。10+numj 列の行には、次の情報が入る。
  4行目 セルの行 (iii)
  5行目 セルの列 (jjj)
  6行目 セルの番地 ( iii, jjj )
  7行目から15行目までは候補の数字
  16行目 候補の数
  17行目 Block の番号

候補の数字の選出は、まずBlockごとに、数字1から9までが候補になりえるかを check する。行と列に対しては、check の中で Block に対しては checkmate で行う。表出数(givens) でない候補は sheet1 の search table にかきこまれる。

table を作る方法はいろいろあると思われるが、このアルゴリズムでの長所は、7行目から書き込まれる候補の数字は小さい数字の順番であることである。このことは後々探索法のアルゴリズムを簡単にしている。

2009年6月28日日曜日

(23) 演習:候補の一覧表を作るマクロ

SUDOKU_Ver9 までで一応、力づくで解を得ることができるようになった。しかし使っている探索法はたった3つに過ぎない。数独を人間が解くのに用いる方法で人間の思考過程をシミュレートするようなソフトを作るためには、用いる探索法を網羅し、解く過程のヒントが得られるようなそれぞれのフェーズに適したソフトにしなければならない。

SUDOKU_Ver10 から数独のソフトを作る基本的なマクロの例をいくつか書き留めておきたい。そうすれば自ずからそのアルゴリズムも理解しやすくなるであろう。まづは、空白セルにはいる候補の一覧表を作るマクロ search_table (これまでは mixy とか mixy_part と呼んでいた。また最終的には candy_table と呼ぶ)マクロである。

Sub search_table()
clear_answer     
numj = 0
For ii = 1 To 9
For jj = 1 To 9  
If Cells(6 + ii, 1 + jj) = "" Then
iii = ii jjj = jj  
group_search
check
Cells(6, 11 + numj) = "(" & iii & "," & jjj & ")"
Cells(4, 11 + numj) = iii
Cells(5, 11 + numj) = jjj
Cells(17, 11 + numj) = grp
numj = numj + 1
End If
Next jj
Next ii
count_kosuu
End Sub

Sub check()
num = 0
For aaa = 1 To 9
For i = 1 To 9
ccc = Cells(6 + i, 1 + jjj)
If aaa = ccc Then GoTo contaaa
Next i
For j = 1 To 9
bbb = Cells(6 + iii, 1 + j)
If aaa = bbb Then GoTo contaaa
Next j
checkmate
If flag = 1 Then GoTo contaaa
num = num + 1
Cells(6 + num, 11 + numj) = aaa
contaaa:
flag = 0
Next aaa
End Sub

Sub checkmate()
group_search
For ci = igs To ige
For cj = jgs To jge
If Cells(6 + ci, 1 + cj) = aaa Then
flag = 1: Exit Sub
End If
Next cj
Next ci
End Sub

2009年6月22日月曜日

(22) マクロはオブジェクト指向プログラムに最適。

Excel VBA のマクロは数独ソフトのプログラミングに最適のものである。いろいろと不勉強で十分に使いこなしていないところはあるが、文法やデバッグでは、格段と使いやすい。

オブジェクト指向プログラムは文字とおり、オブジェクト(目的対象物)によってプログラムを組み立てて使う。ある仕事をするのに必要な人材(マクロ)をかき集めて行うプロジェクト(ソフト)に似ている。効率よく目的を達成するために、有能なマクロをもっていることがソフト価値をきめる条件になる。

人材(マクロ)はいつ何時に呼び出されてもすぐに仕事ができるように生きた状態で存在しなければならない。そこがサブルーチンとマクロの違いである。プログラムで END というコマンドを入れると死んだ状態になる。マクロで注意しなければならないのは、ENDはすべてご破算になるので注意を要する。

マクロでは他のマクロがどうなっているのかに関係なく仕事が出来るようにしておくべきなので、連絡手段・方法は非常に大切である。マクロの中では必要な情報はすべて内臓するか、参照できる状態にしておかねばならず、PUBLIC ステートメントや文字の選択には細心の注意が必要である。

2009年6月18日木曜日

(21) Excel VBA に潜む怪

プログラミングに長く慣れ親しんできた人は、人間は過ちを犯すもので、コンピューターの馬鹿正直なおろかさをいやと言うほど知っている。すらすらと通ったプログラムも思わぬところでバグがでることがある。ちょっとしたことで確認を怠ったためにその原因を突き止めるのに、一週間も無駄にすることもある。ケアレスミスでデータをなくしてしますこともある。コピーをこまめに取らなかったために、古いファイルを数日掛かった新しいファイルに逆に上書きして、唖然とする経験はだれにでもある。大抵の場合、コンピューターは正しく、プログラマーの無知や正確に起因するトラブルである。

Excel でも、数独開発において、VBA特有のトラブルに何度か遭遇した。それは決定版数独の第54問でおこった。当時のメモから抜粋すると、「54番が最終状態まで到達しないので調べてみた。随分とかかった。まず、全部のケースでblindになること。正解と比較してみると、(7,2)のセルには8がはいらなければならないのに、6が入っていたためだった。これは(7,3)が実際には空白セルであるにもかかわらず、””ではカウントしているためであった。つまり(7,3)の候補が6とその他であるにもかかわらず、一覧表から漏れたため、6がそのグループの唯一の候補であると認識したためであった。何故空白セルであるにもかかわらず、値がはいっているものと認識するのか? Number_of_cell というマクロで調べてみると、確かに ”” 空白セルを(7,3)はカウントしていなかった。原因はわかったが対策は分からない」

おそらく私のVBAを良く知らない我流のプログラミングによるためであろう。この問題は一度マトリックスに問題を読み直すことでより、エラーを見出せるようになった。プログラミングは頭のさえている時に、はやる気持ちをぐっとこらえて、一歩一歩進めなければならない。と同時に、何かおかしいなと感じる感性を培うことが肝要である。