第17講 末項確定法(魔方陣作成マクロVer.3)への挑戦
第4話 Ver.2とVer.3の時間計測版
Ver.2時間計測版コード例
Dim mah(6, 6) As Byte, x(36) As Byte, y(36) As Byte, p(36) As Byte
Dim n As Byte, cn As Integer
Private Sub CommandButton1_Click()
Dim i, j As Integer
Dim hj As Date, ow As Date
hj = Timer
n = Cells(3, 8)
Rnd (-1)
If n = 4 Then Randomize (219)
If n = 5 Then Randomize (56)
If n = 6 Then Randomize (400)
syokika
zhy
sk = 0
cn = 0
ms (0)
ow = Timer
Cells(1, 28) = (ow - hj) / 10
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,
h As Byte
Dim ii As Integer, iii As Integer, kk As Byte
If cn = 100 Then Exit Sub
・
・
・
If g + 1 < n * n Then
sk = sk + 1
ms (g + 1)
Else
For j = 0 To n - 1
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(4, 12) = cn
If cn = 100 Then Exit Sub
End If
tobi:
If h = 1 Then p(mah(b, a) - 1) = 0
Next
End Sub
Ver.3時間計測版コード例
Dim mah(6, 6) As Byte, x(36) As Byte, y(36) As Byte, p(36) As Byte
Dim n As Byte, cn As Integer
Private Sub CommandButton1_Click()
Dim i, j As Integer
Dim hj As Date, ow As Date
hj = Timer
n = Cells(3, 8)
Rnd (-1)
If n = 4 Then Randomize (425)
If n = 5 Then Randomize (24)
If n = 6 Then Randomize (4768)
syokika
zhy
sk = 0
cn = 0
ms (0)
ow = Timer
Cells(1, 28) = (ow - hj) / 10
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,
h As Byte
Dim ii As Integer, iii As Integer, kk As Byte
If cn = 10 Then Exit Sub
・
・
・
If a > 0 And a < n - 1 And b = n - 1 Then
w = 0
For i = 0 To n - 2
w = w + mah(i, a)
Next
sa = Int(n * (n * n + 1) / 2) - w
If sa < 1 Or sa > n * n Then Exit Sub
If p(sa - 1) = 1 Then Exit Sub
mah(b, a) = sa
p(sa - 1) = 1
If g + 1 < n * n Then
ms (g + 1)
Else
For j = 0 To n - 1
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(4, 12) = cn
If cn = 10 Then Exit Sub
End If
p(sa - 1) = 0
Exit Sub
End If
ii = n * n * Rnd
If n = 4 Then kk = 3
If n = 5 Then kk = 13
If n = 6 Then kk = 11
If n = 3 Then kk = 1
For i = 0 To n * n - 1
・
・
・
End If
tobi:
If h = 1 Then p(mah(b, a) - 1) = 0
Next
End Sub
実験結果
表の中は1個あたりの平均算出時間 実験環境は、インテルCoreTM(3.20Ghz)650
次数 | 4 | 5 | 6 |
Ver.2 | 0.077 | 6.708 | 76.62 |
Ver.3 | 0.023 | 1.129 | 11.64 |
倍率 | 3.3 | 6.0 | 6.6 |
本当は、100個平均でデータをとりたいところですが、Ver.2だと6次は77×100=7700秒=約2時間6分もかかってしまいます。
今回はIf cn = 10 Then Exit SubとCells(1, 28) = (ow - hj) / 10を見ればお分かりのように、
10個作成するのにかかる時間です。
今回は、6次までしか実験していませんが、
7次、8次と次数が進んでいくと倍率が高くなることが予想されます。
しかし、6次で6.6倍の高速化に成功したとはいえ、1個あたり6.6秒はとても褒められたものではありません。
次の講では、一般種法を取り入れてさらなる高速化を図ります。
次数によっては、10万倍以上の高速化が図れ、
私の記憶では12次魔方陣あたりまで、20秒以内で作れるようになります。
4次と5次と6次の作成時間を比較すれば、
次数がひとつ上がるだけで、難度が極めて大きくなることがわかります。
しかも、次数のひとつ差に対する難度の差は次数が大きくなるほど大きくなります。
10次魔方陣あたりでは、シード値をどのように工夫しても1個作成するのに、
Ver.3では10時間を切ることは出来ないでしょう。
それだけ、10次あたりでは難度が高いのです。
ですから、10万倍以上の高速化が図れても、12魔方陣あたりが限界なのです。
26次魔方陣など1秒で数百の単位で作らせるにはまだまだ改良が必要です。
ところで、Timerは現在時刻を取得する関数です。
時刻を収納する変数のタイプはDateです。
Ver.2時間計測版 Ver.3時間計測版
第3話へ 第18講第1話へ
VBA講義第1部へ
vc++講義へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
数学研究室に戻る