规划中的变量(部分或全部)限制为整数时,称为整数规划。目前所流行的求解整数规划的方法,往往只适用于整数线性规划。
整数线性规划模型大致可分为两类:
设有最大化的整数规划问题 A A A,与它相应的线性规划为问题 B B B,从解问题 B B B开始,若其最优解不符合 A A A的整数条件,那么 B B B的最优目标函数必是 A A A的最优目标函数 z ∗ z^* z∗的上界,记作 z ^ \hat z z^;而A的任意可行解的目标函数值将是 z ∗ z^* z∗的一个下界 z ‾ \underline z z。分枝定界法就是将 B B B的可行域分成子区域的方法。逐步减小 z ˉ \bar z zˉ和增大 z ‾ \underline z z ,最终求到 z ∗ z^* z∗。
得用分枝定界法求解整数规划(最大化)问题的步骤为:
例子:设某LP(Linear Program):
max 40 x 1 + 90 x 2 \max 40x_1+90x_2 max40x1+90x2
{ 9 x 1 + 7 x 2 ≤ 56 7 x 1 + 20 x 2 ≤ 70 x 1 , x 2 ≥ 0 \begin{cases} 9x_1+7x_2\leq56\\ 7x_1+20x_2\leq70\\ x_1,x_2\geq0 \end{cases} ⎩⎪⎨⎪⎧9x1+7x2≤567x1+20x2≤70x1,x2≥0
其解为 x 1 = 4.81 , x 2 = 1.82 , z ˉ = 356 x_1=4.81,x_2=1.82,\bar z=356 x1=4.81,x2=1.82,zˉ=356,对其对应的IP(Integer Program)采用分支定界法,加入新约束 x 1 ≤ 4 x_1\leq4 x1≤4与整数约束,得到问题B1,其解为 x 1 = 4 , x 2 = 2.1 , z = 349 x_1=4,x_2=2.1, z=349 x1=4,x2=2.1,z=349。对应的,加入新约束 x 2 ≥ 5 x_2\geq5 x2≥5与整数约束得到新问题B2,其解为 x 1 = 5 , x 2 = 1.57 , z = 341 x_1=5,x_2=1.57,z=341 x1=5,x2=1.57,z=341。由此可得到B11其解为 x 1 = 4 , x 2 = 2 , z = 340 x_1=4,x_2=2, z=340 x1=4,x2=2,z=340。B12其解为 x 1 = 1.42 , x 2 = 3 , z = 327 x_1=1.42,x_2=3,z=327 x1=1.42,x2=3,z=327,B21其解为 x 1 = 5.44 , x 2 = 1 , z = 308 x_1=5.44,x_2=1, z=308 x1=5.44,x2=1,z=308。,B22无可行解。最终得到 z ∗ = 340 z^*=340 z∗=340。
注:将问题B划分为B11,B12,B21,B22四个子问题后,相当于将原LP的可行域划为4个子域,这4个子域的并集即为IP的解,由上可知,B11求到了整数解4,2,340,即 z ‾ = 340 \underline z=340 z=340,B11,B12,B2中最大的z为341(B21中的z更小,被剪枝),但对于变量的取值不是整数,所以B11的解即为IP的解。
变量值只取0和1的一种特殊的整数规划
只检查变量取值的组合的一部分,就能求到问题的最优解。这样的方法称为隐枚举法(Implicit Enumeration),分枝定界法也是一种隐枚举法。
对于非线性整数规划目前尚未有一种成熟而准确的求解方法,因为非线性规划本身的通用有效解法尚未找到,更何况是非线性整数规划。
对于非线性整数规划问题,采用显枚举法计算量大,如对有5个变量,每个变量有100种课能得取值时,显枚举法要计算 10 0 5 100^5 1005即 1 0 10 10^{10} 1010种取值,然而应用蒙特卡洛去随机计算 1 0 6 10 ^{6} 106个点,便可找到满意解。
对于指派矩阵 C = [ 3 8 2 10 3 8 7 2 9 7 6 4 2 7 5 8 4 2 3 5 9 10 6 9 10 ] C=\begin{bmatrix} 3&8&2&10&3\\ 8&7&2&9&7\\ 6&4&2&7&5\\ 8&4&2&3&5\\ 9&10&6&9&10 \end{bmatrix} C=⎣⎢⎢⎢⎢⎡3868987441022226109739375510⎦⎥⎥⎥⎥⎤,其求解的Lingo程序如下:
model:
sets:
var/1..5/;
link(var,var):c,x;
endsets
data:
c=3 8 2 10 3
8 7 2 9 7
6 4 2 7 5
8 4 2 3 5
9 10 6 9 10;
enddata
min=@sum(link:c*x);
@for(var(i):@sum(var(j):x(i,j))=1);
@for(var(j):@sum(var(i):x(i,j))=1);
@for(link:@bin(x));
end
分支定界法