随机.shuffle 随机性

5

我正在尝试编写一个遗传算法来解决旅行商问题的作业

我正在尝试的变异函数之一是对巡回旅游路线使用random.shuffle

当我阅读random.shuffle的文档时,看到:

shuffle(self, x, random=None, int=<type 'int'>) method of random.Random instance
x, random=random.random -> shuffle list x in place; return None.

Optional arg random is a 0-argument function returning a random
float in [0.0, 1.0); by default, the standard random.random.

请问这个函数中的“random”参数有什么作用?我已经看了这篇问题,但并没有回答我的问题。

如果可能的话,我特别想使用这个函数来控制洗牌的随机程度(如果这样说有意义的话)。


你能更详细解释一下“如果我可以以某种方式控制洗牌的随机程度,我特别想使用这个函数”吗?你只是希望它更加完美地随机吗?为什么? - KobeJohn
我的意思是“我想控制洗牌后的列表与原始列表相比有多大不同”。我想差异可以通过列表中不同对应条目的数量来衡量。说实话,我不是100%确定,因为这是我比较新的东西。 - inspectorG4dget
我明白了。看起来你想要计算原始数据和新数据之间的“距离”。你想要最大化这个距离吗?当然,如果你这样做,它就不会很随机了。如果距离是你真正的目标,也许你需要改变问题或者提出一个新问题。我已经更新了我的答案,指向距离计算。 - KobeJohn
3个回答

4
random参数用于指定(另一个)随机数生成器,它是一个函数,期望返回范围在0<=x<1之间的均匀随机数。
如果从随机数生成器中两次返回相同的数字,则洗牌(shuffle)将是相同的。例如,
def mynonrandom():
 return 0.1

q
[1, 2, 3, 4]
random.shuffle(q, mynonrandom)
q
[2, 3, 4, 1]
random.shuffle(q, mynonrandom)
q
[3, 4, 1, 2]

请注意,在这种特殊情况下,每次我都得到了一个-1的偏移量。对于随机输入,你得到的结果可能取决于random.shuffle的实现方式。
对于遗传算法,你希望能够具有可变大小的洗牌随机性。这不能通过random.shuffle来实现。你可能需要定义一些示例更改(例如距离N交换的对),然后随机化(使用你定义的一些参数)对每组新基因执行多少次这些操作。

1
Python算法从最后开始运作... 选择从0到n-1的一个随机索引与单元格n-1进行交换,然后选择从0到n-2与n-2进行交换.... Johan的例子总是与第一个单元格进行交换,因此发生了位移。如果“mynonrandom”返回0.75或更高,则始终与当前单元格进行交换,不会改变任何东西。 - Chris Nash

1

正如Johan所说,随机参数只是提供用于洗牌函数的随机性。因此,您可以使用默认值或提供自己的值。如果您想使其更完美地随机,您可以去查找比Python更好的库。

根据您对我的评论的回复,听起来您正在寻找距离而不是随机性。您可能希望进行一组n个随机洗牌并最大化距离。要计算距离,您可以使用像这样的一些技术, 我没有寻找它们的实现,但肯定存在。


不,你还没有。正如我在回复你的评论中所说的:“我的意思是‘我想控制洗牌后的列表与原始列表相比有多大的不同’”。我想差异可以通过列表中不同对应条目的数量来衡量。老实说,我不是100%确定,因为这是我比较新的东西。 - inspectorG4dget

1

shuffle 库例程允许您提供随机数源(如果没有,它将使用内置默认值)。因此,理论上,如果您有更好的随机数源 - 也许是连接到盖革计数器或“白噪声”广播电台的东西,或者从 random.org 获取数字的东西 - 您可以使用它来代替。如果您正在进行测试,则可能更有用的是,您可以连接返回相同数字序列的源,这将确保您的测试用例可重复,并且每次都生成相同的洗牌。

理论上,您可以开发一个随机数例程,以便完全控制洗牌的混合程度;但这意味着您需要确切地了解shuffle的工作原理以及您需要返回哪些数字来“指导”结果到达目标位置。理论上...这并不太困难,使用的算法非常好文档化(Fisher-Yates),在调用期间生成n-1个随机数,第一个从索引0到n-1选择一个元素,与最后一个元素交换,第二个从0到索引n-2选择一个元素,与倒数第二个元素交换,以此类推。所以是的,您可以使用它来控制洗牌,就像@JohanLundberg的示例一样,它强制洗牌进行移位-但是很难使用它来控制洗牌(因为每次迭代,所有原始数据都在跳动)。

简而言之,如果您需要对洗牌施加特定的约束条件,例如“仅交换相邻元素”-最好实现自己的算法,可能使用洗牌源代码作为指南。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接