智能优化课,老师让实现遗传算法,每行加注释,略感无语。。。我发现我正好有现成的,加了下注释。
import numpy as np
import random
from matplotlib import pyplot as plt
mutation_rate = 0.001 # 变异率
max_iter = 500 # 最大迭代次数
m = 20 # 总基因个数
n = 4 # 单个基因长度
def func(x): # 目标函数
return 15 * x - x ** 2
class Gene():
def __init__(self, n, func: 'function'):
'''
## 基因类
---
n: 基因长度
func: 用于计算适应度的函数
'''
self.n = n # 基因长度
self.func = func # 适应度计算函数
self.gene = [0 for i in range(self.n)] # 用一个数组表示基因
def mutation(self): # 变异
for i in range(self.n): # 对每一位基因进行变异判断
if random.uniform(0, 1) <= mutation_rate: # 如果随机数小于变异概率
self.gene[i] ^= 1 # 和1异或变成想法值
def cal_fitness(self): # 计算适应度
num = 0 # 基因所表示数字的和(二进制转十进制)
for i in self.gene: # 对于每位基因
num *= 2 # 前面所有位左移一位
num += i # 加上此位
return self.func(num) # 函数值作为适应度
def cross(n, g1: Gene, g2: Gene):
'''
## 基因交叉函数
---
n: 最大切断位置
g1: 基因1
g2: 基因2
'''
pos = random.randint(0, n) # 随机选择一个位置切断
# 交换操作
g1_r = g1.gene[pos:] # 暂存g1断点右边
g2_r = g2.gene[pos:] # 暂存g2断点右边
g1.gene[pos:] = g2_r # g2断点右边替换g1断点右边
g2.gene[pos:] = g1_r # g1断点右边替换g2断点右边
def next_gene(genes: list[Gene]): # 轮盘赌法选择下一代基因
'''
## 求下一代基因
---
genes: 当前所有基因
'''
select_prob = []
total_prob = 0.0 # 总概率值
for g in genes: # 根据适应度计算选择每个基因的概率
prob = g.cal_fitness() # 求出此基因概率(适应度)
select_prob.append(prob) # 保存起来
total_prob += prob # 求总概率(适应度)
new_genes: list[Gene] = [] # 保存新基因
for i in range(len(genes)): # 上一代有多少个,下一代就选多少个
prob = random.randint(0, total_prob) # 随机生成一个概率(位置)
c = -1 # 循环控制变量
while prob > 0: # 当prob没减完,说明还没到随机生成的位置
c += 1 # 循环变量加一
prob -= select_prob[c] # 按顺序减掉概率
new_genes.append(genes[i]) # 到了就将此处的基因作为下一代的一个基因
for i in range(int(len(genes) / 2)): # 每两个子代基因进行交叉和变异
cross(new_genes[i].n, new_genes[i], new_genes[i + 1]) # 交叉
new_genes[i].mutation() # 变异
new_genes[i + 1].mutation() # 变异
return new_genes # 返回新基因
def best_gene(genes: list[Gene]):
'''
## 求一代中最好的基因
---
genes: 所有基因
'''
best = 0 # 保存最佳值
for gene in genes: # 对于每个基因
fit = gene.cal_fitness() # 计算适应度
if fit > best: # 如果比目前最好的好
best = fit # 替换最好的
return best # 返回最好的基因
if __name__ == '__main__': # 主函数
genes = [Gene(n, func) for i in range(m)] # 生成初始基因
value = [] # 保存每次迭代的最佳基因适应度
i = 0 # 循环控制变量
while i < max_iter: # 大于最大迭代次数退出
genes = next_gene(genes) # 生成下一代基因
value.append(best_gene(genes)) # 保存最佳基因适应度
i += 1 # 循环变量加一
print(max(value)) # 输出最大值
ax1 = plt.subplot(1, 2, 1)
x = np.arange(-30, 30)
plt.plot(x, func(x))
ax2 = plt.subplot(1, 2, 2)
plt.plot(value) # 画图
plt.show() # 显示图像
有问题请大佬指正。