Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a2dbf95

Browse files
committed
Some genetic_search() fixes: states were lists but had .mutate() called on them; pmut was probability of *not* mutating; initial population nonrandom; bad fitness function.
1 parent 89cba73 commit a2dbf95

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

search.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -287,34 +287,42 @@ def lrta_star_agent(a):
287287
#______________________________________________________________________________
288288
# Genetic Algorithm
289289

290-
def genetic_search(problem, fitness_fn, ngen=1000, pmut=0.0, n=20):
290+
def genetic_search(problem, fitness_fn, ngen=1000, pmut=0.1, n=20):
291291
"""Call genetic_algorithm on the appropriate parts of a problem.
292-
This requires that the problem has a successor function that generates
293-
reasonable states, and that it has a path_cost function that scores states.
294-
We use the negative of the path_cost function, because costs are to be
295-
minimized, while genetic-algorithm expects a fitness_fn to be maximized."""
296-
states = [s for (a, s) in problem.successor(problem.initial_state)[:n]]
292+
This requires that the problem has a successor function that
293+
generates states that can mate and mutate, and that it has a value
294+
method that scores states."""
295+
states = [s for (a, s) in problem.successor(problem.initial_state)]
297296
random.shuffle(states)
298-
fitness_fn = lambda s: - problem.path_cost(0, s, None, s)
299-
return genetic_algorithm(states, fitness_fn, ngen, pmut)
297+
return genetic_algorithm(states[:n], problem.value, ngen, pmut)
300298

301-
def genetic_algorithm(population, fitness_fn, ngen=1000, pmut=0.0):
299+
def genetic_algorithm(population, fitness_fn, ngen=1000, pmut=0.1):
302300
"""[Fig. 4.7]"""
303-
def reproduce(p1, p2):
304-
c = random.randrange(len(p1))
305-
return p1[:c] + p2[c:]
306-
307301
for i in range(ngen):
308302
new_population = []
309303
for i in len(population):
310304
p1, p2 = random_weighted_selections(population, 2, fitness_fn)
311-
child = reproduce(p1, p2)
312-
if random.uniform(0,1) > pmut:
305+
child = p1.mate(p2)
306+
if random.uniform(0, 1) < pmut:
313307
child.mutate()
314308
new_population.append(child)
315309
population = new_population
316310
return argmax(population, fitness_fn)
317311

312+
class GAState:
313+
"Abstract class for individuals in a genetic algorithm."
314+
def __init__(self, genes):
315+
self.genes = genes
316+
317+
def mate(self, other):
318+
"Return a new individual crossing self and other."
319+
c = random.randrange(len(self.genes))
320+
return self.__class__(self.genes[:c] + other.genes[c:])
321+
322+
def mutate(self):
323+
"Change a few of my genes."
324+
abstract
325+
318326
def random_weighted_selection(seq, n, weight_fn):
319327
"""Pick n elements of seq, weighted according to weight_fn.
320328
That is, apply weight_fn to each element of seq, add up the total.

0 commit comments

Comments
 (0)