神奇的量子世界——量子遗传算法(Python&Matlab实现)

目录

1 重要知识点

1.1 遗传算法

 1.2 量子计算

1.3 量子遗传算法

2 操作步骤

3 流程图

4 量子遗传算法——Python实现 

4.1 数据

4.2 代码 

4.3 结果 

5 量子遗传算法——Matlab实现 

           ​


1 重要知识点

在专栏我已经系统总结了遗传算法:*智能优化算法(持续更新中......),下面我们先讲解重要知识点,然后用Python和Matlab分别实现。

1.1 遗传算法

遗传算法是一种模拟达尔文生物进化论和遗传变异的智能算法。这种算法具有鲁棒性(用以表征控制系统对特性或参数扰动的不敏感性)较强,实现的步骤规范、简单通用等优点,在人工智能、多目标决策、社会及经济等领域都有大量运用。但一般遗传算法存在一定的局限性:收敛速度慢、迭代的次数多,易过早收敛,容易陷入局部最优解。

 1.2 量子计算

量子计算为量子力学与信息科学的综合交叉学科。量子计算具有量子力学的并行性,计算速度更快;同时,量子状态多种多样,在进行最优解的搜索时极少陷入局部的极值。

1.3 量子遗传算法

量子遗传算法将量子的态矢量引入遗传算法,利用量子比特的概率幅应用于染色体的编码。一条染色体是多个量子状态的叠加。并使用量子旋转门实现染色体的变异更新。因此量子遗传算法具有迭代次数少,运行速度快,能以较少种群进行遗传变异,搜索范围广,难以陷入局部的极值等优点。

想更深入了解量子遗传算法,可以阅读以下两篇文章:

神奇的量子世界——量子遗传算法(Python&Matlab实现)_第1张图片 

神奇的量子世界——量子遗传算法(Python&Matlab实现)_第2张图片

简单通过一幅图介绍量子遗传算法的特性,黄色个体上有当前最优值,黑色为某其他个体,迭代一次,黑色个体会旋转并向黄色个体靠近,量子遗传算法用旋转门取代了原有的交叉过程。个体自带两个函数值,寻优收敛速度更快,有旋转过程寻找最优,旋转公式中也有惯性公式,即随着迭代次数增加旋转幅度会降低,整体比较遗传算法,更不易陷入局部最优。 

                                 神奇的量子世界——量子遗传算法(Python&Matlab实现)_第3张图片

操作步骤

2.1 运用量子比特初始化父代染色体

在传统的二进制计算中,用|0》与|1》表示数值,它们即为比特。类似的,在量子计算的过程中,使用与表示量子的两种基本状态,称其为量子比特。量子比特的各种状态,用下式表示:

其中,α与β为一复数,称之为概率幅,且α与β满足

其等效于

量子状态又可表示为:

量子遗传算法将染色体上的基因用量子比特表示,从而增加种群多样性。随机生成m个染色体,每个染色体上的基因用量子比特表示,且初始化为。 

2.2 在量子遗传算法中,染色体采用量子位的概率幅进行编码,编码方案如下:

神奇的量子世界——量子遗传算法(Python&Matlab实现)_第4张图片

Pi为第i个基因,为量子比特的相位,n为染色体数目,k为量子位的位数即解空间的维数,rand是[0,1]范围内的随机数。每个量子位为分上下两行,分别对应两个量子基本态的概率幅,满足归一化条件,因此每个个体包含上下两条文化基因链,每条基因链是优化问题的一个候选解。由此可知,量子遗传算法在种群规模不变的情况下,候选解个数比遗传算法多一倍,增加了解空间的多样性,提高了寻优成功的概率。

2.3 对初始化种群中的每一个个体进行测量。

随机生成一个数x∈[0,1],若

则测量值取1,否则取0。

2.4 对每个测量值进行适应度的评估,以适应度来选择最优个体,进行遗传变异。

2.5 使用量子旋转门进行下一代个体的更新,量子旋转门为逻辑门中一种较为常用的方法,具体表示为:

