random.shuffle 随机性
我正在写一个遗传算法来解决作业中的旅行商问题。
我尝试的一个变异函数是对旅行路线使用 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”参数是干什么用的吗?我看过这个问题,但它没有回答我的疑问。
我特别想使用这个函数,如果我能以某种方式控制洗牌的随机程度的话(如果这样说有意义的话)。
3 个回答
正如Johan所说,random参数只是给shuffle函数提供随机性的。你可以使用默认的设置,也可以自己提供一个。如果你想要更完美的随机性,可以去找一个比Python自带的更好的库。
根据你对我评论的回复,听起来你其实是在寻找距离,而不是随机性。你可能想要进行n次随机洗牌,然后最大化这些洗牌之间的距离。要计算距离,你可以使用一些这样的技术,虽然我没有查找过具体的实现,但肯定是有的。
这个 shuffle
库的功能让你可以提供一个随机数的来源(如果你不提供,它会使用默认的随机数)。所以,理论上来说,如果你有一个更好的随机数来源,比如连接到盖革计数器的设备,或者是一个播放“白噪音”的电台,或者从 random.org 获取数字的工具,你都可以用这些来替代默认的随机数。更有用的是,如果你在测试中,可以连接一个返回相同数字序列的来源,这样可以确保你的测试用例是可重复的,每次都能生成相同的洗牌结果。
理论上,你可以开发一个随机数的程序,让你精确控制洗牌的程度;但这就需要你完全了解 shuffle
是怎么工作的,以及你需要返回什么样的数字来“引导”结果达到你想要的方向。理论上来说,这并不太难,因为使用的算法(Fisher-Yates)文档写得很清楚。在调用时,它会生成 n-1
个随机数,第一个随机数用来选择从 0 到 n-1 的一个元素,与最后一个元素交换,第二个随机数选择从 0 到 n-2 的一个元素,与倒数第二个元素交换,依此类推。所以,是的,你可以用这个来控制洗牌,就像 @JohanLundberg 的例子那样强制洗牌移动——但要用这个来“控制”洗牌会很困难,因为每次迭代时,所有原始数据都在跳动。
简单来说,如果你需要对洗牌有特定的限制,比如“只交换相邻的元素”,那么你最好自己实现一个,或许可以参考洗牌的源代码作为指导。
random
这个参数是用来指定一个(另外的)随机数生成器的。它是一个函数,期望返回在0到1之间均匀分布的随机数。
如果随机数生成器两次返回了相同的数字,那么洗牌的结果就会是一样的。例如,
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的两个元素交换),然后随机化(使用你定义的一些参数)每次对新基因集执行多少次这些操作。