List 稍微更改种子时稍微更改随机列表的输出 问题:

List 稍微更改种子时稍微更改随机列表的输出 问题:,list,algorithm,random,shuffle,seed,List,Algorithm,Random,Shuffle,Seed,我想随机洗牌一个列表,但使用种子值s,这样,当只稍微改变s时,洗牌的输出也只会稍微改变 细节: 我有一个元素的排序列表,例如: [0,1,3,5,7] 此列表应多次洗牌,每次使用种子值s。当两个种子值s1和s2=s1+d彼此接近时,无序列表也应“相似” 所谓“相似”,我的意思是,新的无序列表中的元素要么与使用原始种子值时的元素相同,要么仅被原始列表中与其接近的值替换(例如,它们在原始列表中的直接邻居) 编辑:输出仍然应该是确定的,即在对相同的输入列表进行混洗时使用相同的种子s1,应产生相同的混

我想随机洗牌一个列表,但使用种子值
s
,这样,当只稍微改变
s
时,洗牌的输出也只会稍微改变

细节: 我有一个元素的排序列表,例如:

[0,1,3,5,7]
此列表应多次洗牌,每次使用种子值
s
。当两个种子值
s1
s2=s1+d
彼此接近时,无序列表也应“相似”

所谓“相似”,我的意思是,新的无序列表中的元素要么与使用原始种子值时的元素相同,要么仅被原始列表中与其接近的值替换(例如,它们在原始列表中的直接邻居)

编辑:输出仍然应该是确定的,即在对相同的输入列表进行混洗时使用相同的种子
s1
,应产生相同的混洗列表

上述列表的示例(请注意,添加较小的值
d
只会略微扰动列表,即许多值保持不变,如果它们发生变化,通常会被原始列表中的相邻值替换。随着偏移量的增加,“差异”列表之间的值可能会进一步增加,也可能会选择邻居之外的值):

种子: 输出:
s
[5,0,1,7,3]
s+d
[5,0,3,7,1]
s+2d
[7,0,3,5,1]
s+3d
[7,0,1,3,5]

