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
。然后,每次使用seeds
调用生成器时:
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如果您可以将“相似性”的定义更改为排列元素之间交换的数量,那么我们可以使用 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