Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 周期检测算法_Algorithm_Function_Detection_Cycle_Floyd Cycle Finding - Fatal编程技术网

Algorithm 周期检测算法

Algorithm 周期检测算法,algorithm,function,detection,cycle,floyd-cycle-finding,Algorithm,Function,Detection,Cycle,Floyd Cycle Finding,假设我有一个函数f: f(0) = 0 f(i) = (i - 1) % 4 f(0..12): 我想找到循环开始和循环长度,分别是1和4。 龟兔算法使用迭代函数,但我没有迭代函数。 是否有其他算法可用于非迭代函数,或者可以为此修改龟兔算法 编辑: 根据Jason的回答,我终于想出了这个似乎有效的方法: 公共静态元组ModifiedToSoisehare(Func f,int x0=0,int checks=4) { 对于(;;x0++) { int lam=0,乌龟,兔子; 做 { lam+

假设我有一个函数f:

f(0) = 0
f(i) = (i - 1) % 4
f(0..12):

我想找到循环开始和循环长度,分别是1和4。 龟兔算法使用迭代函数,但我没有迭代函数。 是否有其他算法可用于非迭代函数,或者可以为此修改龟兔算法

编辑:

根据Jason的回答,我终于想出了这个似乎有效的方法:

公共静态元组ModifiedToSoisehare(Func f,int x0=0,int checks=4)
{
对于(;;x0++)
{
int lam=0,乌龟,兔子;
做
{
lam++;
乌龟=f(x0+lam);
兔子=f(x0+2*lam);
}而(乌龟!=野兔);
int mu=-1;
做
{
mu++;
乌龟=f(x0+mu);
兔子=f(x0+mu+lam);
}而(乌龟!=野兔);
如果(mu!=0)继续;
bool correct=true;
int lamCheckMax=lam*检查;
对于(int x=0;x
如果函数是一个“黑匣子”,并且您能够为任何单个x找到f(x)(无论是对实数有效还是仅对整数有效),但您不知道任何其他内容,则没有找到循环开始和长度的通用方法。例如,考虑函数

f(k) = (k - 1) % 4 + g(k)
g(k) = max(0, k-1000000)
然后f(k)看起来像是每4个整数重复一次,但是当你到达k=1000000时,模式就停止了


如果函数的范围有限,并且您可以测试所有整数,则可以使用龟兔算法(=)提供帮助

不是迭代函数求值,而是计算f(k0+k)和f(k0+2*k),直到它们匹配为止,此时怀疑的周期是k,您只需重复所有值,以验证循环是否继续


你的问题似乎是一个有很多答案的等价问题。

对于你给出的fn,因为它被4除,长度是4,并且没有增加值,所以0实际上是循环的开始,而不是1。如果你使用已经指出的图表来实现它,你实际上可以观察到这一点。
由于这些是fn值,您可以使用链表代替,fn返回的每个值,如果没有,请将其添加到列表中,否则您可以有一个循环。假设只有一个循环。

可能重复@SuprDewd:您是否在寻找重复至少两次且长度最长的循环,还是以最长的总长度重复的循环?(例如,“01010101010123401234”作为f(0)=0,f(1)=1,f(2)=0,f(3)=1等的简写,其中有6个循环的0 1,总长度为12,2个循环的0 1 2 3 4,总长度为10)或其他什么?……或者你知道f(x)总是遵循某种特定的形式吗?(例如,
f(x)=(x-x0)%m
对于所有x>一些x1)我正在寻找最长的周期。我上面的代码将返回起始0和长度2,但我很确定这是很难避免的。例如序列:123123…*50亿次123*…123456123456。。。像这样的序列很难解释。但是你说的“你只需要重复所有的值来验证循环是否继续”是什么意思?可能还有无限多的值,我无法全部检查…我说的是“如果函数有一个有限的范围”-你在问题陈述中没有说函数是在有限范围还是无限范围上。如果是有限的,请全部检查。如果无限,您需要另一个成功/失败的标准,因为您无法全部检查它们。
f(k) = (k - 1) % 4 + g(k)
g(k) = max(0, k-1000000)