生成并留出列表的随机洗牌
R
。然后,每次使用seed
s
调用生成器时:

  • s=s%factorial(N)
    其中
    N
    是列表的长度(或者只要求
    s
    应介于0和N!-1之间)
  • 属于
    s
  • p
  • p
    应用于
    R
    并返回结果
  • 这种结构使得排列
    p(s)
    p(s+1)
    在词典顺序上相邻。这些步骤可以有效地实施


    您可以将同样的想法用于排列集的其他排序,这会使更改更为最小化,例如,但我不知道步骤3。在这些情况下可以有效地实现。

    在这种情况下,很难给出“相似”的度量。[Ex:Apple的第一个shuffle实现有一个问题——人们觉得歌曲的混合不够随机]

    我将以另一种方式重新表述这个问题:“我们如何修改一些简单的洗牌算法,从而达到预期的结果?”。

    以下是我的想法:

  • 我们需要一个基线种子
    s
    -(较大的,与您的案例/数据中通常使用的列表大小相当,此值可以硬编码或作为参数传递,但如果我们改变
    s1
    ,则应保持固定)
  • d=abs(s1-s)
    -(s1离s有多远)
  • 使用
    s
    作为种子执行默认的随机洗牌(您选择的语言随机库中的任何函数都可以满足要求)。
  • 现在迭代列表,并以某种概率将任何元素
    p
    (0,1)与距离您所在位置d处的任何其他元素交换。
    例:d=2
    1234567
    元件5可与3、4、6或7互换
    位置
    i
    的基本元素将与此范围
    [i-d,i+d]
    内的任何元素(也可以随机选择)交换,概率为p
  • 操纵p和s,直到你的“相似性”分数/感觉满意为止

  • 如果您可以将“相似性”的定义更改为排列元素之间交换的数量,那么我们可以使用 Trotter-Johnson置换排序,其中连续置换仅因置换中两个项目的一次交换而不同

    有一些算法将连续整数列与顺序的连续perm关联,还有一些算法可以从列生成perm,反之亦然。使用seed作为秩值,那么两个不同n的seed需要n个交换项才能在各自的perm之间切换

    大量的搜索都提到了这本书:

    D.L.Kreher和D.R.Stinson,《组合算法:生成》, 《查点与检索》,华润出版社,1999年

    我已将其转换为以下Python:

    #-*-编码:utf-8-*-
    """
    创建于2021年6月3日星期四08:44:56
    @作者:Paddy3118
    """
    从输入导入列表开始
    Perm=List[int]
    _事实=[1]#阶乘缓存
    def print_perm(T:perm)->无:
    打印(T)
    def tj_unrank(n:int,r:int)->Perm:
    “返回整数0..n-1的r级Trotter-Johnson置换”
    全球事实
    对于范围内的i(len(_fact),n+2):#必要时扩展阶乘缓存。
    _事实。附加(_事实[i-1]*i)
    pi:Perm=[0]*(n+2)
    pi[1]=1
    r2=0
    对于范围(2,n+1)内的j:
    r1=(r*_事实[j])/_事实[n]
    k=r1-j*r2
    如果((r2%2)==0):
    对于范围内的i(j-1,j-k-1,-1):
    pi[i+1]=pi[i]
    pi[j-k]=j
    其他:
    对于范围(j-1,k,-1)内的i:
    pi[i+1]=pi[i]
    pi[k+1]=j
    r2=r1
    返回[i-1表示pi中的i[1:-1]]
    def tj_秩(n:int,p:Perm)->int:
    返回0..n-1整数的Trotter-Johnson置换p的排序
    断言集(p)==set(range(n)),f“Perm{p}不是0..{n-1}的Perm。”
    pi=[0]+[i+1表示p中的i]+[0]
    r=0
    对于范围(2,n+1)内的j:
    i=k=1
    而pi[i]!=j:
    如果(pi[i]Testing rank/unrank n=4.
    
      Rank:    0 to perm: [0, 1, 2, 3], parity: 0 to rank: 0
      Rank:    1 to perm: [0, 1, 3, 2], parity: 1 to rank: 1
      Rank:    2 to perm: [0, 3, 1, 2], parity: 0 to rank: 2
      Rank:    3 to perm: [3, 0, 1, 2], parity: 1 to rank: 3
      Rank:    4 to perm: [3, 0, 2, 1], parity: 0 to rank: 4
      Rank:    5 to perm: [0, 3, 2, 1], parity: 1 to rank: 5
      Rank:    6 to perm: [0, 2, 3, 1], parity: 0 to rank: 6
      Rank:    7 to perm: [0, 2, 1, 3], parity: 1 to rank: 7
      Rank:    8 to perm: [2, 0, 1, 3], parity: 0 to rank: 8
      Rank:    9 to perm: [2, 0, 3, 1], parity: 1 to rank: 9
      Rank:   10 to perm: [2, 3, 0, 1], parity: 0 to rank: 10
      Rank:   11 to perm: [3, 2, 0, 1], parity: 1 to rank: 11
      Rank:   12 to perm: [3, 2, 1, 0], parity: 0 to rank: 12
      Rank:   13 to perm: [2, 3, 1, 0], parity: 1 to rank: 13
      Rank:   14 to perm: [2, 1, 3, 0], parity: 0 to rank: 14
      Rank:   15 to perm: [2, 1, 0, 3], parity: 1 to rank: 15
      Rank:   16 to perm: [1, 2, 0, 3], parity: 0 to rank: 16
      Rank:   17 to perm: [1, 2, 3, 0], parity: 1 to rank: 17
      Rank:   18 to perm: [1, 3, 2, 0], parity: 0 to rank: 18
      Rank:   19 to perm: [3, 1, 2, 0], parity: 1 to rank: 19
      Rank:   20 to perm: [3, 1, 0, 2], parity: 0 to rank: 20
      Rank:   21 to perm: [1, 3, 0, 2], parity: 1 to rank: 21
      Rank:   22 to perm: [1, 0, 3, 2], parity: 0 to rank: 22
      Rank:   23 to perm: [1, 0, 2, 3], parity: 1 to rank: 23