Skip to content

Instantly share code, notes, and snippets.

@maxcountryman
Created January 5, 2011 22:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxcountryman/767102 to your computer and use it in GitHub Desktop.
Save maxcountryman/767102 to your computer and use it in GitHub Desktop.
A weasel program
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