模拟退火解决背包问题

这篇具有很好参考价值的文章主要介绍了模拟退火解决背包问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题重述 

模拟退火算法解决背包问题,matlab,启发式算法,模拟退火算法,动态规划

经典解法:整数规划 

        如图为清风老师讲义中的背包问题 ,其给出的解法为整数规划,代码如下:

%% 背包问题(货车运送货物的问题)
c = -[540 200 180 350 60 150 280 450 320 120];  % 目标函数的系数矩阵(最大化问题记得加负号)
intcon=[1:10];  % 整数变量的位置(一共10个决策变量,均为0-1整数变量)
A = [6 3 4 5 1 2 3 5 4 2];  b = 30;   % 线性不等式约束的系数矩阵和常数项向量(物品的重量不能超过30)
Aeq = []; beq =[];  % 不存在线性等式约束
lb = zeros(10,1);  % 约束变量的范围下限
ub = ones(10,1);  % 约束变量的范围上限
%最后调用intlinprog()函数
[x,fval]=intlinprog(c,intcon,A,b,Aeq,beq,lb,ub)
fval = -fval

模拟退火

        我尝试了一下用模拟退火求解,也可得到相同的答案,下面为求解过程。模拟退火是一种材料退火过程的仿真优化算法,通过Matropolis准则对随机解进行筛选与迭代,从而完成最优解的求解的方法。

        着重介绍一下metropolis准则,这也是模拟退火算法的重点所在。Metropolis  准则在物理上是指在温度下降过程中,粒子的移动产生了新的状态,若新状态的能量更小,则接受新状态,反之,考虑热运动的影响,就以某个概率判断是否接受新状态。在模拟退火算法的搜索过程中,如果算法在某个区域得到了一个适应度值比当前解更差的新解,就使用 Metropolis  准则判断是否接受新解。通过使用 Metropolis  准则,模拟退火算法可以接受较差的解,具备了跳出局部最优陷阱的能力。

        对于背包问题,初始解的生成可以采用数组形式,这一点和我之前文章中处理旅行商问题是一样的。不同点在于,此处生成的是0-1序列,因为背包问题解决的根本逻辑是整数规划中的0-1规划。新解的产生只要随机将序列中的0变成1或1变成0即可。这时候便产生一个新的问题,新解中多少个0变成1和多少个1变成0是最有效率的?这也是在该问题中算法优化的主要方向。

参数设定

        将各个物理参数和目标参数用类的形式整合在一起,一目了然。模拟退火的外在框架是一个马尔可夫链。每一个温度下,新解的产生都是一个马尔科夫链循环。马尔科夫链即无记忆序列,在同一温度下多次计算可以保证结果的稳定性,但马尔科夫链太长算法的速度便不能保证。其他参数为固体退火基本参数,详细参考模拟退火物理原理,此处不做过多解释。惩罚系数作用于罚函数,此处笔者也不是很了解,一般取1.5。

%% 背包问题
clear;clc

%% 设置求解问题的参数
problem.numVar = 10;       %变量个数
problem.fun = @(x)obj_fun(x); %优化目标函数名称
problem.fun_CV = @(x)obj_fun_CV(x);  %约束条件

%% 模拟退火的参数
SAParameters.temperature = 100;% 初始温度 设置的足够大的话,可以在初始拥有更好的性能
SAParameters.kb = 0.3; % 温度系数
SAParameters.alpha = 0.9; % 降温系数
SAParameters.penalty = 1.5; % 惩罚系数
SAParameters.num = 100; % 马尔可夫链长度
SAParameters.Tmin = 1; % 结束温度
 

目标函数

        参考0-1规划模型。决策变量x是个长度为10的序列,只包含0或1。0代表不运送该货物;1代表运送该货物。货物价值写在矩阵c中,通过与0-1矩阵的点乘便可求出总价值。具体写法如下:

function f = obj_fun(x) % 目标函数
    c = -[540 200 180 350 60 150 280 450 320 120]; 
    f = c.*x;
    f = sum(f);
end

罚函数

        约束条件为所装所有货物重量小于等于30。因此要对货物质量大于30的解进行惩罚。A为各货物的重量矩阵,通过与0-1矩阵的点乘便可求出货物总重量。具体写法如下:

function CV = obj_fun_CV(x)  % 约束条件函数
    A = [6 3 4 5 1 2 3 5 4 2];
    g1 = sum(A.*x)-30;
    G1 = (g1>0)*g1; % 大于30时候对其进行惩罚
    CV = G1;
end

初始解生成

        初始解必须是一个可行解,因此全部为1的序列肯定不行,需要对序列进行随机扰动,并且让该序列的解满足罚函数值为0(即满足约束条件)。

