SM持ってないけどSM孵化検証やってます。
準備に手間はかかりますが乱数調整可能です。

今回はその乱数列計算に関する内容になります。
某ツールを使えば出来るとか言わない!

WEB上で計算する奴作ってみた。
http://blog.livedoor.jp/x_x_saki_x_x/RNG/SMBreeding.html


●事前知識

SM孵化仕組み検証
http://blastoise-x.hatenablog.com/entry/SM-breed

SM孵化の乱数列生成アルゴリズムについて
http://odanpoyo.blogspot.jp/2016/12/sm.html


●使用されている乱数

「SM孵化の乱数列生成アルゴリズムについて」にもある通り、
今回のSM孵化には「TinyMT」なる乱数列が使用されている。
この乱数列は内部状態としてstatus[0-3]の128bitを持ち、それを調律したものが出力される。
BWの64bit検索でも通常PCでは全探索は事実上不可能であったので、当然全探索という力技はできない。

また、調律の処理が曲者で、非線形となる処理をしているため逆算するのが難しくなっている。
TinyMTには調律を線形とする設定もあるが、その場合の逆算についてはこちら。
http://d.hatena.ne.jp/oupo/20161210/1481361175

 ↓非線形になる原因箇所
#if defined(LINEARITY_CHECK)
    t1 = random->status[0]
	^ (random->status[2] >> TINYMT32_SH8);
#else
    t1 = random->status[0]
	+ (random->status[2] >> TINYMT32_SH8);
#endif

今回はその非線形を回避すべく、最下位bitのみに注目してみることにする。


●何故最下位bitなのか

TinyMTでは基本的にビット演算で処理を行っているが、
その中に加算が交じることで非線形となってしまっていた。
その原因は繰り上がり処理。
繰り上がりを考慮しなければ加算はただのxorであるので、
繰り上がりの影響を受けない最下位bitだけを見れば線形は保たれていることになる。


●計算してみる

status[]から出力される最下位bitを計算してみると、
出力はstatus[3]の最下位bitと同じであることが分かる。

この出力の最下位bit列 $y$ から初期status列 $x$ を求める行列 $A^{-1}$ があればそれを求めたい。
$y=Ax \Leftrightarrow x=A^{-1}y$

まず、内部状態の更新処理を行列で扱えるよう変換する。
この際、status[0]の最上位bitを除外し、127×127となるようにする。
(status[0]の最上位bitは更新処理時に欠落する情報であり、また出力最下位bitから復元できないので、あると行列が正則にならない。)
その行列の0乗から126乗を求め、status[3]の最下位bit計算に使用する行を取りだして並べると $A$ が求まる。
この $A$ を計算した結果正則であったので、逆行列 $A^{-1}$ が求まった。


というわけで、無事連続する127個の最下位bitから元のstatusを計算することができました。
個体値列からの検索もやりたいけど課題が多いのでどうなることやら。

WEB上で計算する奴も作ったので是非乱数調整しましょう!
現時点で乱数列から出力計算してくれるツール公開されてないと思うけど。