コラッツ完全木ノードアドレスコードの拡張

完全木を使いながら,すべての奇数ノードに一意のアドレスを割り当てる方式を編み出した.これは最強の解決策と言えると思う.この方式では非3倍数と3倍数を完全に分離し,非3倍数のみからなる完全木上のノードには親ノードの子ノードのうち非3倍数のみを数えた順序数を与え,3倍数では3倍数のみを数えたときの順序数を与える.これにより,すべての奇数ノードはユニークなアドレスコードによって一意に特定することができるようになる.非3倍数に与えられる枝番号は正値とし,3倍数の枝番号は負値で表記する.ただし,この負値の枝番号はつねにアドレスコードの終端にしか現れない.

このアドレス方式のメリットはアドレス→番号変換で,任意の枝番号列を指定することができるというところにある.一般木のアドレス方式ではランダムなアドレスコードを与えると大概の場合は,コード上のどこかにほぼ確実に3倍数が現れるため,「無効なアドレス」として短縮されてしまう.逆に言えば,完全木アドレス方式では無効なアドレスというのが原理的に発生しない.これにより,完全正則木の最大枝数をD,木の高さをHとするとき,D^Hの完全に均一なアドレス空間を確保することができる.完全木アドレスを拡張して3倍数ノードに負の枝番号を付与する方式(負値枝番号はアドレスコードの終端のみ)ではあらゆる長さの任意のアドレスコードが有効なアドレスとして認識される.

すでに実装して検証テストも完全木モードで動作するようになっているが,まだ多少の問題が残っている.どうもどこかで3倍数の一部が落ちているようだ.まず,このシューティングから入ることにしよう.⇒明らかに現行の隣接リスト生成には手抜かりがある.5-3という関係が落ちている.アドレス→番号変換を単独で実施したときには正しく生成されているので,検証テストで処理が脱落しているのだろう.MakeAdjacencyListで失敗しているようだ.

いや,なにか勘違いしていたのだろうか?少なくとも2^5では3倍数を含む1~63までの奇数がすべて揃っている.2^6でもOKだ.多分テストの手順を誤っていたのだろう.おそらく,Odd numberが更新されているのを忘れて大きい数から検定を開始してその結果を見ていたのではないか?2^7でも確認した.OKのようだ.コラッツ完全木対応修正はほぼ,完全に完了したのではないかと思う.

あとは,マニュアルを書きながら動作確認するまでだ.今回のマニュアル更新では「アドレス」という用語を強調する必要がある.この意味ではアドレスコードの構文に1.2.3-4のような地番表記を導入するというのは意味があるのではないだろうか?内部的に-を.-に置き換えるというだけだから,処理的には難しくない.正負の地番が存在するというより,3倍数のアドレスは3番地の4のように分筆されるとした方がわかり易いような気がする.非3倍数ノードが独立した地番を持つ宅地であるとすれば,3倍数は親ノードの地所に付属する1区分という理解でよいだろう.

▲アドレスコード中ピリオドだけが連続していると黙って後ろをカットしてしまうが,メッセージを出した方がよい.

ここまで進むと,偶数を含むすべての整数にアドレスを与えることも不可能ではなくなる.偶数の場合には,たとえば,1.2.3+4のように表記すればよい.これを使えば完全にユニバーサルなアドレスコードを確立することができる.検証テストも奇数だけではなくすべての偶数を含む整数全体のテストを実施することができるだろう.かなり大掛かりな修正になってしまうが,やるだけの価値はあるのではないだろうか?

ただし,検証テストでこれをやると作図上の問題が発生するかもしれない.偶数はコラッツ木上では必ずしも終端ノードではないので,その従属関係まで表示しようとすれば,完全木の範囲を大幅に逸脱してしまうし,解析も相当困難なものになる.偶数ノードつまり,2倍数を3倍数に準ずるような終端ノードとして扱うことは不可能ではないが,見易い図式になるかどうかはかなり疑問だ.たとえば,6, 12, 24, 48, 96,…などのノードはすべて3の子ノードということになる.かなりごちゃごちゃした見辛いものになりそうだ.

コラッツ数列やアドレス番号変換などを拡張して偶数を扱えるようにするのは悪くないが,検証テストで偶数を扱うのは,特に隣接リストを出力してグラフを描画するというのはあまりよいアイディアではない.従って,検証テストの対象は現行通り,奇数に限定するというのでよいと思う.しかし,「ユニバーサルアドレスコード」という概念が理論的には成立することはどこかで示しておいた方がよい.

偶数を表記するのに地番+枝番の形式を適用するというのは悪いアイディアではないが,実装的にはやや難点がある.評価関数では+12を単に12として扱うことしかできないからだ.現行では枝番号を符号付き整数として扱っているが,たとえばそれをInt16の範囲に限定し,それより大きい数値は偶数の枝番として扱うなどの方策も考えられないではないが,結構面倒だ.最初に+で分割してその後ろの数値を取り出してしまうということは考えられなくもない.これは比較的安全に履行できそうな気もする.⇒ユニバーサルアドレスコードというアイディアはかなり魅力的なので,なんとか実現してみたい…

4010814653485のコラッツ数列を求めようとしてエラーが発生する.⇒Exit Functionが入っていなかったため,エラートラップに入ってしまった.⇒対処した.

また厄介な問題が出てきた.完全木モードでは2倍数と3倍数を処理対象範囲に含めようとしている.完全木的にはいずれも終端ノードとして扱われるが,場合によっては2倍数が3倍数に連結するということが起こり得る.たとえば,444は2倍数だが,上位ノードの111は3倍数だ.3倍数の上位ノードが2倍数になるということはあり得ないから,2倍数→3倍数というパターンだけ考えればよいはずだが,そのような準備は整っていない.現行ではどちらか片方だけが発生するという前提になっているが,まず,2倍数を処理して,次に3倍数を処理するという手順に変更しなくてはならない.コラッツ数列と枝番号変換の両側で対応する必要がある.444を完全木で展開すると,

1. 2. 1. 1. 1. 1. 1. 1. 2. 1. 1. 1. 2. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1-1. +2

のようになる.どうもイマイチなので,以下のように変えてみた.

1. 2. 1. 1. 1. 1. 1. 1. 2. 1. 1. 1. 2. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1-1^2

これ以上複雑になることはないので,とりあえず,これでゆくことにする.⇒最終的には,以下のような書式を採用することにした.

1. 2. 1. 1. 1. 1. 1. 1. 2. 1. 1. 1. 2. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1-1*2

「.」で区切られた単位が完全木上のノードを示す番地であり,-1*2はその枝番(詳細付番)に相当する.詳細付番付きの番地はアドレスコードの終端にしか現れない.パターンとしては,a-b, a*b, a-b*cの3種だけだ.a-bは3倍数を示し,a*bは2倍数,a-b*cは3倍数に接続する2倍数である.これですべての整数にユニバーサルなアドレスコードを与えることができるようになった.

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA