LINGO是一种专门用于求解数学规划问题的软件包。由于LINGO执行速度快,易于方便地输入、求解和分析数学规划问题,因此在教学、科研和工业界得到了广泛应用。LINGO主要用于求解线性规划、非线性规划、一次规划和整数规划等问题,也可用于求解一些线性和非线性方程组及代数方程求根等。本章介绍的LINGO可在LINGO5.0、LINGO9.0、LINGO12.0等中使用。
一.LINGO使用介绍
1.1 LINGO编写格式
LINGO模型以MODEL开始,以END结束。中间为语句,分为四大部分。
(1)集合部分(SETS)
这部分以"SETS:"开始,以"ENDSETS"结束。这部分的作用在于定义必要的变量,便于后面进行编程进行大规模计算,在LINGO中称为集合(SET)及其元素和属性。
LINGO中的集合有两类:
- 一类是原始集合 ,其定义的格式为:
- SETNAME/member list(or 1,n)/:attribute, attribute, etc.
- 另一类是导出集合 ,即引用其他集合定义的集合,其定义的格式为:
- SETNAME(set1, set2, etc.): attribute, attribute, etc.
如果要在程序中使用数组,就必须在该部分定义,否则可不需要。如
Person/1..10/:A;
Task/1..12/:B;
Link(Person,Task):X;
(2)目标与约束
这部分定义了目标函数、约束条件等。一般要用到LINGO的内部函数。求解优化问题时,该部分是必须的。
(3)数据部分(DATA)
这部分以"DATA:"开始,以"END DATA"结束。其作用在于对某些集合的属性(数组)输入必要的数据。格式为:attribute=value_list。该部分主要是方便数据的输入。
(4)初始化部分(INIT)
这部分以"INIT:"开始,以"END INIT"结束。作用在于对某些集合的属性(数组)定义初值。格式为:attribute=value_list。
编写LINGO程序要注意的几点:
- 所有的语句除SETS, ENDSETS, DATA, ENDDATA, INIT, ENDINIT和MODEL, END之外必须以一个分号 ";" 结尾。
- LINGO求解非线性规划时已约定各变量非负。
1.2 LINGO内部函数使用详解.
LINGO建立优化模型时可以引用大量内部函数,这些函数以"@"符号打头.
(1) 常用数学函数
@ABS(X) 返回变量X的绝对数值。
@COS(X) 返回X的余弦值,X的单位为弧度
@EXP(X)返回指数函数值,其中e=2.72828...
@FLOOR(X)向0靠近返回回X的整数部分。
@LGM(X)返回l函数的自然对数值。
@LOG(X)返回变量X的自然对数值
@SIGN(X) 返回变量X的符号值,当X<0时为-1;当X>0时为1.
@SIN(X) 返回X的正弦值,X的单位为弧度
@SMAX(X1, X2,..., XN)
返回一列值X1, X2,..., XN的最大值.
@SMIN(X1, X2,..., XN)
返回一列值X1, X2,..., XN的最小值.
@TAN(X) 返回X的正切值,X的单位为弧度
(2)集合函数
集合函数的用法如下: set_operator(set_name|condition:expression)。其中set_operator是集合函数名,set_name是数据集合名,expression部分是表达式,|condition部分是条件,用逻辑表达式描述(无条件时可省略)。逻辑表达式式中可以三种逻辑算符#AND#(与), #OR# (或), #NOT#(非)和六种关系算符#EQ# (等于), #NE# (不等于),#GT#(大于), #GE#(大于等于), #LT#(小于), #LE#(小于等于)。
常见的集合函数如下:
@FOR(set_name: constraint_expressions)对集合(set_name)的每个元素独立地生成约束,约束由约束表达式(constraint_expressions)描述。
@MAX(set_name: expression)返回集合上表达式(expression)的最大值。
@MIN(set_name: expression)返回集合上的表达式(expression)最小值。
@SUM(set_name: expression)返回集合上的表达式(expression)的和。
@SIZE(set_name)返回数据集set_name中包含元素的个数。
@IN(set_name,set_element)如果数据集set_name中包含元素set_element 则返回1,否则返回0。
(3) 变量界定函数
变量函数对变量的取值范围附加限制,共有四种。
@BND(L,X,U)限制L≤X≤U
@BIN(X)限制X为0或1.
@FREE(X)取消对X的符号限制(可取任意实数值).
@GIN(X)限制X为整数值.
二、LINGO求解优化模型实例
- 某昼夜服务的公交路线每天各时间区段内需司机和乘务人员见表1.
设司机和乘务人员分别在各时间区段一开始上班, 并连续工作八小时, 问该公交线路至少配备多少名司机和乘务人员? 从第一班开始,试建立线性模型。
LINGO程序如下:
MODEL:
min=x1+x2+x3+x4+x5+x6;
x1+x6>=60;
x1+x2>=70;
x2+x3>=60;
x3+x4>=50;
x4+x5>=20;
x5+x6>=30;
END
得到的解为: x1=60,x2=10,x3=50,x4=0,x5=30,x6=0; 配备的司机和乘务人员最少为150人。
- 公司在各地有4项业务, 选定了4位业务员去处理. 由于业务能力、经验和其它情况不同, 4业务员处理4项业务的费用(单位:元)各不相同, 见表2。应当怎样分派任务, 才能使总的费用最小?
解: 这是一个最优指派问题. 引入如下变量:
LINGO程序如下:
MODEL:
SETS:
person/1..4/;
task/1..4/;
assign(person,task):a,x;
ENDSETS
DATA:
a=1100,800,1000,700,
600,500,300,800,
400,800,1000,900,
1100,1000,500,700;
ENDDATA
min=@sum(assign:a*x);
@for(task(j):@sum(person(i):x(i,j))=1);
@for(person(i):@sum(task(j):x(i,j))=1);
@for(assign(i,j):@bin(x(i,j)));
END
得到的结果如下:
x(1,1)=0,x(1,2)=0,x(1,3)=0,x(1,4)=1;
x(2,1)=0,x(2,2)=1,x(2,3)=0,x(2,4)=0;
x(3,1)=1,x(3,2)=0,x(3,3)=0,x(3,4)=0;
x(4,1)=0,x(4,2)=0,x(4,3)=1,x(4,4)=0;
最小费用为2100元.即第1个做第4项业务, 第2个做第2项业务, 第3个做第1项业务, 第4个做第3项业务.总费用达到最小, 为2100元。
采用数据文件方式程序:
model:
sets:
person/1..4/;
task/1..4/;
assign(person,task):a,x;
endsets
data:
a=@file(data.txt);
enddata
min=@sum(assign:a*x);
@for(person(i):@sum(task(j):x(i,j))=1);
@for(task(j):@sum(person(i):x(i,j))=1);
@for(assign(i,j):@bin(x(i,j)));
end
同时在LINGO目录下建立文本文件data.txt, 数据如下:
1100,800,1000,700
600,500,300,800
400,800,1000,900
1100,1000,500,700
- 有四种资源被用于生产三种产品, 资源量、产品单件可变费用、单件售价、资源单耗量及组织三种商品生产的固定费用用见下表.现要求制定一个生产计划,使总收益最大。
第I种产品销售一件可收入7-4=3元,第II种产品销售一件可收入10-6=4元,第III种产品销售一件可收入20-12=8元.则问题的整数规划模型见右。
得到的解为x1=100,x2=0,x3=0,y1=1,y2=0,y3=0.最大值为Z=200元.
LINGO程序.
MODEL:
DATA:
M=150;
ENDDATA
max=3*x1+4*x2+8*x3-100*y1-150*y2-200*y3;!目标函数;
2*x1+4*x2+8*x3<=500;
2*x1+3*x2+4*x3<=300;
x1+2*x2+3*x3<=100;
3*x1+5*x2+7*x3<=700;
x1<=M*y1; x2<=M*y2; x3<=M*y3;
@GIN(x1); @GIN(x2); @GIN(x3); !指定产品件数为整数;
@BIN(y1); @BIN(y2); @BIN(y3); !指定0-1变量;
end