%% 解的初始化,产生一个可行解
variables = ones(1,10);
while 1
    temp = ceil(rand.*problem.numVar);
    variables(temp) = ~variables(temp);
    CV = problem.fun_CV(variables);
    if CV == 0
        break
    end
end
var_final = variables; % 初始化最终最优解
T = SAParameters.temperature; % 初始化温度
E0_OBJ = problem.fun(variables); % 初始化目标函数值
E0_CV = problem.fun_CV(variables); % 初始化CV值
E0 = E0_OBJ+SAParameters.penalty*E0_CV; % 最终目标值
E_OBJ_f = E0; % 初始化最佳温度

退火过程

        通过随机扰动,随机将序列中的1变成0或0变成1,作为新解。此处有很大优化空间,直接决定算法的速度。笔者此处是对整个序列进行随机01变动,但这种方法显然很慢。不过暂时没有想到更好的方法。。。

%% 退火过程
while (T>=SAParameters.Tmin) % 开始降温
    for i = 1:SAParameters.num % 马尔科夫链
        variables_temp = variables; % 用于暂时存放原来的解 
		%% 新解的产生,随机扰动法
        temp = ceil(rand.*problem.numVar);
        variables(temp) = ~variables(temp);
        %% 移动后的目标值计算
        E_OBJ = problem.fun(variables); % 移动后的目标函数值
        E_CV = problem.fun_CV(variables); % 移动后的CV值
        E = E_OBJ+SAParameters.penalty*E_CV;
        dE = E-E0;
        if (E_OBJ<=E_OBJ_f && E_CV==0)
           var_final = variables; % 适应度更小且满足约束条件,保留解
           E_OBJ_f=E_OBJ;
        end
        prob=exp(-dE/SAParameters.kb/T);
        if(dE>0 && rand()>prob)
            variables = variables_temp; % 不满足Metropolis准则,还原解
        end
        E0_OBJ=problem.fun(variables); %初始目标函数值
        E0_CV=problem.fun_CV(variables); %初始CV值
        E0=E0_OBJ+SAParameters.penalty*E0_CV;
    end
T = T*SAParameters.alpha; % 降温
end
E_OBJ_f = -E_OBJ_f;

总代码 

%% 背包问题
clear;clc

%% 设置求解问题的参数
problem.numVar = 10;       %变量个数
problem.fun = @(x)obj_fun(x); %优化目标函数名称
problem.fun_CV = @(x)obj_fun_CV(x);  %约束条件

%% 模拟退火的参数
SAParameters.temperature = 100;% 初始温度 设置的足够大的话,可以在初始拥有更好的性能
SAParameters.kb = 0.3; % 温度系数
SAParameters.alpha = 0.9; % 降温系数
SAParameters.penalty = 1.5; % 惩罚系数
SAParameters.num = 100; % 马尔可夫链长度
SAParameters.Tmin = 1; % 结束温度
 
%% 解的初始化,产生一个可行解
variables = ones(1,10);
while 1
    temp = ceil(rand.*problem.numVar);
    variables(temp) = ~variables(temp);
    CV = problem.fun_CV(variables);
    if CV == 0
        break
    end
end
var_final = variables; % 初始化最终最优解
T = SAParameters.temperature; % 初始化温度
E0_OBJ = problem.fun(variables); % 初始化目标函数值
E0_CV = problem.fun_CV(variables); % 初始化CV值
E0 = E0_OBJ+SAParameters.penalty*E0_CV; % 最终目标值
E_OBJ_f = E0; % 初始化最佳温度

%% 退火过程
while (T>=SAParameters.Tmin) % 开始降温
    for i = 1:SAParameters.num % 马尔科夫链
        variables_temp = variables; % 用于暂时存放原来的解 
		%% 新解的产生,随机扰动法
        temp = ceil(rand.*problem.numVar);
        variables(temp) = ~variables(temp);
        %% 移动后的目标值计算
        E_OBJ = problem.fun(variables); % 移动后的目标函数值
        E_CV = problem.fun_CV(variables); % 移动后的CV值
        E = E_OBJ+SAParameters.penalty*E_CV;
        dE = E-E0;
        if (E_OBJ<=E_OBJ_f && E_CV==0)
           var_final = variables; % 适应度更小且满足约束条件,保留解
           E_OBJ_f=E_OBJ;
        end
        prob=exp(-dE/SAParameters.kb/T);
        if(dE>0 && rand()>prob)
            variables = variables_temp; % 不满足Metropolis准则,还原解
        end
        E0_OBJ=problem.fun(variables); %初始目标函数值
        E0_CV=problem.fun_CV(variables); %初始CV值
        E0=E0_OBJ+SAParameters.penalty*E0_CV;
    end
