遗传算法结合模糊认知图实现论文数据 (可能有错误),仅供参考。数据来自一篇论文(论文题目:基于模糊认知图的物流需求预测模型研究)。

# 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)





你可能感兴趣的:(python,开发语言)