第19講 対角線法による魔方陣自動生成ソフトの高速化
第2話 対角線法とは?
第9講で学んだ魔方陣自動生成ソフトは、
数字を次の順で入れていました。
4次魔方陣の場合
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
5次魔方陣の場合
1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 |
ですが、これは合理的ではありません。
なぜなら、セルの中で一番重要なのは、
対角線のセルです。
対角線のセルは、縦横の条件だけでなく、
対角線の条件を満たさなければならないからです。
条件が多い方から、難しい方からクリアしていくのが、
問題解決の基本的方針です。
時間割を作るというのは、
数独よりずっと難しいパズルです。
現在の高校では、選択・習熟があり、
体育では場所の制約が、家庭科では時間の制約があり、
さらに、非常勤の先生方への配慮など、
複雑な条件が絡んでくるからです。
時間割を作成するためのコツは、
制約の多い駒から入れて行くです。
フリーな駒を残しておかないと、
あっという間に動きが取れなくなるからです。
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 |
の入れ方だと、条件の緩い方から入れていることになります。
条件の厳しい方から、クリアするという難問解消の方法に従っていません。
そこで、数字を入れる順番を
1 | 9 | 10 | 5 |
11 | 2 | 6 | 12 |
13 | 7 | 3 | 14 |
8 | 15 | 16 | 4 |
1 | 10 | 11 | 12 | 6 |
13 | 2 | 14 | 7 | 15 |
16 | 17 | 3 | 18 | 19 |
20 | 8 | 21 | 4 | 22 |
9 | 23 | 24 | 25 | 5 |
と入れ替えようというのが、この講の狙いです。
では、皆さん
参考ダウンロード添付ファイル
を改良していきましょう。
行合計・列合計・対角線合計は、添付ファイルより遙かに難度が高くなりますので、
一端3つの条件を外して、さらに1個出来た段階で止めるように
変更しておきます。変更添付ファイル
Sub f(g As Byte)
Dim i As Byte, j As Byte, y As Byte, x As Byte, jy As Byte, jx As Byte, w As Byte
y = Int(g / n)
x = g Mod n
For i = 1 To n * n
If g > 0 Then
For j = 0 To g - 1
jy = Int(j / n)
jx = j Mod n
If i = a(jy, jx) Then GoTo tobi
Next
End If
a(y, x) = i
' If x = n - 1 Then
' w = 0
' For j = 0 To n - 1
' w = w + a(y, j)
' Next
' If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
' End If
' If y = n - 1 Then
' w = 0
' For j = 0 To n - 1
' w = w + a(j, x)
' Next
' If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
' End If
' If x = 0 And y = n - 1 Then
' w = 0
' For j = 0 To n - 1
' w = w + a(j, n - 1 - j)
' Next
' If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
' End If
' If x = n - 1 And y = n - 1 Then
' w = 0
' For j = 0 To n - 1
' w = w + a(j, j)
' Next
' If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
' End If
If g + 1 < n * n Then
Call f(g + 1)
If cn = 1 Then Exit Sub
Else
Call h
If cn = 1 Then Exit Sub
End If
tobi:
Next
End Sub
尚、合計の条件の部分をすべてまとめて注釈文にするには、
ドラッグによって範囲指定をしてから、
赤い囲いをクリックします。
また、まとめて元に戻すときはその隣のアイコン(緑の囲い)をクリックします。
赤い囲いのアイコンをコメントブロック、緑囲いのアイコンを非コメントブロックといいます。
もし、そのコメントブロックと非コメントブロックがない場合には、
表示→ツールバー→ユーザー設定
の順にクリックして
コメントブロックと非コメントブロックをツールバーにドラッグします。
2つがない方は、是非ツールバーに入れておいて下さい。
をどうやったら、
と変更できるのでしょうか。
5次の例を見ればお分かりのように、
大変難しい課題です。
対角線のところで交差しているからです。
最初、私はこの難しい課題を数学の等差数列を使う、
大変複雑なコードを書きましたが、
本サイトのユーザである仮屋崎さんから、
魅力的でシンプルにコードが書けるアイデアが提供されましたので、
その考え方を次話と次次話で説明したいと思います。
次話と次次話を読んで皆さんコードを組んでみましょう。
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入門へ
本サイトトップへ