• ベストアンサー

エクセルVBAで「コラッツの予想」の検証?

「コラッツの予想」を確かめるため、下記のようなマクロを書いてみました。 コラッツの予想とは「正の整数に対して、偶数なら2で割り、奇数なら3を掛け1を足す。これを繰り返すとやがて1になる。」という未だ証明されてない数学の問題です。 Sub Collatz_test02() Dim x As Double t = Time() With Application .ScreenUpdating = False .Calculation = xlCalculationManual For n = 1 To 10000000 x = n + 1 '.StatusBar = n & "目を処理中です。" 'Cells(n) = x Do While x > 1 If Int(x / 2) = x / 2 Then 'Modは途中でエラー! x = x / 2 Else x = x * 3 + 1 End If Loop Next .StatusBar = "" .ScreenUpdating = True .Calculation = xlCalculationAutomatic End With Cells(1 , 1) = Time() - t End Sub 1.セルにいちいち数値をいれたり、進行状況をStatusBarに表示したりしなければ1~1000万までは約8分で終了し、少なくとも1000万までは「予想」は正しいことを実証できましたが、このペースではこれを10億や100億まで試すわけにもいきません。 なにか良い方法はありますでしょうか?数台のPCを使って分散するという方法以外でお願いします。(エクセル2000です) 2.Mod演算子を使うと途中で必ずエラーになります。なぜでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • kinki-u
  • ベストアンサー率11% (1/9)
回答No.1

プログラム自体よりもアルゴリズムの話ですが、すでにチェックを 終えた数値に一旦なれば、そこでその数値の計算を終了するという 一文を入れたらどうでしょうか? つまり、500という数字を検証して いるのならば、499以下の数字になればそこで証明済みなのでストップ させるということです。毎回カウントアップしていけば、すぐに チェックできると思います。 プログラムに明るくありませんので、すでにその機構が上記の プログラムに含まれているのなら失礼しました。

merlionXX
質問者

お礼

なるほど、仰せのとおりです。 下記のように修正したところ、1000万までわずか30秒でした! このペースなら100億にも手が届きそうです。 Sub Collatz_test03() Dim x As Double, n As Double Dim t As Date t = Time() Cells(1, 1) = t With Application .ScreenUpdating = False .Calculation = xlCalculationManual For n = 1 To 10000000 x = n + 1 Do While (1) If Int(x / 2) = x / 2 Then x = x / 2 Else x = x * 3 + 1 End If If x = 1 Then Exit Do If x < n Then Exit Do Loop Next .StatusBar = "" .ScreenUpdating = True .Calculation = xlCalculationAutomatic End With Cells(2, 1) = Time() Cells(3, 1) = Time() - t End Sub

merlionXX
質問者

補足

偶数の判定に便利なMOD演算子をつかうと、n=113383で必ずエラーになります。なぜかわかりませんでしょうか?

その他の回答 (2)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。Wendy02です。 私には、むつかしい話は加われませんが、 >2.Mod演算子を使うと途中で必ずエラーになります。なぜでしょうか? >偶数の判定に便利なMOD演算子をつかうと、n=113383で必ずエラーになります。なぜかわかりませんでしょうか? Long 型は、2,147,483,647 が上限ですから、それを越える数値は扱うことが出来ません。たぶん、それを越えて、オーバーフローが起きているのだと思います。Mod の精度の一番上の型は、Long 型です。n がいくらDouble 型でも、Mod の演算で、サイズダウンしますから、Long 型の扱いになります。

merlionXX
質問者

お礼

Wendy02さん、いつもご指導ありがとうございます。 > Mod の精度の一番上の型は、Long 型 そうなんですか?!上限があるなんて存じませんでした。Σ( ̄ロ ̄lll) > Long 型は、2,147,483,647 が上限 それじゃ、2,482,111,348でひっかかるのは当然なんですね。 勉強になりました。<(_ _)>

merlionXX
質問者

補足

100億まで試したところ、6時間弱で終了! 無限ループにならなかったということは100億までは「コラッツの予想」の検証ができたということですよね。できたからと言って得するわけじゃないですけど(笑) ありがとうございました。o(^-^)o

  • kinki-u
  • ベストアンサー率11% (1/9)
回答No.2

ここが参考になりそうです。 (コラッツ予想は、一回とんでもない数字に行ってから帰ってくる こともあるので難しいですね。というかおもしろいですね) http://blog.livedoor.jp/dankogai/archives/50562776.html

参考URL:
http://blog.livedoor.jp/dankogai/archives/50562776.html
merlionXX
質問者

お礼

kinki-uさん、何度もありがとうございます。 御紹介のサイトはVBAではないのでよくわかりませんが、113383が1812855948になってひっかかったようです。 わたしのは120回目で2482111348になってひっかかりました。 If x Mod 2 = 0 Then を If Int(x / 2) = x / 2 Then に変えてやって247回目で1に収束したのですが。 面白いですね。

merlionXX
質問者

補足

昨夜、100億まで試しました。 6時間弱かかりましたが無限ループになりませんでしたので100億までは「コラッツの予想」の検証ができました。できたからと言って別にどうかなるわけじゃないんですが(笑) ありがとうございました。o(^-^)o

関連するQ&A