1844674407370955169の逆演算でレンジオーバーが発生した

正則コラッツ木生成ツールでは18446744073709551615までの数を処理することができるが,3N+1を計算する段でレンジオーバーになってしまうため,最大数の経路を計算することができない.しかし,これよりも一桁小さい1844674407370955169なら回答を得ることができる.この数は5正則木上の143階にあり,1からそのノードまでの経路も確認できる.

▲上の設定で分岐リストを取り出したあと,「Get the number」で逆演算を実行したところエラーになってしまった.計算は樹高97のところで止まっている.最後に出力された数は 432760650373657297だ.しかし,この数はオーバーフローするほど大きな数のようには見えないのだが…経路を計算できるのに,その経路を逆にたどってゆく途中でエラーになるということがあるだろうか?⇒これは避けられない.コラッツ正則木上のノードはすべて奇数だが,計算過程では偶数を扱っている.偶数の種になっている奇数は小さかったとしても,偶数は巨大なものになる可能性がある.

VBにはDecimalというデータ型がある.128ビットで7.9228 x 10^28 を超える値を格納できる.ただし,かなり遅いようだ.Uint128というデータ型があるとよいのだが,VBには入っていない.BigIntegerというのがある.これは桁数に制限がない.試してみよう.⇒実装した.VS 2017ではSystem.Numericsを参照できなかったので,VS 2019を使うことにした.それに加えて.NET 5.0を使う必要がある.ネット情報では.NET 4.0以降で実装されたとなっているが,何かいろいろあったようで,いまのところ確実に動作するためには.NET 5.0が必須のようだ.

相当重くなるのではないかと思ったが,むしろ逆に速くなっている.前の版で3正則木樹高11という設定で5分17秒掛かっていたテストが,3分37秒に短縮された.マイクロソフトはこの機能に関しては相当気合を入れて作っているように思われる.億兆円,京兆円という金額を1円の誤差もなく計算するにはこのような機能は必須ということだろう.

▲新しい版でRoot Numberに17602325を設定して3正則木樹高5を走らせて冒頭の1行を表示しただけでハングしてしまった.旧版で動作確認すると,totalとMAXが一致しないという理由で停止している.total=4, MAX=364となっているので,最初の一行をダンプして打ち切られている模様だ.⇒現行では樹高が設定値を超えると打ち切るようになっているが,ルートが1でない場合に対応していない.⇒Offsetを引く必要がある.⇒動作するようになった.

▲Stopボタンで停止したとき,totalとMAXが一致しないという理由で停止する.Cancelボタンで打ち切ったときも同様のことが起こる.Stopボタンの場合は値によって判定できるが,Cancelのときは,イベントハンドラの中でResetFlagでリセットしているため,状態が取れない.⇒いや,ResetFlagの中でResetFlagを立てているので判別できるのではないか?⇒ループの中でリセットしている.⇒対処した.

BigNumberの導入によってレンジオーバーが発生する可能性がゼロになったので,これまで表示していたオーバーフローカウントを廃止して,Void node countを表示するようにした.この値は,3の倍数より下の部分木に含まれるノード数で,この値とValid node countの和がMax node countに一致しなければ,どこかで誤っていることになる.

B面のRoot numberは不要なのではないか?A面ではノードを指定して部分木を取るという使い方が考えられるが,B面のGet the sequenceはかならず1までの経路を出力するようになっていて,Get the numberはその逆演算に相当するのだから,Root numberはつねに1でよいように思われる.仮に,これを可変にしておいたとしても,その数字から始まる意味のある枝番号リストを作るのはかなり難しいので,ほとんど用途がない.むしろ,A面のOdd numberとB面のMax odd numberの桁数を増やした方がよいと思う.

また,B面のMax degreeは読み取り専用でよいのではないか?Get the sequenceでは,指定したノードが通る経路の最大枝番号で自動的に上書きされるし,Get the numberでもストレートな経路を通るだけだから,枝番号リストの最大値以外の値は意味がない.Truncated treeでは任意の値が設定できるというのは少し意味があるが,そのパスの最大枝数以下の値を与えても意味がない.実際,現状ではこれらすべての場合で,実行結果によって上書きされるようになっている.

B面を実行中はイベントを取らないようになっているのだろうか?処理中にタブを切り替えようとしても動かない.⇒時間が掛かるのはTruncated tree の場合だけで,それ以外はほとんど瞬時に終わると見てよいので,Truncated tree の場合だけイベントを取るようにすればよいのではないか?⇒タブを切り替えてもB面のループを回っているので,A面には変化がない.B面には打ち切りボタンというのがないので,タブの切り替えができても意味がないと思う.つまり,B面では処理が終わるまで待つしかないという仕様になる.

▲枝数3樹高41でエラーが出た.Int32のレンジオーバーが出ている.Max node countがオーバーフローしたのだろうか?ノード番号を格納しているodd[]という配列をRedimしようとするところでレンジオーバーしているようだ.配列サイズは Int32を超えられないのではないだろうか?⇒VBでは配列の要素数はInt32の範囲内になっているので,2147483647を超える配列は作れない.三元木の場合は,樹高19が限界だ.樹高20で,5230176601となり上限を超えてしまう.

ただし,現行では予定した配列セルをすべて使っている訳ではないので,もっと小さい配列でも動作するはずだ.あらかじめ充填率が計算できれば間に合う程度の配列を作る用意もできるのだが…⇒しかし,配列サイズを制限してやっても,別のエラーになる.

image

Redimでエラーが出ている.配列要素数をInt32.MaxValueの1/4まで削減してようやく動くようになった.MaxValueの1/2では動くことは動くが途中で重くなってほとんど停止してしまう.(これはおそらくメモリ不足ではないかと思う)実際には有効ノードというのはずっと少ししかないので,充填率を予測できれば最小限で間に合わせることができる…

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA