第16講 魔方陣作成の高速化(数万倍へ)
第9話 実験結果とそれに基づくVer.2完成一歩前版
実験結果による最適値
n | 4 | 5 | 6 |
Randomize()の括弧内の数字(シード値) | 219 | 56 | 400 |
sh()の括弧内の数字 | 3 | 19 | 4 |
sh()の値 | 7 | 24 | 13 |
Ver.2コード
Dim mah(6, 6) As Byte, x(36) As Byte, y(36) As Byte
Dim n As Byte, cn As Integer
Private Sub CommandButton1_Click()
Dim i, j As Integer
n = Cells(3, 8)
Rnd (-1)
If n = 4 Then Randomize (219)
If n = 5 Then Randomize (56)
If n = 6 Then Randomize (400)
zhy
sk = 0
cn = 0
ms (0)
Cells(4, 12) = cn
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, kk As Byte
a = x(g)
b = y(g)
ii = n * n * Rnd
If n = 4 Then kk = 7
If n = 5 Then kk = 24
If n = 6 Then kk = 13
If n = 3 Then kk = 1
For i = 0 To n * n - 1
iii = (ii + kk * i) Mod n * n
Ver.2が完成して、一応6次魔方陣まで作れるようになりました。
今回のコードでも自動実験を粘り強く続ければ7,8次あたりも出来るようになるかもしれません。
しかし、1個が出来るまでの時間はあっという間に出来ても1秒に数百個単位で作らせるとなると、
まだまだ改善が必要です。
実はすぐに第17講に入り、末項確定法に挑むつもりでしたが、
Ver.2の範囲内でもう一つ改良できることを思い出しました。
よく考えてみると、
Sub ms(g As Byte)
Dim i As Byte, j As Byte, k As Byte, a As Byte, b As
Byte, w As Byte
a = x(g)
b = y(g)
For i = 0 To n * n -
1
mah(b, a) = i + 1
If g > 0 Then
For j = 0 To g -
1
If mah(b, a) = mah(y(j), x(j)) Then GoTo
tobi
Next
End If
のピンクの部分は無駄があります。
毎回、今まで入力したものと重複がないか調べていますが、
そんなことをしなくても簡単に重複検査ができます。
例えば、グローバル配列p(i)を用意しておいて
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 〜 |
p(i) | × | × | × | × | × | × | × | × | × | × | × | × |
使っていない数字を×(実際には0)を入れておいて、その数字を使用したら○(実際には1)に変更し、
○が重なるときは重複と判定すればよいのです。
尚、配列の要素は0から始まりますので、p(mah(b,a)-1)としておくとよいでしょう。
ですから、表も数字がずれています。
今回の改良をもってVer.2の完成とします。
第8話へ 第10話へ
VBA講義第1部へ
vc++講義へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
数学研究室に戻る