整数规划
- 简介
- 0-1型整数规划
- 蒙特卡洛法
- 面积的近似问题
- 非线性整数规划问题
- PS:整数线性规划用Lingo会更简单
- 指派问题
简介
- 整数规划:数学规划中的变量(部分或全部)限制为整数时,称为整数规划。
- 整数线性规划:将线性规划的变量限制为整数。【目前有套路解决,重点掌握】
0-1型整数规划
- 变量只能取0或1,即有或无、去或不去这样的情况,是二进制变量
- 一般对于不同的变量会有相互排斥的约束条件
方法:
- 引入充分大的正实数
- 直接把二进制变量乘到约束条件上(有点逻辑电路使能端的意思)
蒙特卡洛法
利用概率解决问题。
面积的近似问题
clc,clear
%蒙特卡洛函数 在[0,21]x[0,9]区域内生成随机数点
x = unifrnd(0,12,[1,10000000]);%横坐标
y = unifrnd(0, 9,[1,10000000]);%纵坐标
pinshu = sum(y<x.^2 & x<=3) + sum (y<12-x & x>=3);%统计出现在区域内的频数
area_appr = 12*9*pinshu/10^7%根据频率求面积的近似值
非线性整数规划问题
待求值含有x的非一次幂,如果用枚举法显然不现实,可以利用蒙特卡洛法取少量点计算结果并给出可信度,即可找出满意解。
例子:
为了方便,先写一个函数。
function[f,g]=mengte(x);
f=x(1)^2 + x(2)^2 + 3*x(3)^2 + 4*x(4)^2 + 2*x(5)^2 - 8*x(1) - 2*x(2) -...
3*x(3) - 4*x(4) - 2*x(5);
g = [sum(x)-400
x(1)+2*x(2)+2*x(3)+x(4)+6*x(5)-800
2*x(1)+x(2)+6*x(3)-200
x(3)+x(4)+5*x(5)-200];
下面是主程序
clc,clear
rand('state',sum(clock));%初始化随机数发生器 用时间做种子
p0=0;
tic %计时开始
for i=1:10^6
x=randi([0,99],1,5);%产生一行五列的区间【0,99】的随机整数
[f,g]=mengte(x);
if all(g<=0)
if p0<f
x0=x;p0=f;%记录下当前较好的解
end
end
end
x0,p0
toc %计时结束
但由于是用随机数模拟的,所以结果不唯一,只能得出较为满意的解。
PS:整数线性规划用Lingo会更简单
在淘宝花十块买了一个,虽然要支持正版,但…大家都懂的。
用MATLAB求解也不是不行,但是涉及到全部转换为一维向量,比较复杂,没有Lingo简便。
还是上个例子:
model:
sets:
row/1..4/:b;
col/1..5/:c1,c2,x;
link(row,col):a;
endsets
data:
c1 = 1,1,3,4,2;
c2 = -8,-2,-3,-1,-2;
a=1 1 1 1 1
1 2 2 1 6
2 1 6 0 0
0 0 1 1 5;
b=400,800,200,200;
enddata
max=@sum(col:c1*x^2+c2*x);
@for(row(i):@sum(col(j):a(i,j)*x(j))<b(i));
@for(col:@gin(x));
@for(col:@bnd(0,x,99));
end
这里用Lingo的话结果会比MATLAB更精确一点。
指派问题
MATLAB
clc,clear
%指派矩阵
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=c(:);%需要变成一维向量才能继续计算
a=zeros(10,25);
intcon=1:25;
for i=1:5
a(i,(i-1)*5+1:5*i)=1;
a(5+i,i:5:25)=1;
end
b=ones(10,1);
lb=zeros(25,1);ub=ones(25,1);
x=intlinprog(c,intcon,[],[],a,b,lb,ub);
x=reshape(x,[5,5])
Lingo
相比之下Lingo的写法上就比较容易理解。但是之前没学过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
结果也不是很好看的样子。