第16講 魔方陣作成の高速化(数万倍へ)
第7話 自動実験コード
コード
Dim mah(6, 6) As Byte, x(36) As Byte, y(36), sh(20) As Byte, d As Byte
Dim n As Byte, cn As Integer
Dim sk As Long, c As Long ’試行回数を数える変数sk、Randomizeの番号(シード値)を指定するグローバル変数c
Dim kz As Byte, kz2 As Integer '列位置を整える変数kz、行位置を揃える変数kz2
Private Sub CommandButton1_Click()
Dim i, j As Integer
n = Cells(3, 8)
If n = 4 Then 'この行から
sh(0) = 1
sh(1) = 3
sh(2) = 5
sh(3) = 7
sh(4) = 9
sh(5) = 11
sh(6) = 13
sh(7) = 15
End If
If n = 5 Then
sh(0) = 1
sh(1) = 2
sh(2) = 3
sh(3) = 4
sh(4) = 6
sh(5) = 7
sh(6) = 8
sh(7) = 9
sh(8) = 11
sh(9) = 12
sh(10) = 13
sh(11) = 14
sh(12) = 16
sh(13) = 17
sh(14) = 18
sh(15) = 19
sh(16) = 21
sh(17) = 22
sh(18) = 23
sh(19) = 24
End If
If n = 6 Then
sh(0) = 1
sh(1) = 5
sh(2) = 7
sh(3) = 11
sh(4) = 13
sh(5) = 17
sh(6) = 19
sh(7) = 23
sh(8) = 25
sh(9) = 29
sh(10) = 31
sh(11) = 35
End If 'この行までは、n*nと互いな素な(つまり、n*nと1以外の公約数をもたない)整数を指定している。
zhy
kz2 = 0
For c = 1 To 10000
h = 0
If n = 4 Then kk = 7
If n = 5 Then kk = 19
If n = 6 Then kk = 11
kz = 0
For d = 0 To kk
sk = 0
cn = 0
Rnd (-1) '乱数系列の初期化、これがないとRandomizeで番号を指定しても反映されない。
Randomize (c) '乱数系列の指定。Rnd(-1)とセットで使う。
ms (0)
If cn = 1 Then h = 1
Next
If h = 1 Then
Cells(5 + kz2, 1) = c
kz2 = kz2 + 1 '行位置調整
End If
Next
End Sub
・
・
・
Sub ms(g As Byte)
Dim i As Integer, j As Byte, k As Byte, a As Byte, b As Byte, w As Byte
Dim ii As Integer, iii As Integer
If sk > 10000 Then Exit Sub '試行回数が上限を超えたら、思考を止めFor文の次に進めるようにしてあります。
If cn = 1 Then Exit Sub '魔方陣が見つかったら止めるようにしてあります。
a = x(g)
b = y(g)
ii = n * n * Rnd
For i = 0 To n * n - 1
iii = (ii + sh(d) * i) Mod n * n
mah(b, a) = iii + 1
・
・
・
If g + 1 < n * n Then
sk = sk + 1
ms (g + 1)
Else
'For j = 0 To n - 1 '以降の6行は、魔方陣を表示させないように'を入れ注釈文に変えられています。
'For k = 0 To n - 1 'もちろん削除してもいいわけですが、復元を考えて注釈文にしました。
'Cells(6 + k + Int(cn / 10) * (n + 1), 1 + j + (cn Mod 10) *
(n + 1)) = mah(j, k)
'Next
'Next
cn = cn + 1
Cells(5 + kz2, 3 + 2 * kz) = d
Cells(5 + kz2, 4 + 2 * kz) = sk
kz = kz + 1 '列位置調整
If cn = 1 Then Exit Sub '魔方陣が見つかったら止めるようにしてあります。
End If
tobi:
Next
End Sub
実行画面例
例えば、5次のときは
Rnd (-1)
Randomize (56)
として、
sh(19) = 24
から
iii = (ii + 24 * i) Mod n * n
とすると最適であることがわかります。
第6話へ 第8話へ
VBA講義第1部へ
vc++講義へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
数学研究室に戻る