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

Skip to content

Commit dafac5b

Browse files
committed
Moved random_weighted_selection to utils and rewrote it using bisect.
1 parent 50e8f0f commit dafac5b

File tree

2 files changed

+25
-23
lines changed

2 files changed

+25
-23
lines changed

search.py

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,8 @@ def genetic_algorithm(population, fitness_fn, ngen=1000, pmut=0.1):
367367
for i in range(ngen):
368368
new_population = []
369369
for i in len(population):
370-
p1, p2 = random_weighted_selections(population, 2, fitness_fn)
370+
fitnesses = map(fitness_fn, population)
371+
p1, p2 = weighted_sample_with_replacement(population, fitnesses, 2)
371372
child = p1.mate(p2)
372373
if random.uniform(0, 1) < pmut:
373374
child.mutate()
@@ -389,25 +390,6 @@ def mutate(self):
389390
"Change a few of my genes."
390391
abstract
391392

392-
def random_weighted_selection(seq, n, weight_fn):
393-
"""Pick n elements of seq, weighted according to weight_fn.
394-
That is, apply weight_fn to each element of seq, add up the total.
395-
Then choose an element e with probability weight[e]/total.
396-
Repeat n times, with replacement. """
397-
totals = []; runningtotal = 0
398-
for item in seq:
399-
runningtotal += weight_fn(item)
400-
totals.append(runningtotal)
401-
selections = []
402-
for s in range(n):
403-
r = random.uniform(0, totals[-1])
404-
for i in range(len(seq)):
405-
if totals[i] > r:
406-
selections.append(seq[i])
407-
break
408-
return selections
409-
410-
411393
#_____________________________________________________________________________
412394
# The remainder of this file implements examples for the search algorithms.
413395

@@ -885,7 +867,4 @@ def compare_graph_searchers():
885867
886868
>>> boggle_hill_climbing(list('ABCDEFGHI'), verbose=False)
887869
(['E', 'P', 'R', 'D', 'O', 'A', 'G', 'S', 'T'], 123)
888-
889-
>>> random_weighted_selection(range(10), 3, lambda x: x * x)
890-
[8, 9, 6]
891870
""")

utils.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,18 @@ def probability(p):
501501
"Return true with probability p."
502502
return p > random.uniform(0.0, 1.0)
503503

504+
def weighted_sample_with_replacement(seq, weights, n):
505+
"""Pick n samples from seq at random, with replacement, with the
506+
probability of each element in proportion to its corresponding
507+
weight."""
508+
totals = []
509+
for w in weights:
510+
totals.append(w + totals[-1] if totals else w)
511+
def sample():
512+
r = random.uniform(0, totals[-1])
513+
return seq[bisect.bisect(totals, r)]
514+
return [sample() for s in range(n)]
515+
504516
def num_or_str(x):
505517
"""The argument is a string; convert to a number if possible, or strip it.
506518
>>> num_or_str('42')
@@ -939,4 +951,15 @@ def fixup(test):
939951
>>> sl(a)
940952
['a', 'b', 'c', 'd', 'r', 'w', 'y', 'z']
941953
954+
>>> weighted_sample_with_replacement([], [], 0)
955+
[]
956+
>>> weighted_sample_with_replacement('a', [3], 2)
957+
['a', 'a']
958+
>>> weighted_sample_with_replacement('ab', [0, 3], 3)
959+
['b', 'b', 'b']
942960
"""
961+
962+
__doc__ += random_tests("""
963+
>>> weighted_sample_with_replacement(range(10), [x*x for x in range(10)], 3)
964+
[8, 9, 6]
965+
""")

0 commit comments

Comments
 (0)