整数规划之分枝定界法

整数规划之分枝界定法

引子:

在这里插入图片描述

题目分析:

这个整数规划问题相当于是在简单的线性规划问题上增加了决策变量为整数的限制条件。如果没有这个限制条件,那我们用linprog函数很容易解决如下

>> c=[40,90];
>> a=[9 7;7 20];
>> b=[56;70];
>> lb=[0;0];
>> ub=[];
>> aeq=[];
>> beq=[];
>[x,y]=linprog(-c,a,b,aeq,beq,lb,ub);

Optimal solution found.
>> disp(x)
    4.8092
    1.8168

>> disp(-y)
  355.8779

但显然这结果不是我们想要的,因为我们需要x1,x2均为整数。那我们该怎么办呢,分支界定法。
(1)我们首先找到上面最优解(不符合整数约束的)x1
将原来x1的取值范围分割成两半(0<=x1<=4<4.8092,x1>=5>4.8092)之所以这么分是因为4,5之间没有其他整数,所以不会漏掉解,其他决策变量范围暂时保持不变;
(2)接下来我们需要在分割的两个区间b1,b2中求其最优解
b1

c=[40,90];
a=[9 7;7 20];
b=[56;70];
lb=[0;0];
ub=[4;inf];
aeq=[];
beq=[];
[x,y]=linprog(-c,a,b,aeq,beq,lb,ub)

Optimal solution found.

x =
    4.0000
    2.1000


y =
  -349%这里的值是我们最大值的相反数

b2:

c=[40,90];
a=[9 7;7 20];
b=[56;70];
lb=[5;0];
ub=[inf;inf];
aeq=[];
beq=[];
[x,y]=linprog(-c,a,b,aeq,beq,lb,ub)

Optimal solution found.
x =
    5.0000
    1.5714
y =

 -341.4286%最大值相反数

可以发现我们的求解代码都是极其相似的,只有决策变量的上下界发生了改变。但遗憾的是我们至今还没有找到我们想要的答案。那现在我们可以再x2做分割(因为我们发现b1,b2的解中x1都成了整数,那我们就只需要再在此基础上对x2分割就可以)
那我们得到四个取值区间及其结果如下:
c1:0<=x1<=4,0<=x2<=2;

x =
     4
     2
y =
   340

c2:0<=x1<=4,x2>=3;

x =
    1.4286
    3.0000
y =
  327.1429

c3:x1>=5,0<=x2<=1;

x =
    5.4444
    1.0000
y =
  307.7778

c4:x1>=5,x2>=2;

No feasible solution found.
Linprog stopped because no point satisfies the constraints.

通过以上的比较我们发现c1,c2,c3,c4四个子区间中只有c1,c2,c3存在最优解且只有c1的解符合整数条件。最最最巧合的是c1的max值刚好比c2,c3的max值大,所以到此我们就完成了此题的所有步骤
得到其最佳解:
x1=4,x2=2;
y=340

新的思考及体会:

对于任何一个需要分割的主问题A,我们分割一次后将其分为B1,B2两个子区间,如果区间不存在可行解(如上例中c4),那么就无需讨论,直接“割”去,讨论其他区间即可。但如果均有最优解(不考虑是否为整数),那将会有以下情况出现:
(1)B1找到了最优解max1且符合整数条件,B2最优解max2<=max1,那么这种情况无论max2是不是整数解都无所谓了,其最优整数解一定是max1;(2)但如果出现了max1是B1区间的最优整数解,而max2的最优解非整数但却有max2>max1。那么这时候我们需要把B2区间的问题看成主问题继续递归分支下去,直到出现(1)中那样的情况为止,再逐层返回,最后比较得到答案。这是最最最严谨的思路。不过这过程是无尽的重复,一般来讲理想的做题不会有太多次递归,就如上面的题目。
写在最后:刚开始学习matlab,语法不太熟悉,希望后续可以完成对这道题目函数的编写,让matlab替我完成这“无尽”的循环。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
整数规划是一种优化问题,它要求在一组整数的可行解集合中找到一个最优解。分枝是一种求解整数规划问题的有效方。以下是一个使用C语言实现分枝的示例代码。 ```C #include <stdio.h> #include <stdlib.h> #define MAXN 1000 #define MAXM 1000 int n, m; int c[MAXN], a[MAXM][MAXN], b[MAXM]; int x[MAXN], bestx[MAXN]; int bestc, curc; void dfs(int i) { if (i > n) { if (curc > bestc) { bestc = curc; for (int j = 1; j <= n; j++) { bestx[j] = x[j]; } } return; } if (curc + c[i] <= bestc) { return; } x[i] = 1; int sum = 0; for (int j = 1; j <= m; j++) { int ok = 1; for (int k = 1; k <= n; k++) { if (a[j][k] && x[k] == 0) { ok = 0; break; } } if (ok) { sum += b[j]; } } curc += sum; dfs(i + 1); curc -= sum; x[i] = 0; dfs(i + 1); } int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &c[i]); } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { scanf("%d", &a[i][j]); } scanf("%d", &b[i]); } dfs(1); printf("bestc = %d\n", bestc); for (int i = 1; i <= n; i++) { printf("%d ", bestx[i]); } printf("\n"); return 0; } ``` 该代码实现了一个简单的整数规划求解器,用于解决如下形式的整数规划问题: $$\max \sum_{i=1}^n c_i x_i$$ $$\text{s.t.} \sum_{i=1}^n a_{ji} x_i \leq b_j, j = 1, 2, \cdots, m$$ $$x_i \in \{0, 1\}, i = 1, 2, \cdots, n$$ 其中,$n$表示变量个数,$m$表示约束个数,$c_i$表示第$i$个变量的系数,$a_{ji}$表示第$j$个约束中第$i$个变量的系数,$b_j$表示第$j$个约束的右端常数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

公子小白痴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值