(转载)基于量子遗传算法的函数寻优算法

news2024/7/6 18:16:20

8.1 理论基础

8.1.1 量子遗传算法概述

        量子遗传算法(quantum genetic algorithm,QGA)是量子计算与遗传算法相结合的产物,是一种新发展起来的概率进化算法。遗传算法是处理复杂优化问题的一种方法,其基本思想是模拟生物进化的优胜劣汰规则与染色体的交换机制,通过选择、交叉、变异三种基本操作寻找最优个体。由于GA不受问题性质、优化准则形式等因素的限制,仅用目标函数在概率引导下进行全局自适应搜索,能够处理传统优化方法难以解决的复杂问题,具有极高鲁棒性和广泛适用性,因而得到了广泛应用并成为跨学科研究的热点。但是,若选择、交叉、变异的方式不当,GA会表现出迭代次数多、收敛速度慢、易陷入局部极值的现象。
        量子计算中采用量子态作为基本的信息单元,利用量子态的叠加、纠缠和干涉等特性,通过量子并行计算可以解决经典计算中的NP问题。1994年Shor提出第一个量子算法,求解了大数质因子分解的经典计算难题,该算法可用于公开密钥系统RSA;1996年Grover提出随机数据库搜索的量子算法,在量子计算机上可实现对未加整理的数据库√N量级的加速搜索,量子计算正以其独特的计算性能迅速成为研究的热点。
        量子遗传算法就是基于量子计算原理的一种遗传算法。将量子的态矢量表达引入遗传编码,利用量子逻辑门实现染色体的演化,实现了比常规遗传算法更好的效果。量子遗传算法建立在量子的态矢量表示的基础之上,将量子比特的几率幅表示应用于染色体的编码,使得一条染色体可以表达多个态的叠加,并利用量子逻辑门实现染色体的更新操作,从而实现了目标的优化求解。

8.1.2 量子比特编码

        在量子计算机中,充当信息存储单元的物理介质是一个双态量子系统,称为量子比特。量子比特与经典位不同就在于它可以同时处在两个量子态的叠加态中,比如:
        在量子遗传算法中,采用量子比特存储和表达一个基因。该基因可以为“0”态或“1”态,或它们的任意叠加态。即该基因所表达的不再是某一确定的信息,而是包含所有可能的信息,对该基因的任一操作也会同时作用于所有可能的信息。
        采用量子比特编码使得一个染色体可以同时表达多个态的叠加,使得量子遗传算法比经典遗传算法拥有更好的多样性特征。采用量子比特编码也可以获得较好的收敛性,随着|α|²或|β|²趋于0或1,量子比特编码的染色体将收敛到一个单一态。

8.1.3 量子门更新

        量子门作为演化操作的执行机构,可根据具体问题进行选择,目前已有的量子门有很多种,根据量子遗传算法的计算特点,选择量子旋转门较为合适。量子旋转门的调整操作为

 

8.2 案例背景

8.2.1 问题描述

        复杂二元函数求最值

 

 matlab代码及该函数的图形如下。

x = linspace(0, 12.1, 200);
y = linspace(4.1, 5.8, 200);
[x, y] = meshgrid(x,y);
f = 21.5+x.*sin(4*pi*x)+y.*sin(20*pi*y);
 
figure;
surf(x,y,f);
colormap(gca, 'jet')
xlabel('x');
ylabel('y');
zlabel('f(x,y)');
title('函数图像')

        从图8-1中可以看出,该非线性函数在给定范围内分布着许多局部极值,通常的寻优算法极易陷入局部极值或在各局部极值间振荡,比较适用于验证量子遗传算法的性能。

8.2.2 解题思路及步骤

        1.量子遗传算法流程
        量子遗传算法的算法流程如下:
        (1)初始化种群Q(t0),随机生成n个以量子比特为编码的染色体;
        (2)对初始种群Q(t0)中的每个个体进行一次测量,得到对应的确定解P(t0);
        (3)对各确定解进行适应度评估;
        (4)记录最优个体和对应的适应度;
        (5)判断计算过程是否可以结束,若满足结束条件则退出,否则继续计算;
        (6)对种群Q(t)中的每个个体实施一次测量,得到相应的确定解;
        (7)对各确定解进行适应度评估;
        (8)利用量子旋转门U(t)对个体实施调整,得到新的种群Q(t+1);
        (9)记录最优个体和对应的适应度;
        (10)将迭代次数t加1,返回步骤(5)。
        对应的流程图如图8-2所示。

 

        随后,算法进入循环迭代阶段,随着迭代的进行,种群的解逐渐向最优解收敛。在每一次迭代中,首先对种群进行测量,以获得一组确定解P(t),然后计算每个解的适应度值,再根据当前的演化目标和事先确定的调整策略,利用量子旋转门对种群中的个体进行调整,获得更新后的种群,记录下当前的最优解,并与当前的目标值进行比较,如果大于当前目标值,则以新的最优解作为下一次迭代的目标值,否则保持当前的目标值不变。
