Created
January 5, 2011 22:01
-
-
Save maxcountryman/767102 to your computer and use it in GitHub Desktop.
A weasel program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random, string, time | |
TEST = False | |
def timeit(func, *args): | |
'''Simple timeit wrapper for functions.''' | |
start = time.time() | |
func(*args) | |
elapsed = time.time() - start | |
return elapsed | |
def test(goal=10000): | |
'''Run the Generations simulation goal number of times, find the average | |
iterations for the solution. | |
''' | |
k = 0 | |
l = [] | |
while k < goal: | |
test = Generation('CARBON', offspring=100, rate=5) | |
l.append(test.i) | |
k += 1 | |
print('Average: ' + str(float(sum(l)) / len(l))) | |
class Generation(object): | |
'''Mutates a seed through sucessive generations, producing n number of | |
offspring, of those the best match is choosen to seed the next | |
generation until the target string is matched exactly. Rate specifies | |
the how much mutation will occur, as a percentage; too much and it will | |
take a very very long time for the target to be met. | |
''' | |
def __init__(self, target=None, offspring=100, rate=5): | |
self.target = target | |
self.offspring = offspring | |
self.rate = self.offspring * (rate / 100.0) | |
self._chars = string.uppercase + ' ' | |
self.i = 0 | |
i, seed = 0, '' | |
while seed != target: | |
mutations = self._generate_seeds() if (i == 0) else self._iter_mutations(seed) | |
seed, score = self._closest_match(mutations) | |
print('{0}: {1} -- score: {2}'.format(i, seed, score)) | |
i += 1 | |
self.i = i | |
def _generate_seeds(self): | |
seed = lambda chars : ''.join([a for a in [random.choice(chars) for x in xrange(len(self.target))]]) | |
seeds = [seed(self._chars) for i in xrange(self.offspring)] | |
return seeds | |
def _closest_match(self, seeds): | |
'''Takes a set of seeds and looks for matches to the target, produces a | |
score and identifies the winner based on the highest score. | |
''' | |
pts = [] | |
for s in seeds: | |
i = 0 | |
for j, c in enumerate(s): | |
if c == self.target[j]: | |
i += 1 | |
pts.append(i) | |
score = max(pts) | |
winner = seeds[pts.index(score)] | |
return winner, score | |
def _mutate(self, seed): | |
'''Mutate a seed.''' | |
k = '' | |
for a in seed: | |
n = a | |
if self.rate >= random.randrange(0, self.offspring): | |
n = random.choice(self._chars) | |
k += n | |
return k | |
def _iter_mutations(self, seed): | |
'''Iterate through mutations.''' | |
mutations = [self._mutate(seed) for i in range(self.offspring)] | |
return mutations | |
if __name__ == '__main__': | |
if TEST: | |
secs = timeit(test) | |
print('Time taken: {:.2f} secs'.format(secs)) | |
else: | |
Generation('METHINKS IT IS LIKE A WEASEL') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment