前段时间,我将this Python implementation of the Pollard-Brent algorithm移植到Clojure。它的工作原理也很快。那不是问题。而且,当给定相同的非随机种子值和步进函数时,它可以精确地再现Python代码的兔子和乌龟的位置。
但是当我在研究它时,我不禁注意到乌龟和野兔的移动与我根据布伦特论文(或Wikipedia或任何其他参考文献。
具体来说,在乌龟传送到野兔的位置后,野兔前进distance
步数,然后然后再前进distance
步数。同样,在Brent-Pollard算法中,中间值也很重要。但是,此代码仅保存第二个野兔“路径”的步骤。
以下是Python代码的6-18行,并附有我的评论:
while g==1:
# Tortoise (x) moves to hare (y)
x = y
# Hare (y) moves ahead by r steps
for i in range(r):
y = ((y*y)%N+c)%N
k = 0
# Hare (y) moves ahead by another r steps,
# with checkpoints at every m steps (the checkpoints are
# for the factorization; not part of Brent's cycle-finding algo proper)
while (k<r and g==1):
ys = y
for i in range(min(m,r-k)):
y = ((y*y)%N+c)%N
q = q*(abs(x-y))%N
g = gcd(q,N)
k = k + m
我今天要回顾我的代码,并决定通过模拟简化版本以显示索引来对其进行确定的测试。这些是当前代码给出的索引:
当前版本:
Distance: 1
Tortoise at: 1
Hare starts at: 2
Hare path: [3]
Distance: 2
Tortoise at: 3
Hare starts at: 5
Hare path: [6 7]
Distance: 4
Tortoise at: 7
Hare starts at: 11
Hare path: [12 13 14 15]
Distance: 8
Tortoise at: 15
Hare starts at: 23
Hare path: [24 25 26 27 28 29 30 31]
Distance: 16
Tortoise at: 31
Hare starts at: 47
Hare path: [48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63]
Distance: 32
Tortoise at: 63
Hare starts at: 95
Hare path: [96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127]
同时,这是我希望算法执行的操作:
预期输出:
Distance: 1
Tortoise at: 1
Hare path: [2]
Distance: 2
Tortoise at: 2
Hare path: [3 4]
Distance: 4
Tortoise at: 4
Hare path: [5 6 7 8]
Distance: 8
Tortoise at: 8
Hare path: [9 10 11 12 13 14 15 16]
Distance: 16
Tortoise at: 16
Hare path: [17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32]
Distance: 32
Tortoise at: 32
Hare path: [33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64]
即使“预期”版本在算法中的使用,在Clojure中的读取效果更好,但平均花费的时间却是原来的两倍(从索引看,这是有道理的。)
我的问题: