注意点
1、Lingo 默认所有变量不为负数,故应先进行定义域自由化。
2、Lingo 只有三种关系运算符:“=”、“>=”以及“<=”。没有单独的“>”和“<”,若出现,Lingo 则视为省略了“=”。
3、Lingo 中的if 函数,必须自带一个else。
4、看不懂可以上这个网站 学习地址
一、lingo函数
1、变量定界函数
函数名 | 作用 |
---|---|
@bin(x) | 限制x只能取0或 1,0−1规划中特别有用 |
@gin(x) | 限制x为整数,在整数规划中特别有用 |
@bnd(a,x,b) | 限制 a≤x≤b |
@free(x) | 取消对变量x 非负的限制,使其定义域自由(lingo默认变量为非负) |
2、数学函数
函数名 | 返回值 |
---|---|
@sin(x) | 返回x 的正弦值 |
@cos(x) | 返回x 的余弦值 |
@tan(x) | 返回x 的正切值 |
@log(x) | 返回x 的自然对数值,其他底数用换底公式 |
@exp(x) | 返回ex的值,因e的数值无法敲入而诞生 |
@abs(x) | 返回x 的绝对值 |
@sigh(x) | 返回 x的符号值x≥0为1,x<0为−1 |
@floor(x) | 返回x 的整数部分,向靠近0 的方向取整 |
@smax( X1,X2,……, Xn) | 返回其中的最大值 |
@smin( X1, X2,……,Xn) | 返回其中的最小值 |
3、集合操作函数
设mark工厂生产 6个元素的矩阵:
函数名 | 作用 |
---|---|
@for( mark : a>0 ) | 循环 |
@sum( mark : a ) | 求和 |
@prod( factory : a ) | 求积 |
@max( factory : a ) | 求最大值 |
@min( factory : a ) | 求最小值 |
二、线性规划
1、例题
lingo\matlab代码
lingo程序:
model:
max=2*x1+x2-5*x3;
x1+x2+x3=7;
2*x1-5*x2+x3>=10;
x1+3*x2+x3<=12;
end
%就是把条件输入即可
matlab程序:
c = [-2 -3 5]';
A = [-2 5 -1;1 3 1];
b = [-10 12];
Aeq = ones(1,3);
beq = 7;
lb = zeros(3,1);
[x fval] = linprog(c, A, b, Aeq, beq, lb)
fval = -fval %
2、实际问题求解
我们可以通过对问题的分析我们得出以下方程:
lingo\matlab代码:
%% 生产决策问题
lingo代码:
model:
sets:
gonjian /1..9 / :a,x;
endsets
%定义矩阵工厂
data:
a=0.75,0.7753,-0.375,-0.447428571428571,-0.35,-0.5,-0.2889,1.15,0.684371428571428;
enddata
%导入数据
max=@sum(gonjian : a*x);
5*x(1)+10*x(6)<=6000;
7*x(2)+9*x(7)+12*x(9)<=10000;
6*x(3)+8*x(8)<=4000;
4*x(4)+11*x(9)<=7000;
7*x(5)<=4000;
x(1)+x(2)=x(3)+x(4)+x(5);
x(6)+x(7)=x(8);
end
%一样是输入条件
matlab代码
format long g %可以将Matlab的计算结果显示为一般的长数字格式
% (1) 系数向量
c = zeros(9,1); % 初始化目标函数的系数向量全为0
c(1) = 1.25 -0.25 -300/6000*5; % x1前面的系数是c1
c(2) = 1.25 -0.25 -321/10000*7;
c(3) = -250 / 4000 * 6;
c(4) = -783/7000*4;
c(5) = -200/4000 * 7;
c(6) = -300/6000*10;
c(7) = -321 / 10000 * 9;
c(8) = 2-0.35-250/4000*8;
c(9) = 2.8-0.5-321/10000*12-783/7000*11;
c = -c; % 我们求的是最大值,所以这里需要改变符号
% (2) 不等式约束
A = zeros(5,9);
A(1,1) = 5; A(1,6) = 10;
A(2,2) = 7; A(2,7) = 9; A(2,9) = 12;
A(3,3) = 6; A(3,8) = 8;
A(4,4) = 4; A(4,9) = 11;
A(5,5) = 7;
b = [6000 10000 4000 7000 4000]';
% (3) 等式约束
Aeq = [1 1 -1 -1 -1 0 0 0 0;
0 0 0 0 0 1 1 -1 0];
beq = [0 0]';
%(4)上下界
lb = zeros(9,1);
% 进行求解
[x fval] = linprog(c, A, b, Aeq, beq, lb)
fval = -fval
intcon = 1:9;
[x,fval]=intlinprog(c,intcon,A,b,Aeq,beq,lb)
fval = -fval
从这两个问题可以看出求解线性规划规划问题中用lingo软件要方便一点。
二、整数规划
1、例题
lingo\matlab代码
lingo代码:
model:
min=18*x1+23*x2+5*x3;
107*x1+500*x2>=500;
107*x1+500*x2<=50000;
72*x1+121*x2+65*x3>=2000;
72*x1+121*x2+65*x3<=2250;
@gin(x1);
@gin(x2);
@gin(x3);
%%%无非加了一个@gin()函数
%%%所以求解0-1规划时直接用@bin()函数就可以了
end
matlab代码:
c=[18,23,5]';
intcon=3; % x3限定为整数
A=[107,500,0;
72,121,65;
-107,-500,0;
-72,-121,-65];
b=[50000;2250;-500;-2000];
lb=zeros(3,1);
[x,fval]=intlinprog(c,intcon,A,b,[],[],lb)
2、实际问题求解
在线性规划中那给实际问题中工件不可能有小数的出现,所以上面那个问题实际是个整数规划问题
代码如下:
model:
sets:
gonjian /1..9 / :a,x;
endsets
%定义矩阵工厂
data:
a=0.75,0.7753,-0.375,-0.447428571428571,-0.35,-0.5,-0.2889,1.15,0.684371428571428;
enddata
%导入数据
max=@sum(gonjian : a*x);
5*x(1)+10*x(6)<=6000;
7*x(2)+9*x(7)+12*x(9)<=10000;
6*x(3)+8*x(8)<=4000;
4*x(4)+11*x(9)<=7000;
7*x(5)<=4000;
x(1)+x(2)=x(3)+x(4)+x(5);
x(6)+x(7)=x(8);
@for(gonjian : @gin(x));
%%不过是在上面那个线性规划中加如一个@gin()函数而已
%%求解0-1规划问题则是加如@bin()函数
end
3、0-1规划问题(背包问题)
通过对题目分析可得:
lingo\matlab代码:
%% 背包问题(货车运送货物的问题)
lingo代码:
model:
sets:
dinyi /1..10/ : a,b,x;
endsets
data:
a=6,3,4,5,1,2,3,5,4,2;
b=540,200,180,350,60,150,280,450,320,120;
enddata
max=@sum(dinyi : b*x);
@sum(dinyi : a*x)<=30;
@for(dinyi : @bin(x));
%无非加了@bin()函数
end
matlab代码:
c = -[540 200 180 350 60 150 280 450 320 120]; % 目标函数的系数矩阵(最大化问题记得加负号)
intcon=[1:10]; % 整数变量的位置(一共10个决策变量,均为0-1整数变量)
A = [6 3 4 5 1 2 3 5 4 2]; b = 30; % 线性不等式约束的系数矩阵和常数项向量(物品的重量不能超过30)
Aeq = []; beq =[]; % 不存在线性等式约束
lb = zeros(10,1); % 约束变量的范围下限
ub = ones(10,1); % 约束变量的范围上限
%最后调用intlinprog()函数
[x,fval]=intlinprog(c,intcon,A,b,Aeq,beq,lb,ub)
fval = -fval
总结
求解整数规划用@gin()函数
求解0-1规划用@bin()函数
我认为求解线性规划和整数规划可以用lingo软件,非线性规划还是建议使用matlab求解。