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!@
Here is how I’m using it:
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
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))
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:
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]]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..
Edit: 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.:
and here’s what I see when I run this self-sufficient script a few times:
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!
Edit: the OP’s code as pasted in pastebin has two bugs that have absolutely nothing to do with
randomand combine to produce the OP’s observed behavior. Here’s the relevant part of the code, redacted: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;-).
Bug 1: since neither
__init__nor any other method ever do an assignmentself.chromosome = ..., all the mentions ofself.chromosomein the code actually refer to the one and only listPhenotype.chromosomewhich all instances of thePhenotypeclass share. So inevitably all such instances will always have exactly the same, identicalchromosome, no matter what. Fix: addself.chromosome = []in__init__(better also to remove the class-level variables because they do no good whatsoever and only confuse the issue).Bug 2: look at the following lines of code again to spot it:
Got it?
self.allelesand the local namealleleSetare all references to exactly the one and the sameallelesset (or list, actually) that’s passed in — so theremovecall 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).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:
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!-)