Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 30 additions & 11 deletions evolve_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,32 @@ def get_text(self):
# TODO: Implement levenshtein_distance function (see Day 9 in-class exercises)
# HINT: Now would be a great time to implement memoization if you haven't

def levenshtein_distance(message, goal_text, dicts = {}):
"""Computes the levenshtein distance between two input strings by memoizing with d, an empty dictionary"""
if (message, goal_text) in dicts.keys():
return dicts[message, goal_text]
else:
if len(message)== 0:
return len(goal_text)
elif len(goal_text) ==0:
return len(message)
elif message[0] == goal_text[0]:
option1 = levenshtein_distance(message[1:], goal_text[1:], dicts)
else:
option1 = 1 + levenshtein_distance(message[1:], goal_text[1:], dicts)
option2 = 1 + levenshtein_distance(message[1:], goal_text, dicts)
option3 = 1 + levenshtein_distance(message, goal_text[1:], dicts)
minimum = min(option1, option2, option3)
dicts[message, goal_text] = minimum
return minimum

def evaluate_text(message, goal_text, verbose=VERBOSE):
"""
Given a Message and a goal_text string, return the Levenshtein distance
between the Message and the goal_text as a length 1 tuple.
If verbose is True, print each Message as it is evaluated.
"""
dicts = {}
distance = levenshtein_distance(message.get_text(), goal_text)
if verbose:
print "{msg:60}\t[Distance: {dst}]".format(msg=message, dst=distance)
Expand All @@ -119,19 +139,16 @@ def mutate_text(message, prob_ins=0.05, prob_del=0.05, prob_sub=0.05):
Substitution: Replace one character of the Message with a random
(legal) character
"""

if random.random() < prob_ins:
# TODO: Implement insertion-type mutation
pass

# TODO: Also implement deletion and substitution mutations
# HINT: Message objects inherit from list, so they also inherit
# useful list methods
# HINT: You probably want to use the VALID_CHARS global variable
message.append(random.choice(VALID_CHARS))
if random.random() < prob_del:
message = message[0:]
if random.random() < prob_sub:
i = random.randint(0, len(message))
message[i] = random.choice(VALID_CHARS)

return (message, ) # Length 1 tuple, required by DEAP


#-----------------------------------------------------------------------------
# DEAP Toolbox and Algorithm setup
#-----------------------------------------------------------------------------
Expand Down Expand Up @@ -181,8 +198,10 @@ def evolve_string(text):

# Run simple EA
# (See: http://deap.gel.ulaval.ca/doc/dev/api/algo.html for details)
pop, log = algorithms.eaSimple(pop,
pop, log = algorithms.eaMuPlusLambda(pop,
toolbox,
mu = 5,
lambda_ = 5,
cxpb=0.5, # Prob. of crossover (mating)
mutpb=0.2, # Probability of mutation
ngen=500, # Num. of generations to run
Expand Down Expand Up @@ -215,4 +234,4 @@ def evolve_string(text):
raise ValueError(msg.format(goal=goal, char=char, val=VALID_CHARS))

# Run evolutionary algorithm
pop, log = evolve_string(goal)
pop, log = evolve_string(goal)
26 changes: 26 additions & 0 deletions results.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
###Experimentation Results for ToolBox-EvolutionaryAlgorithms
###Claire Kincaid
###April 14, 2016

I chose to change the DEAP evolutionary algorithm the code uses from eaSimple to eaMuPlusLambda to examine how it affects the run time and the generation results of the evolutionary algorithm software.

RESULTS
- it still takes forever to run
- after lots of debugging I discovered that the levenshtein distance function was just recursive forever so it never stopped running, invalidating the change made by the use of eaMuPlusLambda
- now it's running great
- it starts running very quickly and slows down after a bit of time
- lets see how many generations it takes, I think we're on 50 right now
- btw the message code here is "THIS IS MY EXPERIMENT"
- mu is set to 5
- lambda_ is set to 5
- its getting closish
- levenshtein distance started at around 22 average now its down to 17
- this still takes forever but is much more efficient than eaSimple for long message codes
- this is taking forever--- I'm going to do a smaller message and that should take less time (?)
- smaller message = EVOLUTION
- already going much faster
- it's slowed down but has an average levenshtein of about 12
- bogged down around randint, had to debug
- rerunning at message = EVOLUTION
- its pretty efficient but still running fairly slow-- I think it's that my lambda_ is too high, I should add fewer new instances each time and keep more of the optemized ones
- took about 200 generations to get it, but I didn't have them officially count it so I don't know for sure