数学建模学习---整数规划1


前言

例如:
—这边学习整数规划的定义,分类,当然也有大家最关心的各种代码解法。

一、整数规划是什么?

1.1 定义

  1. 规划中的变量(部分或全部)限制为整数时,称为整数规划。若在线性规划模型中,变量限制为整数,则称为整数线性规划**。目前所流行的求解整数规划的方法,往往只适用于整数线性规划。目前还没有一种方法能有效地求解一切整数规划。

1.2 整数规划的分类

  1. 变量全限制为整数时,称纯(完全)整数规划
  2. 变量部分限制为整数的,称混合整数规划。
  3. 0-1规划,所有决策变量只能取0或1两个整数

1.3 整数规划特点

在这里插入图片描述
其中(2)可理解为x1或X2等的限制区间为(0,1),所以不出现解即无可行解。
其中2是因为简单取整后的值可能不满足约束条件。

二、求解方法

1.求解方法分类

(i)分枝定界法—可求纯或混合整数线性规划。
(ii)割平面法—可求纯或混合整数线性规划。
(iii)隐枚举法—求解“0-1”整数规划:
①过滤隐枚举法;
②分枝隐枚举法。
(iv)匈牙利法—解决指派问题(“0-1”规划特殊情形)。
(v)蒙特卡洛法—求解各种类型规划。
下面将简要介绍常用的几种求解整数规划的方法。

2.1分枝定界法

1.教材: 对有约束条件的最优化问题(其可行解为有限数)的所有可行解空间恰当地进行系统搜索,这就是分枝与定界内容。通常,把全部可行解空间反复地分割为越来越小的子集,称为分枝;并且对每个子集内的解集计算一个目标下界(对于最小值问题),这称为定界。在每次分枝后,凡是界限超出已知可行解集目标值的那些子集不再进一步分枝,样,许多子集可不予考虑,这称剪枝。这就是分枝定界法的主要思路。(看不懂没关系,接下来通俗的讲讲)
2. 通俗:当你用线性规划的方法求出的X中不管是X1还是X2只要有出现不是整数的,那你就选一个不是整数的X,往上取一个最接近的整数或者往下取一个最接近的整数作为一个新的限制条件(例如X1=2.7,往下取一个整数的获得一个上限的限制条件:X1≤2,往上取获得一个下限的限制条件:X2≥3)一直循环,一直增加限制条件即边界,直到算出来X全是整数为止,不就是所谓的分枝定界法嘛。

2.2分枝定界法的matlab代码

  1. 使用intprog()函数进行求解,intprog()在matlab工具箱中不存在需要自己创建
  2. 下面是创建代码:
    首先创建一个branchboun()函数,具体的我就不讲了直接用就行了
 function [newx,newfval,status,newbound] = branchbound(f,A,B,I,x,fval,bound,Aeq,Beq,lb,ub,e)

% 分支定界法求解整数规划
% f,A,B,Aeq,Beq,lb,ub与线性规划相同
% I为整数限制变量的向量
% x为初始解,fval为初始值

options = optimset('display','off');
[x0,fval0,status0]=linprog(f,A,B,Aeq,Beq,lb,ub,[],options);

%递归中的最终退出条件
%无解或者解比现有上界大则返回原解
if status0 <= 0 || fval0 >= bound
    newx = x;
    newfval = fval;
    newbound = bound;
    status = status0;
    return;
end

%是否为整数解,如果是整数解则返回
intindex = find(abs(x0(I) - round(x0(I))) > e);
if isempty(intindex) %判断是否为空值
    newx(I) = round(x0(I));
    newfval = fval0;
    newbound = fval0;
    status = 1;
    return;
end

%当有非整可行解时,则进行分支求解
%此时必定会有整数解或空解
%找到第一个不满足整数要求的变量
n = I(intindex(1));
addA = zeros(1,length(f));
addA(n) = 1;
%构造第一个分支 x<=floor(x(n))
A = [A;addA];
B = [B,floor(x(n))];%向下取整
[x1,fval1,status1,bound1] = branchbound(f,A,B,I,x0,fval0,bound,Aeq,Beq,lb,ub,e);
A(end,:) = [];
B(:,end) = [];
%解得第一个分支,若为更优解则替换,若不是则保持原状

status = status1;
if status1 > 0 && bound1 < bound
    newx = x1;
    newfval = fval1;
    bound = fval1;
    newbound = bound1;
else
    newx = x0;
    newfval = fval0;
    newbound = bound;
end

%构造第二分支
A = [A;-addA];
B = [B,-ceil(x(n))];%向上取整
[x2,fval2,status2,bound2] = branchbound(f,A,B,I,x0,fval0,bound,Aeq,Beq,lb,ub,e);    
A(end,:) = [];
B(:,end) = [];

%解得第二分支,并与第一分支做比较,如果更优则替换
if status2 > 0 && bound2 < bound
    status = status2;
    newx = x2;
    newfval = fval2;
    newbound = bound2;
end

然后创建一个intprog()函数

function [x,fval,status] = intprog(f,A,B,I,Aeq,Beq,lb,ub,e)
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值