第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
qwe
尚、合計の条件の部分をすべてまとめて注釈文にするには、
edz
ドラッグによって範囲指定をしてから、
wev
赤い囲いをクリックします。
また、まとめて元に戻すときはその隣のアイコン(緑の囲い)をクリックします。
赤い囲いのアイコンをコメントブロック、緑囲いのアイコンを非コメントブロックといいます。
もし、そのコメントブロックと非コメントブロックがない場合には、
表示→ツールバー→ユーザー設定
wez
の順にクリックして
wq
コメントブロックと非コメントブロックをツールバーにドラッグします。
wev
2つがない方は、是非ツールバーに入れておいて下さい。

qweをどうやったら、
vee
qcq
qwqZ
と変更できるのでしょうか。
5次の例を見ればお分かりのように、
大変難しい課題です。
対角線のところで交差しているからです。



最初、私はこの難しい課題を数学の等差数列を使う、
大変複雑なコードを書きましたが、
本サイトのユーザである仮屋崎さんから、
魅力的でシンプルにコードが書けるアイデアが提供されましたので、
その考え方を次話と次次話で説明したいと思います。
次話と次次話を読んで皆さんコードを組んでみましょう。




第1話へ 第3話へ
004

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入門へ
本サイトトップへ