2.量子遗传算法实现
(1)量子比特编码
        采用遗传算法中的二进制编码,对存在多态的问题进行量子比特编码,如两态用一个量子比特进行编码,四态用两个量子比特进行编码。该方法的优点是通用性好,且实现简单。采用多量子比特编码m个参数的基因如下:
(2)量子旋转门
        量子遗传算法中,旋转门是最终实现演化操作的执行机构。这里使用一种通用的、与问题无关的调整策略,如表8-1所列。

8.3 MATLAB程序实现

8.3.1 种群初始化

        种群初始化函数InitPop,得到初始种群的量子比特编码矩阵chrom。
function chrom=InitPop(M,N)
%% 初始化种群-量子比特编码
% M:为种群大小×2,(α和β)
% N:为量子比特编码长度
for i=1:M
    for j=1:N
        chrom(i,j)=1/sqrt(2);
    end
end

8.3.2 测量函数

        对种群实施一次测量,得到二进制编码,函数名为collapse。
function binary=collapse(chrom)
%% 对种群实施一次测量 得到二进制编码
% 输入chrom :为量子比特编码
% 输出binary:二进制编码
[M,N]=size(chrom);  %得到种群大小 和编码长度
M=M/2;  % 种群大小
binary=zeros(M,N);  %二进制编码大小初始化
for i=1:M
    for j=1:N
        pick=rand;  %产生【0,1】随机数
        if pick>(chrom(2.*i-1,j)^2)    % 随机数大于α的平方
            binary(i,j)=1;
        else
            binary(i,j)=0;
        end
    end
end

8.3.3 量子旋转门函数

        旋转门是最终实现演化操作的执行机构,量子旋转门函数为Qgate。
function chrom=Qgate(chrom,fitness,best,binary)
%% 量子旋转门调整策略
% 输入  chrom:更新前的量子比特编码
%     fitness:适应度值
%        best:当前种群中最优个体
%      binary:二进制编码
% 输出  chrom:更新后的量子比特编码
sizepop=size(chrom,1)/2;
lenchrom=size(binary,2);
for i=1:sizepop
    for j=1:lenchrom
        A=chrom(2*i-1,j);   % α
        B=chrom(2*i,j);     % β
        x=binary(i,j);
        b=best.binary(j);
        if ((x==0)&(b==0))||((x==1)&(b==1))
            delta=0;                  % delta为旋转角的大小
            s=0;                        % s为旋转角的符号,即旋转方向
        elseif (x==0)&(b==1)&(fitness(i)<best.fitness)
            delta=0.01*pi;
            if A*B>0
                s=1;
            elseif A*B<0
                s=-1;
            elseif A==0
                s=0;
            elseif B==0
                s=sign(randn);
            end
        elseif (x==0)&(b==1)&(fitness(i)>=best.fitness)
            delta=0.01*pi;
            if A*B>0
                s=-1;
            elseif A*B<0
                s=1;
            elseif A==0
                s=sign(randn);
            elseif B==0
                s=0;
            end
        elseif (x==1)&(b==0)&(fitness(i)<best.fitness)
            delta=0.01*pi;
            if A*B>0
                s=-1;
            elseif A*B<0
                s=1;
            elseif A==0
                s=sign(randn);
            elseif B==0
                s=0;
            end
        elseif (x==1)&(b==0)&(fitness(i)>=best.fitness)
            delta=0.01*pi;
            if A*B>0
                s=1;
            elseif A*B<0
                s=-1;
            elseif A==0
                s=0;
            elseif B==0
                s=sign(randn);
            end
        end
        e=s*delta;       % e为旋转角
        U=[cos(e) -sin(e);sin(e) cos(e)];      % 量子旋转门
        y=U*[A B]';        % y为更新后的量子位
        chrom(2*i-1,j)=y(1);
        chrom(2*i,j)=y(2);
    end
