纯个人学习记录,如有问题,请大佬指出。
本例用遗传算法求解函数最优解问题
f(x)=x*sin(arctan(1)*4*x)+2.0 (-1.0<x<2.0)
第一步:初始化种群-----定义一个函数initgeneration 生成第一代种群群体 population[]
def initgeneration(popsize, lchrom):
population = [] # 用来存放第一代初始化的种群
for i in range(popsize):
temporyary = [] # 染色体暂存器,用来储存新生成的染色体
for j in range(lchrom):
total = random.randint(0, 1)
temporyary.append(total)
population.append(temporyary)
return population
第二步:编码----catulatefitness()---把生成的二进制转换成十进制数,求出初始种群每个个体的适应度值fitness_values[]
def caculatefitness(population, lchrom):
decimal = [] # 存放初始种群每个个体的十进制数
for i in range(len(population)):
temporary = 0
fitness_value = []
population[i].reverse() # 反转列表,为下面计算十进制做准备
for j in range(lchrom): # 二进制转换成十进制
temporary = temporary + population[i][j] * (math.pow(2, j))
decimal.append(temporary)
for i in range(len(population)):
x = -1.0 + decimal[i] * 3 / (math.pow(2, lchrom) - 1)
fitness_value.append(x * math.atan(1) * 4 * x + 2.0)
# 判断每个个体的适应度是否存在负数,如果有则重置为0
fitness_values = []
for i in range(len(fitness_value)):
if fitness_value[i] > 0:
fitness_values.append(fitness_value[i])
else:
fitness_values.append(0)
# print("适应度值为fitnesas_values为:", fitness_values)
# print(population)
return fitness_values
第三步:选择操作-----selectopration()---进行适应度的求和sum,然后计算每个个体的选择概率 = fitness_values[i]/sum(fitness_values),然后计算累积概率,接着产生随机数,如果小于某个累积概率,则进行选择
# 选择操作
def selectopration(population, fitness_values):
q = []
# 进行适应值的求和
sum = 0
for i in range(len(fitness_values)):
sum += fitness_values[i]
# print("适应值求和sum为:", sum)
# 计算每个个体的选择概率
for i in range(len(fitness_values)):
q.append(fitness_values[i] / sum)
# print("个体选择概率q为:", q)
# 计算累计概率
p = []
total = 0
for i in range(len(q)):
total += q[i]
p.append(total)
# 随机选取
new_population = []
ms = [] # 用来存放判断存活的种群的随机数
for i in range(len(population)):
ms.append(random.random())
ms.sort()
# print("个体累计概率p为:", p)
# print("选择操作随机生成数ms为:", ms)
new_population = []
i = 0
j = 0
while i < len(population):
if ms[i] < p[j]:
new_population.append(population[i])
i += 1
else:
j += 1
# print(new_population)
population = new_population # 存放的是选择的个体的累积概率
# print(len(population))
return population
第四步:杂交操作----crossoveropration()---对选择操作选下来的种群进行交叉----随机生成[0,1]之间的数与杂交概率进行比较,如果小于杂交概率,则进行杂交---单点杂交:随机相邻的两个个体,通过随机生成杂交点,进行杂交。
# 杂交操作---对选择操作选下来的种群进行交叉----随机生成[0,1]之间的数与杂交概率进行比较
# 如果小于杂交概率,则进行杂交---单点杂交
def crossoveropration(population, pc):
for i in range(len(population) - 1):
temporary1 = []
temporary2 = []
total = random.random()
if (total <= pc):
crosspoint = random.randint(0, len(population[i]) - 1) # 杂交点
temporary1.extend(population[i][0: crosspoint])
temporary1.extend(population[i + 1][crosspoint:len(population[i])])
temporary2.extend(population[i + 1][0:crosspoint])
temporary2.extend(population[i][crosspoint:len(population[i])])
else:
temporary1 = population[i]
temporary2 = population[i + 1]
population[i] = temporary1
population[i + 1] = temporary2
# print(len(population))
# print("交叉后种群为:", population)
return population
第五步:变异操作----mutationopration()---随机生成一个变异点,然后根据随机生成数若小于变异概率----若基因位为0,则基因位变为1,否则为0
# 变异操作----随机生成一个变异点,然后根据随机生成数小于变异概率----若基因位为0,则基因位变为1,否则为1
def mutationopration(population, pm):
for i in range(len(population)):
j = 0
while (j < 2):
mutationpoint = random.randint(0, len(population[i]) - 1)
if (random.random() < pm):
if (population[i][mutationpoint] == 0):
population[i][mutationpoint] = 1
else:
population[i][mutationpoint] = 0
j += 1
# print("变异后种群为:", population)
return population
第六步:寻找最好的适应度个体---FindBestAndCurrent()---根据当前一代种群每个个体的适应度值进行比较,找出当前种群最好的适应值,和当前最佳个体,然后与全局最佳个体的适应值进行比较,判断谁是最优值,保证最优解的更新。 ----最后输出当前个体,当前最佳个体,当前最佳个体染色体,当前最佳适应度值 ----输出全局最佳个体,全局最佳个体染色体,全局最佳适应度值
# 寻找最好的个体
def FindBestAndCurrent(population, lchrom):
k = gen
m = 0 # 用来标记当代中最好适应度个体的位置
# 先选出当代适应度最好的为
current_best = [] # 当代最好个体
fitness_values = caculatefitness(population, lchrom)
fitness_values.sort()
maxfitness = fitness_values[0]
for i in range(len(population)):
if (maxfitness < fitness_values[i]):
maxfitness = fitness_values[i]
m = i
current_best = population[m] # 当代最好个体
current_best_fitness = maxfitness # 当代最好个体适应值
current_generation = k + 1
print("第几代:", current_generation)
# 进行当代与全局最好适应度个体进行比较
global global_best_fitness
global global_best
# global_best = [] # 全局最好个体
if (global_best_fitness < current_best_fitness):
global_best_fitness = current_best_fitness
global_best = current_best
# 输出当前个体,当前最佳个体,当前最佳个体染色体,当前最佳适应度值
# 输出全局最佳个体,全局最佳个体染色体,全局最佳适应度值
print("当前种群个体:", population)
print("当前种群最佳个体:", current_best)
print("当前种群每个个体适应度值:", fitness_values)
print("当前种群最佳适应度值:", current_best_fitness)
print("-------------")
print("全局最佳个体:", global_best)
print("全局最佳适应度值", global_best_fitness)
return (current_best, current_best_fitness, global_best, global_best_fitness)
第七步:利用main()函数进行迭代250次
# 总共迭代次数250
def main():
N = 250
global gen
popsize = 30
lchrom = 20
pm = 0.01
pc = 0.60
population = initgeneration(popsize, lchrom)
while (gen < N):
print("#######################################################################################################")
fitness_values = caculatefitness(population, lchrom) # 求每个个体的适应值
A = selectopration(population, fitness_values) # 选择操作
B = crossoveropration(A, pc) # 交叉操作
C = mutationopration(B, pm) # 变异操作
FindBestAndCurrent(C, lchrom) # 求当前个体,当前最佳个体,当前最佳个体适应度,全局最佳个体,全局最佳个体适应值
gen += 1
全部代码如下:
全部代码如下:
import random
import math
global global_best_fitness # 使用 global 声明为全局变量
global global_best # 使用 global 声明为全局变量
global gen
global_best_fitness = 0
global_best = []
gen = 0
# 初始化种群 poplation_size = popsize = 种群大小,,chromosome_length = lchrom = 染色体长度
def initgeneration(popsize, lchrom):
population = [] # 用来存放第一代初始化的种群
for i in range(popsize):
temporyary = [] # 染色体暂存器,用来储存新生成的染色体
for j in range(lchrom):
total = random.randint(0, 1)
temporyary.append(total)
population.append(temporyary)
return population
# 编码--把二进制数转化成十进制数 计算适应度函数
def caculatefitness(population, lchrom):
decimal = [] # 存放初始种群每个个体的十进制数
for i in range(len(population)):
temporary = 0
fitness_value = []
population[i].reverse() # 反转列表,为下面计算十进制做准备
for j in range(lchrom): # 二进制转换成十进制
temporary = temporary + population[i][j] * (math.pow(2, j))
decimal.append(temporary)
for i in range(len(population)):
x = -1.0 + decimal[i] * 3 / (math.pow(2, lchrom) - 1)
fitness_value.append(x * math.atan(1) * 4 * x + 2.0)
# print(len(decimal))
# 判断每个个体的适应度是否存在负数,如果有则重置为0
fitness_values = []
for i in range(len(fitness_value)):
if fitness_value[i] > 0:
fitness_values.append(fitness_value[i])
else:
fitness_values.append(0)
# print("适应度值为fitnesas_values为:", fitness_values)
# print(population)
return fitness_values
# 选择操作
def selectopration(population, fitness_values):
q = []
# 进行适应值的求和
sum = 0
for i in range(len(fitness_values)):
sum += fitness_values[i]
# print("适应值求和sum为:", sum)
# 计算每个个体的选择概率
for i in range(len(fitness_values)):
q.append(fitness_values[i] / sum)
# print("个体选择概率q为:", q)
# 计算累计概率
p = []
total = 0
for i in range(len(q)):
total += q[i]
p.append(total)
# 随机选取
new_population = []
ms = [] # 用来存放判断存活的种群的随机数
for i in range(len(population)):
ms.append(random.random())
ms.sort()
# print("个体累计概率p为:", p)
# print("选择操作随机生成数ms为:", ms)
new_population = []
i = 0
j = 0
while i < len(population):
if ms[i] < p[j]:
new_population.append(population[i])
i += 1
else:
j += 1
# print(new_population)
population = new_population # 存放的是选择的个体的累积概率
# print(len(population))
return population
# 杂交操作---对选择操作选下来的种群进行交叉----随机生成[0,1]之间的数与杂交概率进行比较
# 如果小于杂交概率,则进行杂交---单点杂交
def crossoveropration(population, pc):
for i in range(len(population) - 1):
temporary1 = []
temporary2 = []
total = random.random()
if (total <= pc):
crosspoint = random.randint(0, len(population[i]) - 1) # 杂交点
temporary1.extend(population[i][0: crosspoint])
temporary1.extend(population[i + 1][crosspoint:len(population[i])])
temporary2.extend(population[i + 1][0:crosspoint])
temporary2.extend(population[i][crosspoint:len(population[i])])
else:
temporary1 = population[i]
temporary2 = population[i + 1]
population[i] = temporary1
population[i + 1] = temporary2
# print(len(population))
# print("交叉后种群为:", population)
return population
# 变异操作----随机生成一个变异点,然后根据随机生成数小于变异概率----若基因位为0,则基因位变为1,否则为1
def mutationopration(population, pm):
for i in range(len(population)):
j = 0
while (j < 2):
mutationpoint = random.randint(0, len(population[i]) - 1)
if (random.random() < pm):
if (population[i][mutationpoint] == 0):
population[i][mutationpoint] = 1
else:
population[i][mutationpoint] = 0
j += 1
# print("变异后种群为:", population)
return population
# 寻找最好的个体
def FindBestAndCurrent(population, lchrom):
k = gen
m = 0 # 用来标记当代中最好适应度个体的位置
# 先选出当代适应度最好的为
current_best = [] # 当代最好个体
fitness_values = caculatefitness(population, lchrom)
fitness_values.sort()
maxfitness = fitness_values[0]
for i in range(len(population)):
if (maxfitness < fitness_values[i]):
maxfitness = fitness_values[i]
m = i
current_best = population[m] # 当代最好个体
current_best_fitness = maxfitness # 当代最好个体适应值
current_generation = k + 1
print("第几代:", current_generation)
# 进行当代与全局最好适应度个体进行比较
global global_best_fitness
global global_best
# global_best = [] # 全局最好个体
if (global_best_fitness < current_best_fitness):
global_best_fitness = current_best_fitness
global_best = current_best
# 输出当前个体,当前最佳个体,当前最佳个体染色体,当前最佳适应度值
# 输出全局最佳个体,全局最佳个体染色体,全局最佳适应度值
print("当前种群个体:", population)
print("当前种群最佳个体:", current_best)
print("当前种群每个个体适应度值:", fitness_values)
print("当前种群最佳适应度值:", current_best_fitness)
print("-------------")
print("全局最佳个体:", global_best)
print("全局最佳适应度值", global_best_fitness)
return (current_best, current_best_fitness, global_best, global_best_fitness)
# 总共迭代次数250
def main():
N = 250
global gen
popsize = 30
lchrom = 22
pm = 0.05
pc = 0.80
population = initgeneration(popsize, lchrom)
while (gen < N):
print("##############################################################################")
fitness_values = caculatefitness(population, lchrom) # 求每个个体的适应值
A = selectopration(population, fitness_values) # 选择操作
B = crossoveropration(A, pc) # 交叉操作
C = mutationopration(B, pm) # 变异操作
FindBestAndCurrent(C, lchrom) # 求当前个体,当前最佳个体,当前最佳个体适应度,全局最佳个体,全局最佳个体适应值
gen += 1
if __name__ == "__main__":
main()
代码运行结果如下: