一、遺傳演算法簡介
遺傳演算法(Genetic Algorithm)是優化問題中的一種進化演算法。這種演算法源於生物學中進化理論的基本思想,通過模擬生物的進化過程來解決問題。遺傳演算法具有非常廣泛的適用範圍,在機器學習、數據挖掘、優化等領域都有廣泛的應用。
遺傳演算法的核心思想是通過模擬自然界中的進化過程,進行優化的求解過程。具體來說,遺傳演算法首先需要設定一個初始種群,然後通過選擇、交叉、變異等操作,對種群不斷進行迭代和進化,最終得到最優解。
二、遺傳演算法的基本流程
遺傳演算法的基本流程如下:
- 初始化:創建一個種群,其中每一個個體對應一個問題的解。
- 評估:對每個個體進行評估,得到該個體對應問題的解的適應度。
- 選擇:根據適應度對種群進行選擇,選擇前若干個個體作為下一步的父代。
- 交叉:對父代進行交叉,生成下一代個體。
- 變異:對下一代進行變異,引入新的基因。
- 替換:用新的個體替換原有的個體,生成新的種群。
- 終止:如果滿足停止條件,則演算法停止,返回最優解。
三、遺傳演算法的應用案例
案例1:函數最優化問題
以下面的函數為例,來演示如何使用遺傳演算法求解函數最優化問題。
def function(x):
return x*x + 5*math.sin(x)
使用遺傳演算法求解函數最優化問題,需要設計好適應度函數。在這裡,用函數的取值來作為個體的適應度。具體的實現如下:
import random
import math
def function(x):
return x*x + 5*math.sin(x)
# 適應度函數
def fitness_func(individual):
return function(individual)
# 種群規模
POPULATION_SIZE = 100
# 交叉率
CROSSOVER_RATE = 0.8
# 變異率
MUTATION_RATE = 0.1
# 最大迭代次數
MAX_ITERATION = 100
# 種群類
class Population:
def __init__(self, size):
self.individuals = []
for i in range(size):
individual = random.uniform(-10, 10)
self.individuals.append(individual)
# 獲取種群中適應度最高的個體
def get_best_individual(self):
return max(self.individuals, key=fitness_func)
# 獲取種群的平均適應度
def get_average_fitness(self):
total_fitness = sum([fitness_func(individual) for individual in self.individuals])
return total_fitness / len(self.individuals)
# 選擇
def selection(self):
fitness_list = [fitness_func(individual) for individual in self.individuals]
fitness_sum = sum(fitness_list)
fitness_prob = [fitness / fitness_sum for fitness in fitness_list]
selected = random.choices(self.individuals, weights=fitness_prob, k=POPULATION_SIZE)
return selected
# 交叉
def crossover(self, individuals):
new_individuals = []
for i, individual in enumerate(individuals):
if random.random() < CROSSOVER_RATE and i != 0:
parent1 = individual
parent2 = individuals[i-1]
m_rate = random.random()
new_individual = m_rate * parent1 + (1 - m_rate) * parent2
new_individuals.append(new_individual)
return new_individuals
# 變異
def mutation(self, individuals):
new_individuals = []
for individual in individuals:
if random.random() < MUTATION_RATE:
new_individual = random.uniform(-10, 10)
else:
new_individual = individual
new_individuals.append(new_individual)
return new_individuals
# 更新種群
def update(self):
selected = self.selection()
crossed = self.crossover(selected)
mutated = self.mutation(crossed)
self.individuals = mutated
在這裡,我們設置種群大小為100,交叉率為0.8,變異率為0.1,最大迭代次數為100。定義一個Population類,實現選擇、交叉、變異等操作。最終得到該函數的最優解。
案例2:0-1背包問題
0-1背包問題是一個經典的組合優化問題,被廣泛應用於生產排程、資源分配等領域。以下是0-1背包問題的一個例子:
有一張表格,每行表示一件物品與其相應的權值和重量,背包的容量為C。假設每樣物品只有一個,即只有一件可用,如何選擇才能使得背包中的物品總權值最大?
使用遺傳演算法求解0-1背包問題,需要設計好適應度函數。在這裡,用背包中物品的權值之和來作為個體的適應度。具體的實現如下:
import random
# 物品類
class Item:
def __init__(self, weight, value):
self.weight = weight
self.value = value
# 適應度函數
def fitness_func(individual, items, capacity):
total_weight = sum([items[i].weight for i in range(len(individual)) if individual[i] == 1])
if total_weight > capacity:
return 0
else:
total_value = sum([items[i].value for i in range(len(individual)) if individual[i] == 1])
return total_value
# 種群規模
POPULATION_SIZE = 100
# 交叉率
CROSSOVER_RATE = 0.8
# 變異率
MUTATION_RATE = 0.1
# 最大迭代次數
MAX_ITERATION = 100
# 種群類
class Population:
def __init__(self, size, items, capacity):
self.individuals = []
self.items = items
self.capacity = capacity
for i in range(size):
individual = [random.randint(0, 1) for _ in range(len(items))]
self.individuals.append(individual)
# 獲取種群中適應度最高的個體
def get_best_individual(self):
return max(self.individuals, key=lambda x: fitness_func(x, self.items, self.capacity))
# 獲取種群的平均適應度
def get_average_fitness(self):
total_fitness = sum([fitness_func(individual, self.items, self.capacity) for individual in self.individuals])
return total_fitness / len(self.individuals)
# 選擇
def selection(self):
fitness_list = [fitness_func(individual, self.items, self.capacity) for individual in self.individuals]
fitness_sum = sum(fitness_list)
fitness_prob = [fitness / fitness_sum for fitness in fitness_list]
selected = random.choices(self.individuals, weights=fitness_prob, k=POPULATION_SIZE)
return selected
# 交叉
def crossover(self, individuals):
new_individuals = []
for i, individual in enumerate(individuals):
if random.random() < CROSSOVER_RATE and i != 0:
parent1 = individual
parent2 = individuals[i-1]
m_point = random.randint(1, len(self.items)-1)
new_individual = parent1[:m_point] + parent2[m_point:]
new_individuals.append(new_individual)
return new_individuals
# 變異
def mutation(self, individuals):
new_individuals = []
for individual in individuals:
if random.random() < MUTATION_RATE:
m_point = random.randint(0, len(self.items)-1)
individual[m_point] = 1 - individual[m_point]
new_individuals.append(individual)
return new_individuals
# 更新種群
def update(self):
selected = self.selection()
crossed = self.crossover(selected)
mutated = self.mutation(crossed)
self.individuals = mutated
在這裡,我們設置種群大小為100,交叉率為0.8,變異率為0.1,最大迭代次數為100。定義一個Population類,實現選擇、交叉、變異等操作。最終得到該問題的最優解。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/196876.html
微信掃一掃
支付寶掃一掃