end

8.3.4 适应度函数

        这里以求解最大值问题为例进行说明,如果是求解最小值问题,可以转变成求最大值问题(加个负号即可),目标值越大的个体,其适应度值也应该越大,所以可以直接将所优化的目标 函数作为适应度函数。适应度主函数FitnessFunction的代码:
function [fitness,X]=FitnessFunction(binary,lenchrom)
%% 适应度函数
% 输入  binary:二进制编码
%     lenchrom:各变量的二进制位数
% 输出 fitness:适应度
%            X:十进制数(待优化参数)
sizepop=size(binary,1);
fitness=zeros(1,sizepop);
num=size(lenchrom,2);
X=zeros(sizepop,num);
for i=1:sizepop
    [fitness(i),X(i,:)]=Objfunction(binary(i,:),lenchrom);         % 使用目标函数计算适应度
end
        其中,函数Objfunction是待优化的目标函数,这里以8.2.1节中的函数为例进行说明。函数Objfunction的代码:
function [Y,X]=Objfunction(x,lenchrom)
%% 目标函数
% 输入     x:二进制编码
%   lenchrom:各变量的二进制位数
% 输出     Y:目标值
%          X:十进制数
bound=[-3.0 12.1;4.1 5.8];   % 函数自变量的范围
%% 将binary数组转化成十进制数组
X=bin2decFun(x,lenchrom,bound);
%% 计算适应度-函数值
Y=sin(4*pi*X(1))*X(1)+sin(20*pi*X(2))*X(2);
        其中,函数bin2decFun是将二进制编码转换成十进制数,其代码如下:
function X=bin2decFun(x,lenchrom,bound)
%% 二进制转化成十进制
% 输入      x:二进制编码
%    lenchrom:各变量的二进制位数
%       bound:各变量的范围
% 输出      X:十进制数
M=length(lenchrom);
n=1;
X=zeros(1,M);
for i=1:M
    for j=lenchrom(i)-1:-1:0
        X(i)=X(i)+x(n).*2.^j;
        n=n+1;
    end
end
X=bound(:,1)'+X./(2.^lenchrom-1).*(bound(:,2)-bound(:,1))'; 

8.3.5 量子遗传算法主函数

        量子遗传算法主函数代码如下:
clc;
clear all;
close all;
%----------------参数设置-----------------------
MAXGEN=200;                        % 最大遗传代数
sizepop=40;                        % 种群大小
lenchrom=[20 20];          % 每个变量的二进制长度
trace=zeros(1,MAXGEN);
%--------------------------------------------------------------------------      
best=struct('fitness',0,'X',[],'binary',[],'chrom',[]);   % 最佳个体 记录其适应度值、十进制值、二进制编码、量子比特编码
%% 初始化种群
chrom=InitPop(sizepop*2,sum(lenchrom));
%% 对种群实施一次测量 得到二进制编码
binary=collapse(chrom); 
%% 求种群个体的适应度值,和对应的十进制值
[fitness,X]=FitnessFunction(binary,lenchrom);         % 使用目标函数计算适应度
%% 记录最佳个体到best
[best.fitness bestindex]=max(fitness);     % 找出最大值
best.binary=binary(bestindex,:);
best.chrom=chrom([2*bestindex-1:2*bestindex],:);
best.X=X(bestindex,:);
trace(1)=best.fitness;
fprintf('%d\n',1)
%% 进化
for gen=2:MAXGEN
    fprintf('%d\n',gen)  %提示进化代数
    %% 对种群实施一次测量
    binary=collapse(chrom);
    %% 计算适应度
    [fitness,X]=FitnessFunction(binary,lenchrom);
    %% 量子旋转门
    chrom=Qgate(chrom,fitness,best,binary);
    [newbestfitness,newbestindex]=max(fitness);    % 找到最佳值
    % 记录最佳个体到best
    if newbestfitness>best.fitness
        best.fitness=newbestfitness;
        best.binary=binary(newbestindex,:);
        best.chrom=chrom([2*newbestindex-1:2*newbestindex],:);
        best.X=X(newbestindex,:);
    end
    trace(gen)=best.fitness;
end

