在Python字典中,((j*5)和#x2B;1)%2**i如何循环所有2**i

在Python字典中,((j*5)和#x2B;1)%2**i如何循环所有2**i,python,algorithm,dictionary,linear-probing,Python,Algorithm,Dictionary,Linear Probing,我正在研究python如何实现字典。python字典实现中的一个等式与使用该等式对空字典槽进行伪随机探测有关 j = ((j*5) + 1) % 2**i 这是可以解释的 我读过这个问题,基本上理解了字典是如何实现的 我不明白的是,为什么/如何: j = ((j*5) + 1) % 2**i 循环使用2**i的所有余数。例如,如果i=3,则总起始大小为8j经历以下循环: 0 1 6 7 4 5 2 3 0 0 1 6 15 12 13 2 11 8 9 14 7 4 5 10 3 0

我正在研究python如何实现字典。python字典实现中的一个等式与使用该等式对空字典槽进行伪随机探测有关

j = ((j*5) + 1) % 2**i
这是可以解释的

我读过这个问题,基本上理解了字典是如何实现的

我不明白的是,为什么/如何:

j = ((j*5) + 1) % 2**i   
循环使用
2**i
的所有余数。例如,如果
i=3
,则总起始大小为8<代码>j经历以下循环:

0
1
6
7
4
5
2
3
0
0 1 6 15 12 13 2 11 8 9 14 7 4 5 10 3 0
如果起始大小为16,则它将经历以下循环:

0
1
6
7
4
5
2
3
0
0 1 6 15 12 13 2 11 8 9 14 7 4 5 10 3 0
这对于探测字典中的所有槽非常有用但它为什么工作?为什么
j=((j*5)+1)
工作,但不
j=((j*6)+1)
j=((j*3)+1)
这两种方法都陷入了较小的周期


我希望对这一点有一个更直观的理解,而不是简单的方程,这就是为什么他们使用它。

这与伪随机数生成器使用的原理相同,正如贾斯珀所暗示的,即。线性同余生成器是遵循关系
X_(n+1)=(A*X_n+c)mod m
的序列。从wiki页面

一般LCG的周期最多为m,对于某些因子a的选择,周期远小于m。当且仅当满足以下条件时,LCG将对所有种子值具有完整的周期:

  • m
    c
    是相对优质的
  • a-1
    可被
    m
    的所有素数因子整除
  • 如果
    m
    可被
    4
    整除,则
    a-1
    可被4整除
  • 很明显,5是满足这些要求的最小
    a
    ,即

  • 2^i和1是相对素数
  • 4可被2整除
  • 4可以被4整除
  • 同样有趣的是,5不是满足这些条件的唯一数字。9也会起作用。将
    m
    取为16,使用
    j=(9*j+1)%16

    0 1 10 11 4 5 14 15 8 9 2 3 12 13 6 7
    

    这三个条件的证明可以在第5页上找到,以及其他一些与PRNG相关的定理,这些定理可能也很有趣。

    因为5与2^i同素,所以是5*2^i。在你的引文上方几行:“请参阅随机数生成的任何文本进行证明”:@OliverCharlesworth根据该论点,然后(j*3)+Knuth的《计算机编程的艺术:第2卷》对类似问题进行了广泛的处理,你可能会发现这很有帮助。这只是一个Python问题、字典问题,甚至是一个编程问题。在定理的陈述中,它不能是“如果且仅当”;e、 g.将
    c=0
    a
    作为原始的根模2^i将产生一个完整的周期,但是
    0
    m
    @kevmo314不是互质,感谢您的响应。我承认这是正确的答案,但我不确定我是否完全理解每一种情况。例如,当a=7,c=1,m=13时,我得到的周期长度是12,而不是13,但这似乎满足了所有3个要求。另一方面,对于a=7,c=1,m=18,它工作得很好,我得到了预期的周期长度18。我假设在我之前的评论中,m=13可能不满足条件2,因为13没有素数因子(因为它本身就是素数)Knuth btw。还提到当m是不同素数的乘积时,只有a=1才会产生完整的周期,所以这应该让你知道不应该为
    m
    选择什么:)@FairlyNerdy你的后续行动是正确的,13的素因子包括13,其中6不能被整除。如果
    m
    由不同的素因子组成,那么唯一的解决方案将是a=1,正如@poke所指出的。