関数 f があるとします。
f(0) = 0
f(i) = (i - 1) % 4
f(0..12):
0 0 1 2 3 0 1 2 3 0 1 2 3
それぞれ 1 と 4 であるサイクルの開始とサイクルの長さを見つけたいと思います。カメとウサギのアルゴリズムは反復関数で機能しますが、反復関数はありません。反復されない関数で動作する他のアルゴリズムはありますか、またはこのために亀とウサギのアルゴリズムを変更できますか?
編集:
Jason S's answer を使用して、私はこれを思い付くことができました。これはうまくいっているようです:
public static Tuple<int, int> ModifiedTortoiseHare(Func<int, int> f, int x0 = 0, int checks = 4)
{
for (; ; x0++)
{
int lam = 0, tortoise, hare;
do
{
lam++;
tortoise = f(x0 + lam);
hare = f(x0 + 2 * lam);
} while (tortoise != hare);
int mu = -1;
do
{
mu++;
tortoise = f(x0 + mu);
hare = f(x0 + mu + lam);
} while (tortoise != hare);
if (mu != 0) continue;
bool correct = true;
int lamCheckMax = lam * checks;
for (int x = 0; x < lamCheckMax; x++)
{
if (f(x0 + x + mu) != f(x0 + x + mu + lam))
{
correct = false;
if (mu != 0) x0 += mu - 1;
break;
}
}
if (correct) return Tuple.Create(x0 + mu, lam);
}
}