# 並列化の設定 pool = multiprocessing.Pool() toolbox.register("map", pool.map)
# メイン実行ループ population = toolbox.population(n=300) NGEN = 40 for gen inrange(NGEN): offspring = toolbox.select(population, len(population)) offspring = list(map(toolbox.clone, offspring))
for child1, child2 inzip(offspring[::2], offspring[1::2]): if random.random() < 0.5: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values
for mutant in offspring: if random.random() < 0.2: toolbox.mutate(mutant) del mutant.fitness.values
invalid_ind = [ind for ind in offspring ifnot ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit inzip(invalid_ind, fitnesses): ind.fitness.values = fit
population[:] = offspring
pool.close() pool.join()
best_ind = tools.selBest(population, 1)[0] print(f"Best individual is {best_ind}, {best_ind.fitness.values}")
[実行結果]
Best individual is [-9.982904889626795, 9.853294237890143, -9.986879615364009], (296.4835618255468,)
ソースコード解説
このソースコードは、$DEAP(Distributed Evolutionary Algorithms in Python)$ライブラリを使用して、遺伝的アルゴリズムを実行するプログラムです。
遺伝的アルゴリズムは、生物の進化のプロセスに基づいた最適化手法です。
コードを説明します。
1. ライブラリのインポート
1 2 3
import random import multiprocessing from deap import base, creator, tools, algorithms
defcustom_mutation(individual, indpb): for i inrange(len(individual)): if random.random() < indpb: individual[i] = random.uniform(-10, 10) return individual,
population = toolbox.population(n=300) NGEN = 40 for gen inrange(NGEN): offspring = toolbox.select(population, len(population)) offspring = list(map(toolbox.clone, offspring))
for child1, child2 inzip(offspring[::2], offspring[1::2]): if random.random() < 0.5: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values
for mutant in offspring: if random.random() < 0.2: toolbox.mutate(mutant) del mutant.fitness.values
invalid_ind = [ind for ind in offspring ifnot ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit inzip(invalid_ind, fitnesses): ind.fitness.values = fit
population[:] = offspring
pool.close() pool.join()
初期個体群($300$個体)を生成し、$40$世代にわたって進化させます。
各世代で選択、交叉、突然変異を行い、新しい個体群を生成します。
不正な適応度を持つ個体を評価し、適応度を更新します。
10. 最良の個体の表示
1 2
best_ind = tools.selBest(population, 1)[0] print(f"Best individual is {best_ind}, {best_ind.fitness.values}")
最良の個体を選択し、その個体と適応度を表示します。
このコードは、遺伝的アルゴリズムを使用して3次元ベクトルの最適化を行うプログラムです。
各世代で選択、交叉、突然変異を行い、最適な個体を見つけるために進化を繰り返します。
最終的に、最も適応度の高い個体が表示されます。
結果解説
表示された結果について、説明します。
出力結果
1
Best individual is [-9.982904889626795, 9.853294237890143, -9.986879615364009], (296.4835618255468,)
# 並列化の設定 pool = multiprocessing.Pool() toolbox.register("map", pool.map)
# メイン実行ループ population = toolbox.population(n=300) NGEN = 40 for gen inrange(NGEN): offspring = toolbox.select(population, len(population)) offspring = list(map(toolbox.clone, offspring))
for child1, child2 inzip(offspring[::2], offspring[1::2]): if random.random() < 0.5: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values
for mutant in offspring: if random.random() < 0.2: toolbox.mutate(mutant) del mutant.fitness.values
invalid_ind = [ind for ind in offspring ifnot ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit inzip(invalid_ind, fitnesses): ind.fitness.values = fit
population[:] = offspring
pool.close() pool.join()
best_ind = tools.selBest(population, 1)[0] print(f"Best individual is {best_ind}, {best_ind.fitness.values}")
[実行結果]
Best individual is [917758.6757183365, -36.45732263984088, -2555.157039370527], (842287517012.9069,)
population = toolbox.population(n=300) NGEN = 40 for gen inrange(NGEN): offspring = toolbox.select(population, len(population)) offspring = list(map(toolbox.clone, offspring))
for child1, child2 inzip(offspring[::2], offspring[1::2]): if random.random() < 0.5: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values
for mutant in offspring: if random.random() < 0.2: toolbox.mutate(mutant) del mutant.fitness.values
invalid_ind = [ind for ind in offspring ifnot ind.fitness.valid] fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) for ind, fit inzip(invalid_ind, fitnesses): ind.fitness.values = fit
population[:] = offspring
pool.close() pool.join()
このループでは、$40$世代にわたってGAを実行します。
population = toolbox.population(n=300): 初期集団を生成($300$個体)。
NGEN = 40: 世代数を設定。
各世代で以下の操作を行います:
選択: toolbox.selectで選択された個体をoffspringに保存。
交叉: ランダムに選ばれたペアに対してtoolbox.mateを適用。
変異: ランダムに選ばれた個体に対してtoolbox.mutateを適用。
適応度の再評価: 適応度が無効になった個体の適応度を再評価。
集団の更新: 新しい世代に更新。
8. 最良の個体の選択と表示
1 2
best_ind = tools.selBest(population, 1)[0] print(f"Best individual is {best_ind}, {best_ind.fitness.values}")
最良の個体を選択し、その個体と適応度を表示します。
まとめ
このコードは、DEAPライブラリと並列処理を用いて遺伝的アルゴリズムを実装しています。
GAを使用して、与えられた適応度関数に基づいて最適解を見つけるプロセスが示されています。
並列処理を用いることで、評価関数の計算を効率化しています。
結果解説
[実行結果]
Best individual is [917758.6757183365, -36.45732263984088, -2555.157039370527], (842287517012.9069,)
この結果は、遺伝的アルゴリズム(GA)を用いて最適化された個体(解)が示されています。
ここでは、その個体とその適応度(評価値)を詳しく解説します。
結果の詳細
Best individual: [917758.6757183365, -36.45732263984088, -2555.157039370527]
# メイン実行ループ population = toolbox.population(n=300) NGEN = 40 for gen inrange(NGEN): offspring = toolbox.select(population, len(population)) offspring = list(map(toolbox.clone, offspring))
for child1, child2 inzip(offspring[::2], offspring[1::2]): if random.random() < 0.5: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values
for mutant in offspring: if random.random() < 0.2: toolbox.mutate(mutant) del mutant.fitness.values
invalid_ind = [ind for ind in offspring ifnot ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit inzip(invalid_ind, fitnesses): ind.fitness.values = fit
population[:] = offspring
best_ind = tools.selBest(population, 1)[0] print(f"Best individual is {best_ind}, {best_ind.fitness.values}")
[実行結果]
Best individual is [17379.0603611039, 1705192.5401431422, 2.8390485621127146], (2907983630706.9165,)
ソースコード解説
このコードは、DEAPライブラリを使用して遺伝的アルゴリズムを実装しています。
以下に、詳しく説明します。
1. ライブラリのインポート
1 2
import random from deap import base, creator, tools, algorithms
population = toolbox.population(n=300) NGEN = 40 for gen inrange(NGEN): offspring = toolbox.select(population, len(population)) offspring = list(map(toolbox.clone, offspring))
for child1, child2 inzip(offspring[::2], offspring[1::2]): if random.random() < 0.5: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values
for mutant in offspring: if random.random() < 0.2: toolbox.mutate(mutant) del mutant.fitness.values
invalid_ind = [ind for ind in offspring ifnot ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit inzip(invalid_ind, fitnesses): ind.fitness.values = fit
ax = sns.barplot(x="day", y="total_bill", data=tips) ax.set_title("Total Bill per Day") ax.set_xlabel("Day of the Week") ax.set_ylabel("Total Bill") plt.show()
# 問題の定義 problem = pulp.LpProblem("Production Optimization", pulp.LpMaximize)
# 変数の定義 x = pulp.LpVariable("A", lowBound=0, cat='Continuous') y = pulp.LpVariable("B", lowBound=0, cat='Continuous')
# 目的関数の定義 problem += 40 * x + 30 * y, "Profit"
# 制約条件の定義 problem += 2 * x + y <= 40, "Time Constraint" problem += 3 * x + y <= 30, "Resource Constraint"
# 問題を解く problem.solve()
# 結果の表示 print(f"Status: {pulp.LpStatus[problem.status]}") print(f"Optimal production of A: {x.varValue}") print(f"Optimal production of B: {y.varValue}") print(f"Maximum profit: {pulp.value(problem.objective)}")
出力
このコードを実行すると、最適な生産量と最大利益が表示されます。
1 2 3 4
Status: Optimal Optimal production of A: 0.0 Optimal production of B: 30.0 Maximum profit: 900.0