# author:Lenovo # datetime:2022/10/27 19:31 # software: PyCharm # project:project_dmeo01 import pandas as pd import numpy as np import math import random class GA(object): def __init__(self,poopulation_size,N,pc,pm,Max_step): self.population_size=poopulation_size self.N=N self.pc=pc self.pm=pm self.Max_step=Max_step #求最大和最小的y值 def get_maxmin_y(self): temp_list = [] data = pd.read_csv('2005简化版.csv') max_value1 = data['社会物流总额'].max() min_value1 = data['社会物流总额'].min() temp_list.append(max_value1) temp_list.append(min_value1) max_value2 = data['GDP'].max() min_value2 = data['GDP'].min() temp_list.append(max_value2) temp_list.append(min_value2) max_value3 = data['物流消费总额'].max() min_value3 = data['物流消费总额'].min() temp_list.append(max_value3) temp_list.append(min_value3) max_value4 = data['固定资产投资'].max() min_value4 = data['固定资产投资'].min() temp_list.append(max_value4) temp_list.append(min_value4) max_value5 = data['进口总额'].max() min_value5 = data['进口总额'].min() temp_list.append(max_value5) temp_list.append(min_value5) max_value6 = data['出口总额'].max() min_value6 = data['出口总额'].min() temp_list.append(max_value6) temp_list.append(min_value6) # print(temp_list) # print(len(temp_list)) max_min_list = [] for i in range(0, len(temp_list), 2): n = (int)(i / 2) max_min_list.append([]) # print(n) max_min_list[n].append(temp_list[i]) max_min_list[n].append(temp_list[i + 1]) # print(max_min_list) # print(max_min_list) return max_min_list #初始化种群: def species_orgin(self): #初始化种群:和染色体: population=[] for i in range(self.population_size): chromosome = [[]] for j in range(self.N): #一维列表暂存器: temp=[] for k in range(self.N): if (j==k): temp.append(0.0) else: #染色体随机赋值: temp.append(np.random.uniform(-1,1)) # print(type(temp[0])) chromosome.append(temp) chromosome=chromosome[1:] population.append(chromosome) print("初始化的种群:") print(population) return population #获得训练集的节点数据: def read_csv(self,filename): #返回归一化的二维列表: f = open(filename, 'r') content = f.read() final_list = list() rows = content.split('\n') for row in rows: cpoint_M=len(rows[0].split(',')) final_list.append(row.split(',')) #得到归一化二维列表的维度 cpoint_N=len(final_list[:-1]) # print(cpoint_N) # print(final_list[:-1]) #将其转为float类型: cpoint_list=[] for i in range(cpoint_N): temp=[] for j in range(cpoint_M) : j=float(final_list[i][j]) temp.append(j) cpoint_list.append(temp) # print("归一化后的节点数据:") # print(cpoint_list) #返回年份节点列表的的行数和列数 return cpoint_list,cpoint_N,cpoint_M #得到适应度的函数: def get_fitness(self,cpoint_list,population,cpoint_N,cpoint_M): fitness_value=[] #定义适应度列表 dic_population={}#定义一个fitness_value[i] 与population[i]对应的字典; #50条染色体 self.population_size=50 for indivadual in range(self.population_size):#计算每一个个体的适应度: #计算边权和 year_sum_list=[] #定义每一年预测值与真实值 方差求和列表 for k in range(1,cpoint_N):# 遍历到第几年 ; sum1=0 #每一年的(各个节点c^-ci)^2 之和: for i in range(cpoint_M): #第 i 个节点: #激活函数里面权值 与各个节点与受影响的权值相乘在相加: total = 0 for j in range(self.N): #第 j 行 if j!=i: total+=population[indivadual][j][i] * cpoint_list[k-1][i] # cpredict_list.append(self.Sigmod(total)) # print("total的值是:",total) #求出一年的预测值与真实值之间的方差和 sum1+=(self.Sigmod(total)-cpoint_list[k][i]) * (self.Sigmod(total)-cpoint_list[k][i]) # print(sum1) #存放每一年的节点方差和: year_sum_list.append(sum1) #求err year_sum=0 for i in range(len(year_sum_list)):# 求各个节点方差之和: year_sum+= year_sum_list[i] # print(year_sum) err = (1 / (self.N * cpoint_N)) * year_sum fitness=1/(err+1) #将个体适应度与个体配对: dic_population[fitness]=population[indivadual] fitness_value.append(fitness) # print(dic_population) # print((fitness_value)) # print("排序后的fitness_value:") fitness_value=sorted(fitness_value, key=float, reverse=True) # print(fitness_value) # #返回一个 排好序的50大小的适应度值 的列表:和 对应的字典 return fitness_value,dic_population #设置激活函数: def Sigmod(self,x): fx_res=1/(1+math.exp(-x)) #映射到[0,1]之间: # fx_res=math.tanh(x) return fx_res #得到最好的两个体 def get_best_individuals(self,fitness_value,dic_population,poulation): #保留最好的两个个体: new_pop=[] fit_length=len(fitness_value) #选择两个最好的插入新的new_pop max1_fitness=fitness_value[0] # print("最好适应度1:",max1_fitness,dic_population.get(max1_fitness)) max2_fitness=fitness_value[1] # print("最好适应度2:", max2_fitness, dic_population.get(max2_fitness)) new_pop.append(dic_population.get(max1_fitness)) new_pop.append(dic_population.get(max2_fitness)) # print("最好的适应度的两个体:") # print(new_pop) # 选择两个剩下最优的个体 进行交叉变异: for i in range(2,fit_length,2): temp1=[] temp2=[] #将选出的两个个体二维变为一维的列表: pop1=dic_population.get(fitness_value[i]) pop2=dic_population.get(fitness_value[i+1]) # print(fitness_value[i]) # print(fitness_value[i+1]) for j in range(len(pop1)): #N 是节点的个数: for k in range(self.N): temp1.append(pop1[j][k]) # print("temp1的列表数据:",temp1) # print("temp1的长度:",len(temp1)) for j in range(len(pop2)): #N 是节点的个数: for k in range(self.N): temp2.append(pop2[j][k]) # print("temp2的列表数据:",temp2) #交叉 返回交叉后的列表,然后进行变异: c_temp1,c_temp2=self.crossover_individual(temp1,temp2) #变异: m_temp1,m_temp2=self.mutation_individual(c_temp1,c_temp2) #重新组成新的染色体: next_pop1=self.transform_chromosome(m_temp1) next_pop2=self.transform_chromosome(m_temp2) # new_pop.append(next_pop1) new_pop.append(next_pop2) # print("new_pop的长度是:") # print(len(new_pop)) # print("new_pop的值为:") # print(new_pop) return new_pop # 转化为染色体二维列表: def transform_chromosome(self, temp): chromosome = [] for i in range(0,len(temp),6): index_list=[] for j in range(i+6): index_list.append(temp[j]) chromosome.append(index_list) # print(chromosome) return chromosome #交叉 def crossover_individual(self,temp1,temp2): #设置一个随机的变异点 cpoint=random.randint(0,len(temp1)-1) # print("交叉的点:",cpoint) first_temp=[] second_temp=[] #大于交叉概率才进行交叉: if(random.random() > self.pc): first_temp.extend(temp1[0:cpoint]) first_temp.extend(temp2[cpoint:len(temp2)]) second_temp.extend((temp2[0:cpoint])) second_temp.extend(temp1[cpoint:len(temp1)])#交叉完毕: # print("first_temp:",first_temp) # print("second_temp:", second_temp) temp1=first_temp temp2=second_temp # print(temp1) # print(temp2) return temp1,temp2 #变异: def mutation_individual(self,c_temp1,c_temp2): random_R1=random.randint(1,10) random_R2=random.randint(1,10) # # print("c_temp1:") # print(c_temp1) # print("c_temp2:") # print(c_temp2) #设置变异点 first_mpoint=random.randint(0,len(c_temp1)-1) second_mpoint=random.randint(0,len(c_temp2)-1) # print("第一个个体的变异点为:",first_mpoint) # print("第二个个体的变异点为:",second_mpoint) # 设置小r 的值 : r1=random.random() r2=random.random() #如果第一个随机数 变异第一个染色体 if(self.pm < random.random()): if(random_R1 % 2 == 0): c_temp1[first_mpoint]=c_temp1[first_mpoint] + (r1-0.5) * self.Max_step else: c_temp1[first_mpoint] = c_temp1[first_mpoint] - (r1 - 0.5) * self.Max_step #变异第二个染色体 if (self.pm < random.random()): if (random_R2 % 2 == 0): c_temp2[second_mpoint] = c_temp2[second_mpoint] + (r2 - 0.5) * self.Max_step else: c_temp2[second_mpoint] = c_temp2[second_mpoint] - (r2 - 0.5) * self.Max_step # print("变异后的temp1:",c_temp1) # print("变异后的temp2:",c_temp2) return c_temp1,c_temp2 #预测节点的值: def predict_point(self,test_list,cpoint_N,cpoint_M,best_individual,max_min_list): print(cpoint_N) for k in range(1, cpoint_N): # 遍历到第几年 从第二年开始,第一年的数据要使用; sum1 = 0 # 每一年的(各个节点c^-ci)^2 之和: predict_list=[] for i in range(cpoint_M): # 激活函数里面i点与各个节点与受影响的权值相乘在相加: total = 0 for j in range(self.N): if j != i: total+=best_individual[j][i] * test_list[k-1][i] #得到预测的值: predict_list.append(self.Sigmod(total) * (max_min_list[i][0]-max_min_list[i][1]) + max_min_list[i][1]) # 得到了下一年的归一化的预测值的列表: print("预测值:") print(predict_list) # break if __name__ == '__main__': population_size=50 # M=50 N=6 #节点个数 # T=100#设置最大的迭代数 pc=0.7#交叉的概率: Max_step=1 #设置最大步长; pm=0.01 #变异的概率 ga=GA(poopulation_size=population_size,N=N,pc=pc,pm=pm,Max_step=Max_step) #初始化种群: population=ga.species_orgin() # 得到训练集: cpoint_list, cpoint_N, cpoint_M = ga.read_csv('Train1_归一化.csv') #迭代50次: for i in range(1000): fitness_value,dic_population=ga.get_fitness(cpoint_list,population,cpoint_N,cpoint_M) # print(fitness_value[0]) #返回了下一代的个体: new_pop=ga.get_best_individuals(fitness_value,dic_population,population) population=new_pop # print("迭代100次后的种群:",population) final_fitness_value,final_dic_population=ga.get_fitness(cpoint_list,population,cpoint_N,cpoint_M) print("迭代1000次后的适应度:",final_fitness_value) # print("**************************************************************************************************") # print("迭代50次后的适应度与个体染色体对应的字典:",final_dic_population) print("最佳的个体为:",final_fitness_value[0],final_dic_population.get(final_fitness_value[0])) #得到最好的w: best_individual=final_dic_population.get(final_fitness_value[0]) print("=========================================================================") print("2006-2010年预测值:") #读取测试集的归一化二维列表: 测试集列表的长度,二级列表的长度: test_list,test_cpointlist_N,test_cpointlist_M=ga.read_csv('Test1_归一化.csv') # print(test_list,test_cpointlist_N,test_cpointlist_M) #得到最大y 和最小y的二维列表: max_min_list=ga.get_maxmin_y() ga.predict_point(test_list,test_cpointlist_N,test_cpointlist_M,best_individual,max_min_list)