为量子旋转的角度,则量子比特的更新表示为: 

2.6 进行迭代,y=y+1

2.7 达到终止设定条件,输出最佳个体,得到最优解。

3 流程图

神奇的量子世界——量子遗传算法(Python&Matlab实现)_第5张图片

4 量子遗传算法——Python实现 

4.1 数据

4.2 代码 

# -*- coding: utf-8 -*-

#==========导入包============
import numpy as np
from sklearn import svm #SVM是二分类器
from sklearn import cross_validation #交叉验证(Cross Validation)用来验证分类器的性能一种统计分析方法
import random
import math
import matplotlib.pyplot as plt

#=======1.导入训练数据========
def load_data(data_file):
    '''
    input:  data_file(string):训练数据所在文件
    output: data(mat):训练样本的特征
            label(mat):训练样本的标签
    '''
    data = []
    label = []
    f = open(data_file)
    for line in f.readlines():
        lines = line.strip().split(' ')
        
        #===提取得出label===
        label.append(float(lines[0]))
        #==提取出特征,并将其放入到矩阵中===
        index = 0
        tmp = []
        for i in range(1, len(lines)):
            li = lines[i].strip().split(":")
            if int(li[0]) - 1 == index:
                tmp.append(float(li[1]))
            else:
                while(int(li[0]) - 1 > index):
                    tmp.append(0)
                    index += 1
                tmp.append(float(li[1]))
            index += 1
        while len(tmp) < 13:
            tmp.append(0)
        data.append(tmp)
    f.close()
    return np.array(data), np.array(label).T

