تحياتي للجميع
لمن يحب التجريب، برنامج بلغة ال Python من يحاكي موقع ريتشارد دوكينز:
http://www.cbs.dtu.dk/courses/27615....asel/weasel.py
# Python implementation of Richard Dawkin's weasel program
# Illustrates power of cumulative selection vs entirely random search
# This version allows all positions to mutate in any generation, meaning correct letters can be reversed
# Initializations
import sys, random
target = list("METHINKS IT IS LIKE A WEASEL") # Target sequence
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ " # Alphabet of possible symbols (uppercase letters + blank)
n_offspring = 50 # Number of offspring per generation
mut_rate = 0.08 # Mutation rate: probability that any given letter will change
best_offspring = [] # Variable containing best offspring after each generation
# Contains empty list when loop is first entered
# Construct random starting string of same length as target
parent = []
for i in range(len(target)):
parent.append(random.choice(alphabet))
# Main loop: construct mutated offspring, select best for next generation, stop when target reached
gen = 0
while best_offspring != target:
gen = gen + 1
# Keep track of the number of good, bad, and neutral mutations arising in this generation
n_beneficial = n_detrimental = n_neutral = num_mut = 0.0
# Keep track of how many kids in current generation that look exactly like their parent
num_unchanged = n_offspring
# Construct n_offspring children that may contain mutations
kid_list = []
for i in range(n_offspring):
# Copy content of parent to kid
kid = parent[:]
# Iterate over positions in kid, for each position allow possibility of mutating
kid_changed = False
for pos in range(len(kid)):
# Let residue mutate with probability mut_rate
if random.random() < mut_rate:
kid_changed = True
num_mut += 1
# Randomly select new symbol (that is different from the one already present)
old_symbol = parent[pos]
possible_new_symbols = set(alphabet) - set(old_symbol)
new_symbol = random.choice(list(possible_new_symbols))
# Mutate kid
kid[pos] = new_symbol
# Check if mutation was beneficial, detrimental, or neutral and update count
if old_symbol == target[pos]: # Correct letter has been changed: detrimental
n_detrimental += 1
elif new_symbol == target[pos]: # Incorrect letter has been changed to correct: beneficial
n_beneficial += 1
else: # Incorrect letter has been changed to other incorrect letter: neutral
n_neutral += 1
# If kid was mutated, then it no longer looks like its parent
if kid_changed:
num_unchanged -= 1
# Add (possibly) mutated kid to list of current kids
kid_list.append(kid)
# Find most fit offspring (= string most similar to target)
smallest_dif = len(target) + 1
for kid in kid_list:
# Find number of positions that differ between kid and target
dif = 0.0
for pos in range(len(target)):
if kid[pos] != target[pos]:
dif = dif + 1
# Keep best kid found so far
if dif < smallest_dif:
smallest_dif = dif
best_offspring = kid
# Use best offspring as starting point for next round of mutation
parent = best_offspring
# Print progress
fitness = (len(target)-smallest_dif)/len(target) # Fitness of most fit individual
ben_frac = n_beneficial/num_mut
detr_frac = n_detrimental/num_mut
neu_frac = n_neutral/num_mut
result_string = ""
for pos in range(len(target)):
if best_offspring[pos] == target[pos]:
result_string += best_offspring[pos]
else:
result_string += best_offspring[pos].lower()
print "%s ** Gen: %4d Dif: %3d Fit: %.4f Bene: %.4f Detr: %.4f Neu: %.4f Unchanged: %3d" % (result_string,
gen, smallest_dif, fitness,
ben_frac, detr_frac, neu_frac,
num_unchanged)