大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客
本文原创为亓官劼,请大家支持原创,部分平台一直在盗取博主的文章!!!
博主目前仅在CSDN中写博客,唯一博客更新的地址为:亓官劼的博客
本文中的遗传算法是之前所写,为10个种群,10个染色体的遗传算法实现。
适应值函数为di的累加
其余各项在代码中有注释,有需要的话可以自行查看,仅为遗传算法实现的一个示例。
import pandas as pd
import numpy as np
from pandas import DataFrame
import math, random
from math import log
# 种群类
class Population:
def restraint(self,indvs):
sum = 0
for item in indvs:
sum += self.data_list[item][4]
if sum < 500:
return True
else:
return False
def __init__(self, data_file, size, cp, mp, gen_max):
# data_file数据文件路径
# size 为种群所包含的个体数
# cp 个体之间的交叉概率
# mp 个体之间的变异概率
# gen_max 种群进化的最大世代数
# data为读取的数据文件内容
self.data = pd.read_excel(data_file, index_col=None)
# 数据集个体约束
self.data = self.data[(self.data['a_cp'] > 1) & (self.data['b_cp'] > 1) & (self.data['c_cp'] > 1)]
self.cols = ['TARGET_FID', 'a', 'b', 'c', 'd', 'a_cp', 'b_cp', 'c_cp', 'd_cp']
self.data_num = self.data.count()[0] # 数据项数
self.data_array = np.array(self.data)
self.data_list = self.data_array.tolist()
self.dir = {'TARGET_FID': 0, 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'a_cp': 5, 'b_cp': 6, 'c_cp': 7, 'd_cp': 8}
self.individuals = [] # 个体集合
self.fitness = [] # 个体适应度集
self.selector_probability = [] # 个体选择概率集合
self.new_individuals = [] # 新一代个体集合
self.elitist = {'chromosome': [0 for i in range(10)], 'fitness': 0, 'age': 0} # 最佳个体的信息
self.size = size # 种群所包含的个体数
self.chromosome_size = int(log(self.data_num, 2)) + 1 # 个体的染色体长度
self.crossover_probability = cp # 个体之间的交叉概率
self.mutation_probability = mp # 个体之间的变异概率
self.generation_max = gen_max # 种群进化的最大世代数
self.age = 0 # 种群当前所处世代
# 随机产生初始个体集,并将新一代个体、适应度、选择概率等集合以 0 值进行初始化
v = self.data_num
for i in range(self.size):
# 这里直接使用了十进制,一般使用二进制来表示基因型
indvs = [random.randrange(0, v) for i in range(10)]
while self.restraint(indvs) is True:
indvs = [random.randrange(0, v) for i in range(10)]
self.individuals.append(indvs)
self.fitness.append(0)
self.selector_probability.append(0)
# 适应度函数
def Fitness(self, individual):
# 适应值函数
# individual 为个体
f = 0
for i in individual:
f = f + self.data_list[i][2]
return f
# 计算个体适应度
def compute_fitness(self):
for i in range(self.size):
self.fitness[i] = self.Fitness(self.individuals[i])
# 计算个体复制概率
def compute_select(self):
sum = 0
for i in range(self.size):
sum += self.fitness[i]
for i in range(self.size):
self.selector_probability[i] = self.fitness[i] / sum
# 复制
def select(self):
copy_num = 0
for i in range(self.size):
if self.selector_probability[i] * self.size > 1:
copy_item = int(self.selector_probability[i] * self.size)
self.selector_probability[i] -= copy_item
for m in range(copy_item):
self.new_individuals.append(self.individuals[i])
new_indvs_num = self.new_individuals.__len__()
for i in range(self.size - new_indvs_num):
# 当前最大复制概率的下标
now_max_sp_index = self.selector_probability.index(max(self.selector_probability))
self.selector_probability[now_max_sp_index] -= 1 / self.size
self.new_individuals.append(self.individuals[now_max_sp_index])
# 交叉
def cross(self):
# 随机筛选交叉个体
# 这里个体是多染色体的,可以个体间交叉,也可以个体内交叉
# 这里为个体内交叉
cross_index = []
for i in range(self.size):
p = random.random()
if p > (1 - self.crossover_probability):
cross_index.append(i)
cross_num = cross_index.__len__()
# 下面开始选择交叉位置,由于这里的数据项为均不为2次幂的整数,为了保证数据安全,二进制位第一位默认不选。
# 在选中交叉个体后,进行交叉
for i in range(cross_index.__len__()):
idvs = cross_index[i]
item_1_index = random.randint(0, 10)
item_2_index = random.randint(0, 10)
item_1 = self.new_individuals[idvs][item_1_index]
item_2 = self.new_individuals[idvs][item_2_index]
# 由于我们个体中使用的十进制,首先要转化为2进制进行处理
bin_item_1 = str(bin(item_1))[2:].zfill(self.chromosome_size)
bin_item_2 = str(bin(item_2))[2:].zfill(self.chromosome_size)
cross_position = random.randint(1, self.chromosome_size)
new_bin_item_1 = bin_item_1[0:cross_position] + bin_item_2[cross_position:]
new_bin_item_2 = bin_item_2[0:cross_position] + bin_item_1[cross_position:]
new_item_1 = int(new_bin_item_1, 2)
new_item_2 = int(new_bin_item_2, 2)
self.new_individuals[idvs][item_1_index] = new_item_1
self.new_individuals[idvs][item_2_index] = new_item_2
if self.restraint(self.new_individuals[idvs]) is False:
self.new_individuals[idvs] = self.individuals[idvs]
# 变异操作
def mutate(self):
# 随机选择变异个体
mutate_index = []
for i in range(self.size):
p = random.random()
if p > (1 - self.mutation_probability):
mutate_index.append(i)
mutate_num = mutate_index.__len__()
for i in range(mutate_index.__len__()):
idvs = mutate_index[i]
# 个体中随机一个染色体进行变异
item = random.randint(0, 9)
mutate_position = random.randint(1, self.chromosome_size - 1)
item_bin = bin(self.new_individuals[idvs][item])[2:].zfill(self.chromosome_size)
if item_bin[mutate_position] == '0':
item_bin = item_bin[:mutate_position] + '1' + item_bin[mutate_position + 1:]
else:
item_bin = item_bin[:mutate_position] + '0' + item_bin[mutate_position + 1:]
new_item = int(item_bin, 2)
self.new_individuals[idvs][item] = new_item
if self.restraint(self.new_individuals[idvs]) is False:
self.new_individuals[idvs] = self.individuals[idvs]
# 保留最佳个体
def reproduct_elitist(self):
# 与当前种群进行适应度比较,更新最佳个体
j = -1
for i in range(self.size):
if self.elitist['fitness'] < self.fitness[i]:
j = i
self.elitist['fitness'] = self.fitness[i]
if (j >= 0):
self.elitist['chromosome'] = self.individuals[j]
self.elitist['age'] = self.age
# 遗传算法迭代过程
def evolve(self):
self.age += 1
self.compute_fitness()
self.compute_select()
self.select()
self.mutate()
self.individuals = self.new_individuals
self.new_individuals = []
self.compute_fitness()
self.reproduct_elitist()
# 遗传算法迭代
def run(self):
for i in range(self.generation_max):
self.evolve()
print('迭代结束,当前最佳个体信息如下:')
print('当前个体的组内各染色体的TARGET_FID分别为:')
chromosomes = self.elitist['chromosome']
for i in range(10):
print(self.data_list[chromosomes[i]][0])
print("此时的目标函数的值为:", self.elitist['fitness'])
# data_file 数据文件路径
data_file = '/Users/qiguan/Downloads/data.xlsx'
# 数据文件路径为:data_file
# 规模大小:10
# 交叉概率0.2
# 变异概率0.02
# 最大迭代数10
population = Population(data_file, 10, 0.2, 0.02, 10)
population.run()