#===============================2. QGA算法=================================================
class QGA(object):
#====2.1 类初始化======
    '''定义QGA类
    '''
    def __init__(self,population_size,chromosome_num,chromosome_length,max_value,min_value,iter_num,deta):
        '''初始化类参数
        population_size(int):种群数
        chromosome_num(int):染色体数,对应需要寻优的参数个数
        chromosome_length(int):染色体长度
        max_value(float):染色体十进制数值最大值
        min_value(float):染色体十进制数值最小值
        iter_num(int):迭代次数
        deta(float):量子旋转角度        
        '''
        self.population_size = population_size
        self.chromosome_num = chromosome_num
        self.chromosome_length = chromosome_length
        self.max_value = max_value
        self.min_value = min_value
        self.iter_num = iter_num
        self.deta = deta 
        
    #======2.2 种群的量子形式初始化=================
    def species_origin_angle(self):
        '''种群初始化
        input:self(object):QGA类
        output:population_Angle(list):种群的量子角度列表
               population_Angle2(list):空的种群的量子角度列表,用于存储交叉后的量子角度列表
               
        '''
        population_Angle = []
       
        for i in range(self.chromosome_num):
            tmp1 = [] #存储每个染色体所有取值的量子角度
            for j in range(self.population_size): 
                tmp2 = [] #存储量子角度
                for m in range(self.chromosome_length):
                    a = np.pi * 2 * np.random.random()
                    tmp2.append(a)
                tmp1.append(tmp2)
            population_Angle.append(tmp1)
        return  population_Angle

    #======将初始化的量子角度序列转换为种群的量子系数列表======
    def population_Q(self,population_Angle):
        '''
        input:self(object):QGA类
              population_Angle(list):种群的量子角度列表
        output:population_Q(list):种群的量子系数列表
        '''
        population_Q = []
       
        for i in range(len(population_Angle)):
            tmp1 = [] #存储每个染色体所有取值的量子系数对
            for j in range(len(population_Angle[i])): 
                tmp2 = [] #存储每个染色体的每个取值的量子对
                tmp3 = [] #存储量子对的一半
                tmp4 = [] #存储量子对的另一半
                for m in range(len(population_Angle[i][j])):
                    a = population_Angle[i][j][m]
                    tmp3.append(np.sin(a))
                    tmp4.append(np.cos(a))
                tmp2.append(tmp3)
                tmp2.append(tmp4)
                tmp1.append(tmp2)
            population_Q.append(tmp1)
        return population_Q     

    #2.3====计算适应度函数值==============
    def translation(self,population_Q):
        '''将种群的量子列表转换为二进制列表
        input:self(object):QGA类
              population_Q(list):种群的量子列表
        output:population_Binary:种群的二进制列表
        '''
        population_Binary = []
        for i in range(len(population_Q)):
            tmp1 = [] # 存储每个染色体所有取值的二进制形式
            for j in range(len(population_Q[i])):
                tmp2 = [] ##存储每个染色体每个取值的二进制形式
                for l in range(len(population_Q[i][j][0])):
                    if np.square(population_Q[i][j][0][l]) > np.random.random():
                        tmp2.append(1)
                    else:
                        tmp2.append(0)
                tmp1.append(tmp2)
            population_Binary.append(tmp1)
        return population_Binary

    #===求适应度函数数值列表,本实验采用的适应度函数为RBF_SVM的3_fold交叉验证平均值===
    def fitness(self,population_Binary):
        '''
        input:self(object):QGA类
              population_Binary(list):种群的二进制列表
        output:fitness_value(list):适应度函数值类表
               parameters(list):对应寻优参数的列表
        '''
        #===(1)染色体的二进制表现形式转换为十进制并设置在[min_value,max_value]之间===
        parameters = [] #存储所有参数的可能取值
        for i in range(len(population_Binary)):
            tmp1 = []  #存储一个参数的可能取值
            for j in range(len(population_Binary[i])):
                total = 0.0
                for l in range(len(population_Binary[i][j])):
                    total += population_Binary[i][j][l] * math.pow(2,l)  #计算二进制对应的十进制数值
                value = (total * (self.max_value - self.min_value)) / math.pow(2,len(population_Binary[i][j])) + self.min_value ##将十进制数值坐落在[min_value,max_value]之间
                tmp1.append(value)
            parameters.append(tmp1)
        
        #====(2)适应度函数为RBF_SVM的3_fold交叉校验平均值=========
        fitness_value = []
        for l in range(len(parameters[0])):
            rbf_svm = svm.SVC(kernel = 'rbf', C = parameters[0][l], gamma = parameters[1][l])
            cv_scores = cross_validation.cross_val_score(rbf_svm,trainX,trainY,cv =3,scoring = 'accuracy')
            fitness_value.append(cv_scores.mean())
            
        #=====(3)找到最优的适应度函数值和对应的参数二进制表现形式======
        best_fitness = 0.0
        
        best_parameter = []        
        best_parameter_Binary = []
        for j in range(len(population_Binary)):
            tmp2 = []
            best_parameter_Binary.append(tmp2) 
            best_parameter.append(tmp2)
            
        for i in range(len(population_Binary[0])):
            if best_fitness < fitness_value[i]:
                best_fitness = fitness_value[i]
                for j in range(len(population_Binary)):
                    best_parameter_Binary[j] = population_Binary[j][i]
                    best_parameter[j] = parameters[j][i]
        
        return parameters,fitness_value,best_parameter_Binary,best_fitness,best_parameter
        
    #============2.4 全干扰交叉===============
    def crossover(self,population_Angle):
        '''对种群量子角度列表进行全干扰交叉
        input:self(object):QGA类
              population_Angle(list):种群的量子角度列表
        '''
        #===初始化一个空列表,全干扰交叉后的量子角度列表==
        population_Angle_crossover = []
       
        for i in range(self.chromosome_num):
            tmp11 = []                    
            for j in range(self.population_size): 
                tmp21 = []                             
                for m in range(self.chromosome_length):
                    tmp21.append(0.0)
                tmp11.append(tmp21)
            population_Angle_crossover.append(tmp11)
        

        for i in range(len(population_Angle)):
            for j in range(len(population_Angle[i])):
                for m in range(len(population_Angle[i][j])):
                    ni = (j - m) % len(population_Angle[i])
                    population_Angle_crossover[i][j][m] = population_Angle[i][ni][m]
        return population_Angle_crossover

    #============2.4 变异==================
    def mutation(self,population_Angle_crossover,population_Angle,best_parameter_Binary,best_fitness):
        '''采用量子门变换矩阵进行量子变异
        input:self(object):QGA类
              population_Angle_crossover(list):全干扰交叉后的量子角度列表
        output:population_Angle_mutation(list):变异后的量子角度列表
        '''
        #==(1)求出交叉后的适应度函数值列表=======
        population_Q_crossover = self.population_Q(population_Angle_crossover)  ## 交叉后的种群量子系数列表
        population_Binary_crossover = self.translation(population_Q_crossover)  ## 交叉后的种群二进制数列表
        parameters,fitness_crossover,best_parameter_Binary_crossover,best_fitness_crossover,best_parameter = self.fitness(population_Binary_crossover)           ## 交叉后的适应度函数值列表
        #==(2)初始化每一个量子位的旋转角度====
        Rotation_Angle = []
        for i in range(len(population_Angle_crossover)):
            tmp1 = []
            for j in range(len(population_Angle_crossover[i])):
                tmp2 = []
                for m in range(len(population_Angle_crossover[i][j])):
                    tmp2.append(0.0)
                tmp1.append(tmp2)
            Rotation_Angle.append(tmp1)
            
        deta = self.deta

        #====(3)求每个量子位的旋转角度========
        for i in range(self.chromosome_num):
            for j in range(self.population_size):
                if fitness_crossover[j] <= best_fitness:
                    for m in range(self.chromosome_length):
                        s1 = 0
                        a1 = population_Q_crossover[i][j][0][m]
                        b1 = population_Q_crossover[i][j][1][m]
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 0 and a1 * b1 > 0:
                            s1 = -1
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 0 and a1 * b1 < 0:
                            s1 = 1
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 0 and a1 * b1 == 0:
                            s1 = 1
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 1 and a1 * b1 < 0:
                            s1 = -1
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 1 and a1 * b1 == 0:
                            s1 = 1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 0 and a1 * b1 > 0:
                            s1 = -1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 0 and a1 * b1 < 0:
                            s1 = 1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 0 and a1 * b1 == 0:
                            s1 = -1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 1 and a1 * b1 > 0:
                            s1 = 1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 1 and a1 * b1 < 0:
                            s1 = -1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 1 and a1 * b1 == 0:
                            s1 = 1
                        Rotation_Angle[i][j][m] = deta * s1
                else:
                    for m in range(self.chromosome_length):
                        s2 = 0
                        a2 = population_Q_crossover[i][j][0][m]
                        b2 = population_Q_crossover[i][j][1][m]
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 0 and a2 * b2 > 0:
                            s2 = -1
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 0 and a2 * b2 < 0:
                            s2 = 1
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 0 and a2 * b2 == 0:
                            s2 = 1
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 1 and a2 * b2 > 0:
                            s2 = -1
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 1 and a2 * b2 < 0:
                            s2 = 1
                        if population_Binary_crossover[i][j][m] == 0 and best_parameter_Binary[i][m] == 1 and a2 * b2 == 0:
                            s2 = 1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 0 and a2 * b2 > 0:
                            s2 = 1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 0 and a2 * b2 < 0:
                            s2 = -1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 0 and a2 * b2 == 0:
                            s2 = 1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 1 and a2 * b2 > 0:
                            s2 = 1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 1 and a2 * b2 < 0:
                            s2 = -1
                        if population_Binary_crossover[i][j][m] == 1 and best_parameter_Binary[i][m] == 1 and a2 * b2 == 0:
                            s2 = 1
                        Rotation_Angle[i][j][m] = deta * s2
        
        #=======(4)根据每个量子位的旋转角度,生成种群新的量子角度列表===============
        
        for i in range(self.chromosome_num):
            for j in range(self.population_size):
                for m in range(self.chromosome_length):
                    population_Angle[i][j][m] = population_Angle[i][j][m] + Rotation_Angle[i][j][m]
                    
        return population_Angle
                        
    #======2.5 画出适应度函数值变化图======
    def plot(self,results):
        '''
        画图
        '''
        X = []
        Y = []
        for i in range(self.iter_num):
            X.append(i + 1)
            Y.append(results[i])
        plt.plot(X,Y)
        plt.xlabel('Number of iteration',size = 15)
        plt.ylabel('Value of CV',size = 15)
        plt.title('QGA_RBF_SVM parameter optimization')
        plt.show()  

    #===========2.6 主函数================
    def main(self):
        results = []
        best_fitness = 0.0
        best_parameter = []
        #===种群初始化===
        population_Angle= self.species_origin_angle()        
        #===迭代====
        for i in range(self.iter_num):
            population_Q = self.population_Q(population_Angle)
           
            ## 计算本次迭代的适应度函数值列表,最优适应度函数值及对应的参数
            parameters,fitness_value,current_parameter_Binary,current_fitness,current_parameter = self.fitness(population_Binary)
            ## 找出到目前为止最优的适应度函数值和对应的参数
            if current_fitness > best_fitness:
                best_fitness = current_fitness
                best_parameter = current_parameter
            print('iteration is :',i+1,';Best parameters:',best_parameter,';Best fitness',best_fitness)
            results.append(best_fitness)
            
            ## 全干扰交叉
            population_Angle_crossover = self.crossover(population_Angle)
            ## 量子旋转变异
            population_Angle = self.mutation(population_Angle_crossover,population_Angle,current_parameter_Binary,current_fitness)
        