%% 画进化曲线
plot(1:MAXGEN,trace);
title('进化过程');
xlabel('进化代数');
ylabel('每代的最佳适应度');

%% 显示优化结果
disp(['最优解X:',num2str(best.X)])
disp(['最大值Y:',num2str(best.fitness)]);

8.4 结果分析

       优化结果如下所示:

  

        本例是针对8.2.1节中的案例进行编写的,用户可以根据自己的实际问题修改函数Objfunction(待优化的问题也并不局限在函数优化,可以是一个复杂的运算过程),再简单修改下
主函数中的相应变量设置即可。

8.5 延伸阅读

        前面使用的是未改进的量子遗传算法,该算法可以做些改进:

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/575688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

结构型设计模式02-代理模式

✨作者&#xff1a;猫十二懿 ❤️‍&#x1f525;账号&#xff1a;CSDN 、掘金 、个人博客 、Github &#x1f389;公众号&#xff1a;猫十二懿 代理模式 1、不使用代理模式 举例说明&#xff1a;小明喜欢一个女生&#xff08;小红&#xff09;&#xff0c;因为小红不认识小明…

【数据结构】初步了解排序

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 1.排序的概念及其运用 1.1排序的概念 2.常见排序算法的实现 2.1插入排序 2.2希尔排序 问题:gap是多少合适&#xff1f; 1.排序的概念及其运用 1.1排序的概念 排序&#xff1a;所…

App上架流程

准备 开发者账号完工的项目 上架步骤 一、创建App ID二、创建证书请求文件 &#xff08;CSR文件&#xff09;三、创建发布证书 &#xff08;CER&#xff09;四、创建Provisioning Profiles配置文件 &#xff08;PP文件&#xff09;五、在App Store创建应用六、打包上架 一、…

设置linux的时间

目录 一、什么是时间 &#xff08;1&#xff09;例子1 &#xff08;2&#xff09;例子2 二、什么是本地时间 三、linux设置本地时间的方法 &#xff08;1&#xff09;方式一&#xff1a;通过互联网自动同步 1.修改时间同步服务器 2.查看时间同步情况 &#xff08;2&…

自动化测试1

目录 1.什么是自动化测试 1.1自动化分类 1.1单元测试 1.2接口测试 1.3UI自动化测试 2.selenium 1.什么是selenium 2.selenium的特点 3.工作原理 3.seleniumJava 1.搭建 1.查看Chrome版本 2.下载Chrome浏览器驱动 3.配置,放到该目录下 2.验证是否搭建成功 1.什么是…

springboot 集成jwt的使用

1.JWT介绍 JWT&#xff08;JSON Web Token&#xff09;是一种基于JSON格式的身份验证和授权标准&#xff0c;经常用于Web应用程序中的用户身份验证。JWT由三个部分组成&#xff1a;头部、载荷和签名。头部包含算法和类型信息&#xff0c;载荷包含用户数据和元数据&#xff0c;…

tolua源码分析(六) C#委托使用lua函数的机制实现

tolua源码分析&#xff08;六&#xff09; C#委托使用lua函数的机制实现 上一节我们讨论lua层如何使用C#的enum以及使用enum需要注意的事项。这一节我们将讨论项目日常开发中经常会用到的委托注册机制&#xff0c;即C#层暴露若干委托和事件&#xff0c;然后在lua层进行注册&…

【沐风老师】3DMAX宇宙生成器(一键生成星系)插件使用方法详解

3DMAX宇宙生成器&#xff08;一键生成星系&#xff09;插件 3DMAX宇宙生成器&#xff08;一键生成星系&#xff09;插件&#xff0c;用于模拟星团及星系的运动。可以创建单个集合进行动画计算&#xff0c;也可以输入不同坐标&#xff0c;建立多个集合后统一进行动画计算。 【安…

探索iOS之CoreImage框架

CoreImage提供图像处理、人脸识别、图像增强、图像滤镜、图像转场。它操作的数据来自Core Graphics、Core Video、Image IO&#xff0c;使用CPU或GPU进行渲染。CoreImage对底层实现进行封装&#xff0c;为上层提供简单易用的API。 一、CoreImage框架 CoreImage框架分为&#…

计算机电脑中了勒索病毒,如何提高windows系统预防faust勒索病毒的能力

