2008年11月14日金曜日

EXCELのマクロ(VBA)を触ってみた、ランダム陣取りシミュレータ?

ちょっと待ち行列を計算する用事があったので、今まで操作録以外全然触らなかったExcelのマクロの書き方を勉強してみた。
 
 

しかし、なぜか予定と違って観察系の陣取りシミュレータができた。。
    仕様はこんな感じ
  • セルに1-100までの数字を並べる

  • ランダムに1つチョイス、これまたランダムな場所に上書きコピーする

  • 繰り返す。そのうち1つの数字が天下を統一する。


 

待ち行列の計算しようとおもったんですよ、本当ですよ?
 

ということで、数字のセットとランダムコピーのマクロ(VBA)を載せておこう。
 
 


準備用マクロ(VBA):1-100までの数字をセット、ついでにカウンタを0にリセットする


1行に5列ずつで、20行目まで数字を置いていく。

[sourcecode language='vb']Sub reset()
s = 1
For j = 1 To 20
For i = 1 To 5
' セルに数字を書き込む
Cells(j, i) = s
s = s + 1
Next i
Next j

' カウンタリセット、F5がカウンタ
Range("F5") = 0
End Sub[/sourcecode]
 

これで準備はOK、リトライも簡単。
 
 

シミュレータ実行用マクロ(VBA):ランダムに数字を選んで1回コピーの繰り返し


ところどころ乱暴だけど、ランダムコピーの処理。
rnd()の周りはなんかきれいなやり方があるんだろうなぁ。

[sourcecode language='vb']Sub Shuffle()
Randomize
s = Range("F5")

For i = 1 To 500
rndset:
m = Round((Rnd * 40 / 2 + 1), 0)
j = Round((Rnd * 10 / 2 + 1), 0)
k = Round((Rnd * 10 / 2 + 1), 0)
l = Round((Rnd * 40 / 2 + 1), 0)
' 6とか21とか、はみ出し系の結果が出るのでやり直しさせる
If j = 6 Or k = 6 Or m = 21 Or l = 21 Then
GoTo rndset
Else
' 参考用に座標を出力しておく
Range("F1") = j
Range("F2") = k
Range("F3") = m
Range("F4") = l
' これはカウンタ
Range("F5") = s + i
' ランダムに選んだマスの数字を任意の場所に上書きコピーする
Cells(m, j).Copy Destination:=Cells(l, k)
End If
Next i

End Sub[/sourcecode]
 
 


実行してみる、グラフつけると面白い


視覚的なことを考慮してグラフとか色々つけている、リアルタイムで勢力図が見れて面白い。
これもマクロでセットアップしたら良いんだろうけどそれはまた今度かな。
 

統一させるまで見届ける場合は While でまわせばOK、大体 4000-8000 位の施行で終わるがたまに1万超えるし。
 

スタート時点の図、すべての勢力は1つで均等
[caption id="attachment_1051" align="alignnone" width="300" caption="画像:陣取り合戦スタート"]画像:陣取り合戦スタート[/caption]
 
 

ランダムコピー500回実行したところ。93が最大勢力(26ヶ)
[caption id="attachment_1052" align="alignnone" width="300" caption="画像:500ターン"]画像:500ターン[/caption]
左下のところはグラフ用、COUNTIF文 と IF文 で0個になったら勝手に消えるようにしてグラフを見やすいようにしている。
 
 

統一までほったらかしてみる、2300くらい。
とても三国時代だ、NINTENDO64(仮名) vs PC-98(仮名) vs .. JR-100(仮名)? といった所か。
[caption id="attachment_1053" align="alignnone" width="300" caption="画像:2300ターンくらい、三国時代"]画像:2300ターンくらい、三国時代[/caption]
 
 

完全に天下統一 ※Whileに変更したので500回のサンプルとは違う回
[caption id="attachment_1054" align="alignnone" width="300" caption="画像:天下統一!"]画像:天下統一![/caption]
 

見事9102ターン目で PC-98(仮名) が天下統一を果たした、Cバス万歳と言うことなんだろうか。
 
 
 

えーかげん と言うか 今更というか、Excelマクロ も活用したほうがいいなと思った。