if __name__ == '__main__':
    print('----------------1.Load Data-------------------')
    trainX,trainY = load_data('rbf_data')
    print('----------------2.Parameter Seting------------')
    population_size=200
    chromosome_num=2
    chromosome_length=20
    max_value=15
    min_value=0.01
    iter_num=100
    deta=0.1 * np.pi
    print('----------------3.QGA_RBF_SVM-----------------')
    qga = QGA(population_size,chromosome_num,chromosome_length,max_value,min_value,iter_num,deta)
    qga.main()
   

4.3 结果 

神奇的量子世界——量子遗传算法(Python&Matlab实现)_第6张图片

5 量子遗传算法——Matlab实现 

clear,clc
%% 1基本概念
%(1)量子遗传算法是量子计算与遗传算法相结合的智能优化算法,由K.H.Han等人提出,其将量子态、量子门、量子状态特性、概率幅等量子概念引入到遗传算法当中。
      %量子遗传算法也是一种概率搜素算法,它采用量子位来表示基因。遗传算法的基因所表达的是某一确定的信息,而量子遗传算法中,由于量子信息的叠加性使量子位所表达的基因包含所有可能的信息。
%(2)在量子计算中,量子比特|0〉和|1〉表示微观粒子的两种基本状态,根据叠加原理,量子信息的叠加态可以表示为这两个基本态的线性组合,即|ψ〉=α|0〉+β|1〉,式中α和β为复数,表示量子位状态的概率幅,其中和分别表示量子态|ψ〉因测量导致坍缩到|0〉态和|1〉态的概率,且满足的归一化条件
%(3)在量子遗传算法中,染色体采用量子位的概率幅进行编码,编码方案如下:
%θ为量子比特的相位,n为染色体数目,k为量子位的位数即解空间的维数,rand是[0,1]范围内的随机数。每个量子位为分上下两行,分别对应两个量子基本态的概率幅,满足归一化条件,因此每个个体包含上下两条文化基因链,每条基因链是优化问题的一个候选解。由此可知,量子遗传算法在种群规模不变的情况下,候选解个数比遗传算法多一倍,增加了解空间的多样性,提高了寻优成功的概率。
%(4)在量子遗传算法中,采用量子旋转门改变量子比特相位,以更新量子位的概率幅,从而达到基因变异的效果。
%% 2、量子遗传算法的基本步骤:
%step1:初始化父代染色体
%step2:对每个染色体基因位即量子位进行测量,得到一个状态。对每个状态计算适应度,记录最佳个体及适应度。
%step3:遗传进化设定的代数,其中采用量子旋转门对每一代染色体进行遗传变异。
%step4:达到终止条件,输出最佳个体及适应度。
%% 3、量子遗传算法的MATLAB实现代码如下
%% 变量部分              
popsize = 100;        %种群规模                                
vartotal = 2;         %变量个数即一条染色体的量子位数            
shiftstep = 0.01*pi; %转角步长  
Pm = ones(1,popsize)*0.05;%设置变异概率  
maxgen = 200;  %设置迭代次数  
%% 数组部分--解空间的优化变量的取值范围
var_range(1,1) = -100;      
var_range(1,2) = 100;      
var_range(2,1) = -100;    
var_range(2,2) = 100;       
%% 个体初始化
%初始化了2*popsize个体,其中每个个体有两条基因链  
for i=1:1:vartotal  
  fai(:,i)=2*pi*rand(popsize,1);   
  chrom(:,1,i)=cos(fai(:,i));  
  chrom(:,2,i)=sin(fai(:,i));  
  oldfai(:,i)=2*pi*rand(popsize,1);   
  oldchrom(:,1,i)=cos(oldfai(:,i));  
  oldchrom(:,2,i)=sin(oldfai(:,i));  
