みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

エクセル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演算子を使うと途中で必ずエラーになります。なぜでしょうか?

投稿日時 - 2006-10-16 16:48:58

QNo.2476470

暇なときに回答ください

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

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

プログラムに明るくありませんので、すでにその機構が上記の
プログラムに含まれているのなら失礼しました。

投稿日時 - 2006-10-16 17:20:09

補足

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

投稿日時 - 2006-10-16 18:24:22

お礼

なるほど、仰せのとおりです。
下記のように修正したところ、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

投稿日時 - 2006-10-16 18:00:39

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

こんばんは。Wendy02です。

私には、むつかしい話は加われませんが、

>2.Mod演算子を使うと途中で必ずエラーになります。なぜでしょうか?

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

Long 型は、2,147,483,647 が上限ですから、それを越える数値は扱うことが出来ません。たぶん、それを越えて、オーバーフローが起きているのだと思います。Mod の精度の一番上の型は、Long 型です。n がいくらDouble 型でも、Mod の演算で、サイズダウンしますから、Long 型の扱いになります。

投稿日時 - 2006-10-16 21:00:59

補足

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

投稿日時 - 2006-10-18 09:22:45

お礼

Wendy02さん、いつもご指導ありがとうございます。

> Mod の精度の一番上の型は、Long 型

そうなんですか?!上限があるなんて存じませんでした。Σ( ̄ロ ̄lll)

> Long 型は、2,147,483,647 が上限

それじゃ、2,482,111,348でひっかかるのは当然なんですね。
勉強になりました。<(_ _)>

投稿日時 - 2006-10-17 10:14:28

ANo.2

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

http://blog.livedoor.jp/dankogai/archives/50562776.html

参考URL:http://blog.livedoor.jp/dankogai/archives/50562776.html

投稿日時 - 2006-10-16 19:11:40

補足

昨夜、100億まで試しました。

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

ありがとうございました。o(^-^)o

投稿日時 - 2006-10-18 09:17:23

お礼

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

面白いですね。

投稿日時 - 2006-10-17 10:06:28

あなたにオススメの質問