イタチプログラムを改善する
以前の投稿でイタチプログラムについて投稿した.今回はデモで見せるように、さらに発展系を作成した.具体的には0.5秒の休止期間を設け、文字表示が収斂していく様子を可視化できるようにした。
import random
import time
def mutate(parent, mutation_rate=0.05):
"""指定された突然変異率で文字列を変更する。"""
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
return ''.join(
(char if random.random() > mutation_rate else random.choice(alphabet))
for char in parent
)
def generate_initial_population(size, target):
"""初期集団を生成する関数。"""
return [''.join(random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ ") for _ in range(len(target))) for _ in range(size)]
def calculate_fitness(individual, target):
"""文字列の適合度を計算する関数。"""
return sum(1 for i, char in enumerate(individual) if char == target[i])
###################################
# 1. 通常のWeasel programのコード
###################################
def weasel_program_normal(target="METHINKS IT IS LIKE A WEASEL", mutation_rate=0.05, population_size=100, max_generations=1000):
"""進化の過程をシミュレートするメイン関数。"""
population = generate_initial_population(population_size, target)
best_match = max(population, key=lambda x: calculate_fitness(x, target))
best_fitness = calculate_fitness(best_match, target)
for generation in range(1, max_generations + 1):
# 次世代の集団を生成(最も適合度が高い個体を親として突然変異させる)
population = [mutate(best_match, mutation_rate) for _ in range(population_size)]
best_match = max(population, key=lambda x: calculate_fitness(x, target))
best_fitness = calculate_fitness(best_match, target)
# 結果表示
print(f"Generation {generation}: {best_match} (Fitness: {best_fitness})")
# 成否表示
if best_fitness == len(target):
print("Success")
break
else:
print("Failed")
# 0.5秒の待機
time.sleep(0.5)
return best_match
# 実行
weasel_program_normal()