T = T*SAParameters.alpha; % 降温
end
E_OBJ_f = -E_OBJ_f;

最终结果

模拟退火结果

        这是模拟退火过程求得的结果。

模拟退火算法解决背包问题,matlab,启发式算法,模拟退火算法,动态规划

模拟退火算法解决背包问题,matlab,启发式算法,模拟退火算法,动态规划

 整数规划结果

模拟退火算法解决背包问题,matlab,启发式算法,模拟退火算法,动态规划      

结论

        结果相同,证明该模拟退火算法程序是正确的。当然此题比较简单,如果数据更复杂,该算法程序的正确性和效率还有待考察。主要优化空间还在于新解的产生上。笔者在此抛砖引玉,读者若有好想法也可以在评论区交流。文章来源地址https://www.toymoban.com/news/detail-734323.html

到了这里,关于模拟退火解决背包问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 97基于matlab的改进的带记忆的模拟退火算法求解TSP问题

    基于matlab的改进的带记忆的模拟退火算法求解TSP问题,采用多普勒型降温曲线描述迭代过程,在传统算法的基础上增加记忆功能,可测试中国31/64/144以及att48城市的数据,也可自行输入数据进行测试,测试结果基本达到当前最优水平。duoci.m为主文件。数据可更换自己的,程序

    2024年02月05日
    浏览(53)
  • 启发式算法之灰狼优化算法

    蚁群算法?秃鹰算法?布谷鸟算法?鱼群算法?猴群算法?这都是些啥? 这些算法听起来都很接地气,实际上也确实很接地气。它们都是学者通过观察动物们的行为得到的灵感,从而设计出来的精彩的算法。以动物命名的算法可远不止这些,比如还有蜂群算法、狼群算法、蝙

    2024年02月13日
    浏览(43)
  • Matlab【旅行商问题】—— 基于模拟退火算法的无人机药品配送路线最优化

    某市引进一架专业大型无人机用于紧急状态下的药品投递,每个站点只能投放一次,可选择指派任意站点的无人机起飞出发完成投递任务,但必须在配送完毕后返回原来的站点。站点地理位置坐标(单位为公理)如下图所示。每个站点及容纳的病人数量见附件.mat数据,现要求

    2024年02月12日
    浏览(56)
  • 启发式搜索 :A*算法详解

    A*算法,(A-Star)算法是一种静态路网中求解 最短路径 最有效的 直接搜索方法 ,也是解决许多搜索问题的有效算法。 算法中的距离估算值与实际值 越接近 ,最终搜索速度越快。 对于求两个点之间的最短路 普通的BFS是按层遍历的过程,以起点为中心,以到终点的最短路为半径

    2023年04月08日
    浏览(43)
  • 【启发式算法】灰狼优化算法【附python实现代码】

    写在前面: 首先感谢兄弟们的订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 路虽远,行则将至;事虽难,做则必成。只要有愚公移山的志气、滴水穿石的毅力,脚踏实地,埋头苦干,积跬

    2024年02月16日
    浏览(38)
  • 非梯度类启发式搜索算法:Nelder Mead

    Hello,今天给大家介绍一种不基于梯度的优化算法 Nelder Mead。 Nelder Mead 算法通常是用来求解非线性(nonlinear)、导函数未知情况下目标函数的最大值或者最小值。学过梯度下降的同学应该知道,梯度下降类算法的每一步都需要计算当前位置的梯度,从而更新当前解使得最终逐

    2024年02月02日
    浏览(47)
  • 元启发式算法库 MEALPY 初体验-遗传算法为例

    官网: MealPY官网 开源许可: (GPL) V3 MEALPY (MEta-heuristic ALgorithms in PYthon) 是一个提供最新自然启发式元启发算法的Python模块,它是最大的此类Python模块之一。这些算法模仿自然界中的成功过程,包括生物系统以及物理和化学过程。mealPy 的目标是免费向所有人分享元启发领域的知识

    2024年04月11日
    浏览(42)
  • 【场景生成与削减】基于蒙特卡洛法场景生成及启发式同步回带削减风电、光伏、负荷研究(Matlab代码实现)

      💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 相关知

    2023年04月19日
    浏览(43)
  • matlab智能算法之模拟退火算法

    2023年04月29日
    浏览(48)
  • Matlab:遗传算法,模拟退火算法练习题

    1、遗传算法 (1) 遗传算法 是一种基于自然选择原理和自然遗传机 制的搜索(寻优)算法,它是模拟自然界中的生命进化机制,在人工系统中实现特定目 标的优化。遗传算法的实质是通过群体搜索技术,根据适者生存的原则逐代进化,最终 得到最优解或准最优解。它必须

    2024年01月21日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包