问题描述
我正在使用python的random.sample(population,k)函数从列表中生成一组随机值,以创建该列表的新排列.问题在于,每次循环运行时,都会生成完全相同随机序列.为什么是这样?我什至使用random.seed(i),以便i变量(每次在循环中进行更改)每次都将不同的值作为种子.仍然是相同的顺序.有什么用!@
I'm using python's random.sample(population, k) function to generate a set of random values from a list to create new permutations of that list. The issue is that each time it runs through a loop, it's generating the exact same random sequence. Why is this? I even used random.seed(i) so that the i variable (changing each time through the loop) would seed it a different value each time. Still the same sequence. What gives!@
这是我的使用方式:
def initialBuild(self):
alphabet = self.alphabet
for i in range (self.length):
value = random.sample(alphabet, 1)
alphabet.remove(value[0])
self.finalWord.append(value[0])
print "Final word = ", self.finalWord
只是从Individual类的init方法中调用的.像这样调用init方法...
which is just being called from the init method of an Individual class. The init method is being called like so...
def buildPopulation(self, alphabet):
#Initialize empty individuals
for i in range(POPULATION_SIZE):
self.population.append(Individual(alphabet))
和init方法看起来像这样...
and the init method looks like this...
def __init__(self, alphabet = []):
self.length = len(alphabet)
self.alphabet = alphabet
self.initialBuild()
最后,我要印最后一个字.这是两次运行此方法的输出:
At the end, I'm printing a final word. Here is the output of running this method twice:
最终字= [[1150,1160],[720,635],[95、260],[595、360],[770,610],[830、610],[25、185],[520,585],[605、625],[410、250],[555,815],[880、660],[300、465],[1220,580],[1215、245],[1250、400],[565,575],[1605、620],[845、680],[1170,65],[795、645],[525、1000],[760,650],[580、1175],[420、555],[25,230],[345、750],[700、500],[725,370],[1530、5],[1740、245],[875,920],[415、635],[1340、725],[975,580],[575、665],[1465、200],[830,485],[660、180],[475、960],[685,595],[145、665],[510、875],[845,655],[650、1130],[945、685],[480,415],[700、580],[560、365],[685,610],[835、625],[1320、315]]
Final Word = [[1150, 1160], [720,635], [95, 260], [595, 360], [770,610], [830, 610], [25, 185], [520,585], [605, 625], [410, 250], [555,815], [880, 660], [300, 465], [1220,580], [1215, 245], [1250, 400], [565,575], [1605, 620], [845, 680], [1170,65], [795, 645], [525, 1000], [760,650], [580, 1175], [420, 555], [25,230], [345, 750], [700, 500], [725,370], [1530, 5], [1740, 245], [875,920], [415, 635], [1340, 725], [975,580], [575, 665], [1465, 200], [830,485], [660, 180], [475, 960], [685,595], [145, 665], [510, 875], [845,655], [650, 1130], [945, 685], [480,415], [700, 580], [560, 365], [685,610], [835, 625], [1320, 315]]
请注意,这两个是绝对相同的.
Notice that these two are absolutely identical..
编辑:由于我很难挑选出我认为将很有用的代码,但篇幅短短不足以撰写本文,因此我将大量代码发布到了pastebin上. http://pastebin.com/f5f068391 这是一个更好的选择..再次感谢
Since I'm having a hard time picking out code that I think will be useful, yet short enough to go into this post, I've posted a bunch of it on pastebin. http://pastebin.com/f5f068391 This is hopefully a better alternative.. Thanks again
推荐答案
我不确定生成完全相同随机序列"是什么意思.由于您只给了我们一个不能单独运行的代码段,因此很可能在您选择不向我们展示的代码的其他部分中存在错误-我已经尝试添加绝对少量的代码需要使您的代码段运行,即:
I'm not sure what you mean by "generating the exact same random sequence". Since you only give us a snippet that can't be run on its own, it's quite possible that there are bugs in other parts of your code that you choose not to show us -- I've tried adding the absolutely minimal amount of code needed to make your snippet run, i.e.:
import random
import string
def self(): pass
self.alphabet = list(string.lowercase)
self.finalWord = []
self.length = 4
for x in range(5):
alphabet = self.alphabet
for i in range (self.length):
value = random.sample(alphabet, 1)
alphabet.remove(value[0])
self.finalWord.append(value[0])
print "Final word = ", self.finalWord
这是我几次运行此自足脚本的结果:
and here's what I see when I run this self-sufficient script a few times:
$ python sa.py
Final word = ['y', 'm', 'u', 'z']
Final word = ['y', 'm', 'u', 'z', 'h', 'b', 'c', 's']
Final word = ['y', 'm', 'u', 'z', 'h', 'b', 'c', 's', 'x', 'l', 'r', 'n']
Final word = ['y', 'm', 'u', 'z', 'h', 'b', 'c', 's', 'x', 'l', 'r', 'n', 'q', 'a', 'k', 'e']
Final word = ['y', 'm', 'u', 'z', 'h', 'b', 'c', 's', 'x', 'l', 'r', 'n', 'q', 'a', 'k', 'e', 'p', 'd', 'j', 'w']
$ python sa.py
Final word = ['k', 'v', 'o', 'd']
Final word = ['k', 'v', 'o', 'd', 'q', 'p', 'w', 'l']
Final word = ['k', 'v', 'o', 'd', 'q', 'p', 'w', 'l', 'n', 'u', 'g', 't']
Final word = ['k', 'v', 'o', 'd', 'q', 'p', 'w', 'l', 'n', 'u', 'g', 't', 'i', 'r', 'e', 'f']
Final word = ['k', 'v', 'o', 'd', 'q', 'p', 'w', 'l', 'n', 'u', 'g', 't', 'i', 'r', 'e', 'f', 's', 'c', 'j', 'z']
$ python sa.py
Final word = ['o', 'a', 'g', 't']
Final word = ['o', 'a', 'g', 't', 'k', 'j', 'y', 'w']
Final word = ['o', 'a', 'g', 't', 'k', 'j', 'y', 'w', 'z', 'l', 'i', 's']
Final word = ['o', 'a', 'g', 't', 'k', 'j', 'y', 'w', 'z', 'l', 'i', 's', 'u', 'p', 'f', 'm']
Final word = ['o', 'a', 'g', 't', 'k', 'j', 'y', 'w', 'z', 'l', 'i', 's', 'u', 'p', 'f', 'm', 'h', 'e', 'q', 'v']
如您所见,但就是完全相同的随机序列"-它正按预期改变每次运行.
As you see, that's anything but "the exact same random sequence" -- it's changing each and every run, just as expected.
我想我在尝试使您的代码可执行时读错了您的想法,这意味着您使用它的方式与我的小脚本使用它的方式非常不同-但是,念书是一种不可靠的艺术(为什么您发布一个独立的,可运行的示例会变得更好呢,这个示例即使在重现您的问题时又尽可能地小,而不是强迫我们尝试去读懂您的想法!- ).
I imagine I've read your mind incorrectly when trying to make your code executable, and that you mean it to be used very differently than my tiny script uses it -- but then mind-reading is an unreliable art (which is why it would be so much better if you posted a self-contained, runnable example, made as tiny as it can be while still reproducing your problem, rather than forcing us to try and read your mind!-).
为什么不调整我刚刚发布的独立脚本所需的最小数量,以使其更接近您的预期用途并重现您观察到的问题? 然后,对于我们来说,发现您的代码可能存在的任何问题并提出修复它的最佳方法将变得更加容易,而且效率更高!
Why don't you tweak the stand-alone script I've just posted by the minimal needed amount to make it closer to your intended use, and to reproduce the problem you observe? Then it will be so much easier and more productive for us to spot any issue your code may have and suggest the best way to fix it!
编辑:粘贴到pastebin中的OP代码有两个与random
完全无关的错误,它们组合在一起产生了OP的观察到的行为.这是已编辑的代码的相关部分:
Edit: the OP's code as pasted in pastebin has two bugs that have absolutely nothing to do with random
and combine to produce the OP's observed behavior. Here's the relevant part of the code, redacted:
class Phenotype:
...
chromosome = []
def __init__(self, alleles = []):
self.length = len(alleles)
self.alleles = alleles
self.initialBuild()
def initialBuild(self):
alleleSet = self.alleles
for i in range (self.length):
value = random.sample(alleleSet, 1)
alleleSet.remove(value[0])
self.chromosome.append(value[0])
好的,这里还有另一个错误(在新代码中使用旧的,遗留的类,而不是应始终使用的闪亮的新样式类),但这并不是对OP的困扰(尚未),因此我们只在提及它顺带一提;-).
OK, there's another bug here (using old, legacy classes in new code, instead of shiny new style classes which should always be used), but that's not what's biting the OP (yet), so we'll just mention it in passing;-).
错误1:由于__init__
或任何其他方法均未进行赋值self.chromosome = ...
,因此代码中对self.chromosome
的所有提及实际上都是指一个唯一列表Phenotype.chromosome
,其中Phenotype.chromosome
的所有实例c5>班级份额.因此,不可避免地所有这样的实例将始终具有完全相同,完全相同的chromosome
,无论如何.修复:在__init__
中添加self.chromosome = []
(最好也删除类级变量,因为它们没有任何用处,只会混淆问题).
Bug 1: since neither __init__
nor any other method ever do an assignment self.chromosome = ...
, all the mentions of self.chromosome
in the code actually refer to the one and only list Phenotype.chromosome
which all instances of the Phenotype
class share. So inevitably all such instances will always have exactly the same, identical chromosome
, no matter what. Fix: add self.chromosome = []
in __init__
(better also to remove the class-level variables because they do no good whatsoever and only confuse the issue).
错误2:再次查看以下代码行以发现它:
Bug 2: look at the following lines of code again to spot it:
self.alleles = alleles
...
alleleSet = self.alleles
...
alleleSet.remove(value[0])
知道了吗? self.alleles
和本地名称alleleSet
都是对恰好的引用,它们完全是传入的一个和相同的alleles
集(或列表),因此remove
调用i 更改.因此,实例化了第一个表型后,该集合就被留空了(这就是为什么尽管有Bug 1,染色体仍不能保持增长的原因:等位基因集合永远留空了).
Got it? self.alleles
and the local name alleleSet
are all references to exactly the one and the same alleles
set (or list, actually) that's passed in -- so the remove
call i altering the collection that's passed in. So that collection's left empty after the very first Phenotype is instantiated (which is why despite Bug 1 the chromosome doesn't keep growing: because the alleles collection is left empty forevermore).
修复:进行复印,例如alleleSet = list(self.alleles)
,以避免损坏原始集合.
Fix: make a copy, e.g. alleleSet = list(self.alleles)
, to avoid damaging the original collection.
更好的解决方案:您正在做的是一种极其复杂的方法,可以拼写更简单的代码,例如:
Better fix: what you're doing is an extremely convoluted way to spell much simpler code such as:
self.chromosome = list(self.alleles)
random.shuffle(self.chromosome)
,即,获得随机排列.通过处理N个单独的样本并在集合产生时将其从集合中删除来构建随机排列,是一种解决极其简单的问题的真正的环回,缓慢且复杂的方法!-)
i.e., just get a random permutation. Building a random permutation by doing N separate samples and removing each sample from the collection as it's generated is a really round-about, slow and complicated way to attack an extremely simple problem!-)
这篇关于random.sample()每次都返回相同的随机序列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!