LINGO入门学习笔记
LINGO简介:
LINGO是一种专门用于求解数学规划问题的软件包。主要用于求解线性规划问题、非线性规划、二次规划和整数规划等问题,也可以用于求解一些线性和非线性方程组及代数方程求根。
使用介绍:
LINGO模型以MODEL开始,以END结束。中间为语句,分为四大部分。
(1)集合部分(SETS):
以“SETS:”开始,以“ENDSETS”结束。这一部分的作用在定义必要的变量,便于后面编程进行大规模计算,在LINGO中称为集合(SET)及其元素和属性。
LINGO中的集合有两类:
- 第一类是原始集合,其定义的格式为:
SETNAME/member list(or1..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.
注意:
1. 所有的语句除了SETS、ENDSETS、DATA、ENDDATA、INIT、ENDINIT和MODEL,END之外必须加一个分号“;”结尾。
2.注释方法,用“!”开始,用“;”结尾。
3. LINGO求解非线性规划时已约定各变量非负。
4.LINGO不区分大小写!(好吧,这是我第一次接触不区分大小写的编程语言,总觉得怪怪。)
LINGO内部函数使用:
LINGO建立优化模型时可以引用大量内部函数,这些函数是以“@”符号打头。
(1) 常用数学函数
- @ABS(X) 返回变量X的绝对数值
- @COS(X) 返回X的余弦值,X的单位为弧度
- @EXP(X) 返回指数函数值,其中e=2.72828...
- @FLOOR(X) 向0靠近返回X的整数部分
- @LGM(X) 返回Γ函数的自然对数值
- @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: expresssion) 返回集合上表达式(expression)的最大式。
- @MIN(set_name:expression) 返回集合上的表达式(expresssion)的最小值。
- @SUM(set_name:expression) 返回集合上的表达式(expression)的和
- @SIZE(set_name) 返回数据集set_name中包含元素的个数
- @IN(set_name,set_element) 如果数据集set_name中包含元素set_element,则返回1,否则返回0.
变量界定函数:
变量函数对变量的取值范围附件限制,共有四种:
- @BND(L,X,U)限制L<=X<=U。
- @BIN(X)限制X为0或1。(为0/1规划做准备)
- @FREE(X)取消对X的符号(可取任意实数值)。
- @GIN(X)限制X为整数值。
文件调用函数:
- @file()
两道练习题
1.某昼夜服务的公交路线每天各时间区段内需司机和乘务员(见表)。设司机和乘务人员分别在各时间段一开始上班,并连续工作八小时,问该公交路线至少配备多少名司机和乘务人员?从第一班开始排,试建立线性模型 ,解决问题。
班次 | 时间 | 最少需要的人数 |
1 | 6:00——10:00 | 60 |
2 | 10:00——14:00 | 70 |
3 | 14:00——18:00 | 60 |
4 | 18:00——22:00 | 50 |
5 | 22:00——2:00 | 20 |
6 | 2:00——6:00 | 30 |
分析:
每组上班的人都要上8小时,而每4小时为一个时间段有一组人上班,则每个时刻由两组的人在上班。可以设上班的人数为x1,x2,x3,x4,x5,x6。可得方程式组:
x1+x6>=60
x2+x1>=70
x3+x2>=60
x4+x3>=50
x5+x4>=20
x6+x5>=30
x1,x2....x6>=0
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
Ctrl+U或点击同心圆型的按钮,运行。
得到结果:x1=60,x2=10,x3=50,x4=0,x5=30,x6=0;配备的司机和乘务员最少为150人。
2.公司在各地有4项业务,选定了4位业务员去处理。由于业务能力、经验和其它情况不同,四位业务员处理4项业务的费用(单位:元)各不相同,见表。应当怎样分派任务,才能使总的费用最小?
业务员\业务 | 1 | 2 | 3 | 4 |
1 | 1100 | 800 | 1000 | 700 |
2 | 600 | 500 | 300 | 800 |
3 | 400 | 800 | 300 | 800 |
4 | 1100 | 1000 | 500 | 700 |
表2: 业务的费用表
解答示例图
0 | 0|0|1|
0 | 1|0|0|
1|0|0|0|
0|0|1|0|
可以看出,每一行,每一列的和都为1
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
结果:最小值为2100
数据 也可以用导入文件的方式
LINGO程序为
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(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
同时在LINGO目录下建立一个data.txt文件,数据为:
1100,800,1000,700,
600,500,300,800,
400,800,1000,900,
1100,1000,500,700;
看着电脑里不知道什么时候安的LINGO,自己又不会用,觉得挺丢人的。想找一套教学视频学学,找了一圈有没找到,只找到一点视频。先学学入个门,有一个感性的认识。等开了运筹学的课后,若有需要再好好学学。
来源于中国大学MOOK,《数学建模》西北工业大学,第1章1.3节。侵删
-------------------------------------------------------------------------------------
感觉我现在学的运筹学好水,这点东西基本上就够了。。。。。
感觉上了个假大学。。。。