当今社会互联网技术迅猛发展&#xff0c;但随之而来的网络安全问题开始引起人们的重视&#xff0c;其中,勒索软件是当前网络安全领域中最具破坏性和危害性的恶意软件之一&#xff0c;而Faust勒索软件就是其中一种。 Faust勒索病毒是一种很可怕的恶意软件&#xff0c;能够破坏并…

计算机网络 - 网络层的数据平面

Overview 首先Network Layer负责的是host to host的传输, 然后可以分为两个平面, 控制平面以及数据平面. 数据平面: 负责forward datagrams from input to output links 决定路由器从input到output 转发功能: 基于目标地址 转发表 SDN方式基于多个字段流表 控制平面: 调…

第10届蓝桥杯Scratch省赛真题集锦

编程题 第 1 题 问答题 击鼓游戏 题目说明 准备工作: 将复台背景设置为“spotight-stage”&#xff0c;添加一个“Belerina"角色、两个“Drum1"角色和两个“Drum2”角色&#xff0c;并按照图 7-1 的位置摆放。角色“Beleina"的造型和颜色的设置须如图 7-1所示&a…

美女放电还是整形-从《人月神话》误译谈状态机图

DDD领域驱动设计批评文集 欢迎加入“软件方法建模师”群 《软件方法》各章合集 在重审《人月神话》中译本的过程中&#xff0c;发现一处较严重的误译。 原文是&#xff1a; the first milepost is not reached until two months have elapsed. 原译为&#xff1a; 两个月…

Java中常量基础知识

1 问题 什么是字面常量&#xff1f; 2 方法 拿第一行输出语句来说&#xff0c;这行代码输出了 “hello” 这个字符串&#xff0c;无论何时何地运行程序&#xff0c;输出的这个字符串都不会变&#xff0c;这就是字面常量。 定义&#xff1a;常量即程序运行期间&#xff0c;固定不…

chatgpt网站优选集合

目录 chatGpt 国内镜像网站集合 chatgpt接入微信 chatgpt接入谷歌浏览器 chatgptAI绘画 最后 chatGpt 这个说实话&#xff0c;不用我介绍大家也都懂。不如玩一个有意思的&#xff0c;这里我让chatGpt自己介绍一下他自己&#xff1a; 嗨&#xff0c;大家好&#xff0c;我是…

C++ [STL之vector模拟实现]

本文已收录至《C语言和高级数据结构》专栏&#xff01; 作者&#xff1a;ARMCSKGT STL之vector模拟实现 前言正文空间结构默认成员函数构造函数拷贝构造函数赋值重载析构函数关于数据拷贝问题 迭代器容量操作查询容量容量操作 数据访问下标访问头尾数据访问 数据增删尾插尾删重…

学懂缓存雪崩,缓存击穿,缓存穿透仅需一篇,基于Redis讲解

在了解缓存雪崩、击穿、穿透这三个问题前&#xff0c;我们需要知道为什么我们需要缓存。在了解这三个问题后&#xff0c;我们也必须知道使用Redis时&#xff0c;如何解决这些问题。 所以我将按照"为什么我们需要缓存"、"什么是缓存雪崩、击穿、穿透"、&qu…

Linux学习笔记 --- Linux基础命令Part1

一. Linux的目录结构 目标&#xff1a;1. 掌握Linux系统的目录结构 2. 掌握Linux系统的路径表达形式 1.1 Linux系统的目录结构 我们知道&#xff0c;在操作系统中&#xff0c;文件系统的目录结构一般都是树形结构。Linux的目录结构是一个树型结构Windows 系统可以拥有多…

如何使用wireShark抓取还原文件

简介 WireShark的追踪流功能可以帮我们抓取从网络上下载的各种文件&#xff0c;接下来就演示下如何抓取并且进行还原。 使用Nginx搭建文件存储服务器 只要是通过http网站下载的包&#xff0c;都可以通过追踪流工具进行抓取。这里为了演示&#xff0c;临时搭建一个Nginx文件存…

Yolov8涨点技巧:MobileViTAttention助力小目标检测,涨点显著,MobileViT移动端轻量通用视觉transformer

在​crack缺陷检测项目原始0.739提升至 0.772 ,涨点明显,博主多个数据集亲测有效,实现暴力涨点; 现有博客都是将MobileViT作为backbone引入Yolov5,因此存在的问题点是训练显存要求巨大,本文引入自注意力的Vision Transformer(ViTs):MobileViTAttention 1. MobileViT介绍…