end  
%% 解空间变换  
for i=1:1:2   
  for j=1:1:vartotal  
        chromx(:,i,j)=0.5*(var_range(j,2)*(1+chrom(:,i,j))+var_range(j,1)*(1-chrom(:,i,j)));  
        oldchromx(:,i,j)=0.5*(var_range(j,2)*(1+oldchrom(:,i,j))+var_range(j,1)*(1-oldchrom(:,i,j)));  
  end  
end  
%% 计算适应度---适应度函数:Shaffer's F6函数
for i=1:1:popsize  
  for j=1:1:2  
        x1=chromx(i,j,1);  
        x2=chromx(i,j,2);  
        fitness(i,j)=0.5-((sin(sqrt(x1^2+x2^2)))^2-0.5)/(1+0.001*(x1^2+x2^2))^2;  
        x1=oldchromx(i,j,1);  
        x2=oldchromx(i,j,2);  
        oldfitness(i,j)=0.5-((sin(sqrt(x1^2+x2^2)))^2-0.5)/(1+0.001*(x1^2+x2^2))^2;  
  end  
end  
%% 获得最优解及相应自变量  
[Bestf,Indexf]=sort(fitness,2);  
[BestF,IndexF]=sort(Bestf,1);  
gBestfit=BestF(popsize,2);   
gBestpop=IndexF(popsize,2);   
gBestg=Indexf(gBestpop,2);    
gBestfai=fai(gBestpop,:);    
gBestC=chrom(gBestpop,:,:);  
gBest_x=chromx(gBestpop,:,:);  
gBest_fit=fitness(gBestpop,:);  
%% 主循环开始
for gen = 1:1:maxgen     
  for i = 1:1:vartotal   
        tmp=abs(chromx(1,gBestg,i)-oldchromx(1,gBestg,i));  
        if tmp<1.0e-2  
            tmp=1.0e-2;  
        end  
        max(i)=abs(fitness(1,gBestg)-oldfitness(1,gBestg))/tmp;  
        min(i)=abs(fitness(1,gBestg)-oldfitness(1,gBestg))/tmp; 
        for j = 1:1:popsize  
            tmp=abs(chromx(j,gBestg,i)-oldchromx(j,gBestg,i));   
            if tmp<1.0e-2  
                tmp=1.0e-2;  
            end  
            if max(i)<=abs(fitness(j,gBestg)-oldfitness(j,gBestg))/tmp  
                max(i)=abs(fitness(j,gBestg)-oldfitness(j,gBestg))/tmp;  
            end  
            if min(i)>abs(fitness(j,gBestg)-oldfitness(j,gBestg))/tmp  
              min(i)=abs(fitness(j,gBestg)-oldfitness(j,gBestg))/tmp;  
            end  
        end  
    end  
    %% 执行量子位相位旋转,得到新的相位 
    for i=1:1:popsize  
        for j = 1:1:vartotal  
            tmp=abs(chromx(i,gBestg,j)-oldchromx(i,gBestg,j));  
            if tmp<1.0e-2  
                tmp=1.0e-2;  
            end
            grad=abs(fitness(i,gBestg)-oldfitness(i,gBestg))/tmp;
            tmp=abs(grad-min(j));
            if tmp<1.0e-2
                tmp=1.0e-2;
            end
            rate(i,j)=tmp/abs(max(j)-min(j)); 
            if max(j)-min(j)==0
                rate(i,j)=1;
            end
            fai(i,j)=fai(i,j)+sign(chrom(i,1,j)*gBestC(1,2,j)-gBestC(1,1,j)*chrom(i,2,j))*(1-rate(i,j))*shiftstep*exp(-gen/maxgen);          
        end  
    end  
    %% 执行量子位相位变异 
    Pm_rand = rand(popsize,vartotal);%生成随机数,与变异概率比较,决定是否变异  
    for i=1:1:popsize  
        for j=1:1:vartotal  
            if (Pm(i)>Pm_rand(i,j))&&(i==gBestpop)  
                fai(i,j)=0.5*pi-fai(i,j);  
            end  
        end  
    end  
    %% 代间复制---保存的是相邻两代
    oldchrom=chrom;  
    oldchromx=chromx;  
    oldfitness=fitness;  
    %% 生成新的量子个体
    chrom(:,1,:)=cos(fai(:,:));  
    chrom(:,2,:)=sin(fai(:,:));  
    %% 解空间变换  
    for i=1:1:2  
        for j=1:1:vartotal  
            chromx(:,i,j)=0.5*(var_range(j,2)*(1+chrom(:,i,j))+var_range(j,1)*(1-chrom(:,i,j)));  
        end  
    end  
    %% 计算适应度---适应度函数:Shaffer's F6函数
    for i=1:1:popsize  
        for j=1:1:2  
            x1=chromx(i,j,1);  
            x2=chromx(i,j,2);  
            fitness(i,j)=0.5-((sin(sqrt(x1^2+x2^2)))^2-0.5)/(1+0.001*(x1^2+x2^2))^2;  
        end  
    end  
    %% 获得最优解及相应自变量 
    [Bestf,Indexf]=sort(fitness,2);  
    [BestF,IndexF]=sort(Bestf,1);  
    Bestfit=BestF(popsize,2);    
    Bestpop=IndexF(popsize,2);  
    Bestg=Indexf(Bestpop,2);    
    Bestfai=fai(Bestpop,:);    
    BestC=chrom(Bestpop,:,:);   
    Best_x=chromx(Bestpop,:,:);  
    Best_fit=fitness(Bestpop,:);  
    Badpop=IndexF(1,1);   
    %% 若最优解退化则取回上代最优解  
    if Bestfit=gBestfit  
        gBestfit=Bestfit;    
        gBestpop=Bestpop;   
        gBestg=Bestg;   
        gBestfai=Bestfai;    
        gBestC=BestC;   
        gBest_x=Best_x;  
        gBest_fit=Best_fit;  
    end  
    %---------------------记录优化结果---------------------  
    result(gen)=gBestfit;  
end
%% 主循环结束 
bestresult=result(gen)  

figure(1)  
plot(1:maxgen,result)  
xlabel('迭代次数')
ylabel('函数值')

神奇的量子世界——量子遗传算法(Python&Matlab实现)_第7张图片 

           神奇的量子世界——量子遗传算法(Python&Matlab实现)_第8张图片

你可能感兴趣的:(#,神奇的量子世界,#,智能优化算法,matlab,python,开发语言)