整数规划

  • 简介
  • 0-1型整数规划
  • 蒙特卡洛法
  • 面积的近似问题
  • 非线性整数规划问题
  • PS:整数线性规划用Lingo会更简单
  • 指派问题


简介

  • 整数规划:数学规划中的变量(部分或全部)限制为整数时,称为整数规划。
  • 整数线性规划:将线性规划的变量限制为整数。【目前有套路解决,重点掌握】

0-1型整数规划

  • 变量只能取0或1,即有或无、去或不去这样的情况,是二进制变量
  • 一般对于不同的变量会有相互排斥的约束条件
    方法:
  1. 引入充分大的正实数
  2. 直接把二进制变量乘到约束条件上(有点逻辑电路使能端的意思)

蒙特卡洛法

利用概率解决问题。

面积的近似问题

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 %计时结束

整数规划 强化学习 整数规划的步骤_数学建模_02


但由于是用随机数模拟的,所以结果不唯一,只能得出较为满意的解。

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

整数规划 强化学习 整数规划的步骤_整数规划 强化学习_03


这里用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])

整数规划 强化学习 整数规划的步骤_随机数_04


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

结果也不是很好看的样子。

整数规划 强化学习 整数规划的步骤_整数规划 强化学习_05