问题重述

经典解法:整数规划

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

%% 背包问题(货车运送货物的问题)
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

模拟退火

我尝试了一下用模拟退火求解,也可得到相同的答案,下面为求解过程。

参数设定

将各个物理参数和目标参数用类的形式整合在一起,一目了然。

%% 背包问题
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 1temp = ceil(rand.*problem.numVar);variables(temp) = ~variables(temp);CV = problem.fun_CV(variables);if CV == 0breakend
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,作为新解。然后就是常规的退火筛选解的操作了。具体的筛选操作(Metropolis准则等)就不再赘述了。

%% 退火过程
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;endprob=exp(-dE/SAParameters.kb/T);if(dE>0 && rand()>prob)variables = variables_temp; % 不满足Metropolis准则,还原解endE0_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 1temp = ceil(rand.*problem.numVar);variables(temp) = ~variables(temp);CV = problem.fun_CV(variables);if CV == 0breakend
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;endprob=exp(-dE/SAParameters.kb/T);if(dE>0 && rand()>prob)variables = variables_temp; % 不满足Metropolis准则,还原解endE0_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;

最终结果

模拟退火结果

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

整数规划结果

结论

结果相同,以后该模拟退火法可用于同类背包问题的求解了 。

模拟退火解决背包问题相关推荐

  1. 部分背包的贪婪算法 java_使用JAVA实现算法——贪心算法解决背包问题

    packageBasePart;importjava.io.BufferedReader;importjava.io.FileInputStream;importjava.io.IOException ...

  2. 背包问题 贪心算法 java_JS基于贪心算法解决背包问题

    前面我们分享了关于js使用贪心算法解决找零问题,本文我们接着为大家介绍JS基于贪心算法解决背包问题. 贪心算法:在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做 ...

  3. 用贪婪算法解决背包问题_解决主要算法问题的贪婪策略

    用贪婪算法解决背包问题 Introduction: 介绍: Let's start the discussion with an example that will help to understan ...

  4. 基因算法解析、设计,以解决背包问题和旅行商问题为例

    一.算法说明 基因算法 基因算法有一套公共的完整的框架,伪代码如下. beginset time t = 0 # first generationinitGeneration() # initiali ...

  5. 使用ga算法解决背包问题_我如何使用算法解决现实生活中的手提背包的背包问题

    使用ga算法解决背包问题 I'm a nomad and live out of one carry-on bag. This means that the total weight of all m ...

  6. 贪心算法解决背包问题

    贪心算法解决背包问题 问题描述: 给定 n 个物品和一个容量为 C 的背包,请给出物品装入背包的方案,使得背包中物品的总价值 M 最大,并满足: 1.每个物品 I 的重量为 wi,价值为 vi. 2. ...

  7. 背包问题 贪心算法 java_JS基于贪心算法解决背包问题示例

    本文实例讲述了JS基于贪心算法解决背包问题.分享给大家供大家参考,具体如下: 贪心算法:在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局 ...

  8. 动态规划解决背包问题

    动态规划解决背包问题 问题描述: (1)解法一: 解决思路:动态规划 状态索引范围:从1开始 价值数组,大小数组索引范围:从0开始 状态:F(i,j):前i个物品放入大小为j的背包中所获得的最大价值. ...

  9. 动态规划算法解决背包问题

    一.动态规划算法概述 动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从子问题解得到原问题解. 但是经分解得到的子问题往往不是互相独立的.不同子问题的数目常常 ...

最新文章

  1. .net_ckeditor+ckfinder的图片上传配置
  2. java 圆的交点_java计算两条线段交点
  3. C语言讲义——字符串
  4. java定时器写法_java定时器的写法是什么样?
  5. P3388-[模板]割点(割顶)【tarjan】
  6. 单细胞分析Seurat使用相关的10个问题答疑精选!
  7. Day08- team、iptables、firewall
  8. 【图像处理】MATLAB:基本原理
  9. Bootstrap的js插件之側边栏停靠(affix)
  10. 怎么登录微信公众号-微信公众号使用教程2
  11. Word增加和删除行号
  12. missing privilege separation directory /var/empty/sshd问题解决
  13. java 权限 部分截图
  14. ArrayList的实现原理以及实现线程安全
  15. 计算机硬件型号,怎样检测电脑硬件型号
  16. 滚动轴承退化趋势预测
  17. CFA一级学习笔记--权益(一)--市场组织与架构
  18. 汇聚创新 共创未来---记2016华为开发者大赛沙龙深圳站
  19. 三年努力,我活成了自己喜欢的模样
  20. 神舟战神笔记本触控板的开启与关闭

热门文章

  1. 【渝粤题库】广东开放大学 电子商务概论 形成性考核
  2. XShell传输文件(CentOS7)
  3. 吴恩达深度学习 | (20) 序列模型专项课程第一周学习笔记
  4. [杂记]培训杂记(一)
  5. STM32上移植ds1307笔记
  6. 超前进位加法器原理与设计
  7. 自己的第一个Greasy Fork脚本
  8. pyqt5 登录界面界面的设计(多窗口的设计)
  9. 注会考试计算机应用技巧,2019年注会cpa考试机考系统计算器的操作技巧
  10. C/C++语言的应用领域