Lingo基本用法总结.docx
《Lingo基本用法总结.docx》由会员分享,可在线阅读,更多相关《Lingo基本用法总结.docx(94页珍藏版)》请在冰豆网上搜索。
Lingo基本用法总结
Lingo基本用法总结(除集函数部分)
LINGO是用来求解线性和非线性优化问题的简易工具。
Lingo免费版可以支持30个未知数,lingo破解版可以支持几万个未知数、几万个约束条件。
当你在windows下开始运行LINGO系统时,会得到类似下面的一个窗口:
外层是主框架窗口,包含了所有菜单命令和工具条,其它所有的窗口将被包含在主窗口之下。
在主窗口内的标题为LINGOModel–LINGO1的窗口是LINGO的默认模型窗口,建立的模型都都要在该窗口内编码实现。
下面举两个例子。
例1.1如何在LINGO中求解如下的LP问题:
在模型窗口中输入如下代码:
min=2*x1+3*x2;
x1+x2>=350;
x1>=100;
2*x1+x2<=600;
然后点击工具条上的按钮
即可。
得到如下结果:
所以当x1为250,x2为100时目标函数得到最大值。
●算术运算符
Lingo中变量不区分大小写,以字母开头不超过32个字符
算术运算符是针对数值进行操作的。
LINGO提供了5种二元运算符:
^ 乘方﹡ 乘/ 除﹢ 加﹣ 减
LINGO唯一的一元算术运算符是取反函数“﹣”。
这些运算符的优先级由高到底为:
高 ﹣(取反)
^
﹡/
低 ﹢﹣
运算符的运算次序为从左到右按优先级高低来执行。
运算的次序可以用圆括号“()”来改变。
例:
在x1+x2>=350,x1>=100,2*x1+x2<=600的条件下求2*x1+3*x2的最小值
在代码窗口中编写
min=2*x1+3*x2;
x1+x2>=350;
x1>=100;
2*x1+x2<=600;
然后单击上面菜单lingo菜单下solve键即可。
●数学函数
标准数学函数:
@abs(x)返回x的绝对值
@sin(x)返回x的正弦值,x采用弧度制
@cos(x)返回x的余弦值
@tan(x)返回x的正切值
@exp(x)返回常数e的x次方
@log(x)返回x的自然对数
@lgm(x)返回x的gamma函数的自然对数
@sign(x)如果x<0返回-1;否则,返回1
@floor(x)返回x的整数部分。
当x>=0时,返回不超过x的最大整数;当x<0时,返回不低于x的最大整数。
最大最小函数:
@smax(x1,x2,…,xn)返回x1,x2,…,xn中的最大值
@smin(x1,x2,…,xn)返回x1,x2,…,xn中的最小值
边界限定函数:
@bin(x)限制x为0或1
@bnd(L,x,U)限制L≤x≤U
@free(x)取消对变量x的默认下界为0的限制,即x可以取任意实数
@gin(x)限制x为整数
辅助函数
1.@if(logical_condition,true_result,false_result)
@if函数将评价一个逻辑表达式logical_condition,如果为真,返回true_result,否则返回false_result
在默认情况下,LINGO规定变量是非负的,也就是说下界为0,上界为+∞。
@free取消了默认的下界为0的限制,使变量也可以取负值。
@bnd用于设定一个变量的上下界,它也可以取消默认下界为0的约束。
例:
求
其中x1只能取0或1;x2为整数
在代码窗口中编写
min=x1^2+3*x2-x1*x2+@exp(x3);
x1+x2>=350;
x1+x3<50;
2*x1+x2+x3<=600;
@bin(x1);@gin(x2);
以上是lingo最基本的用法
●逻辑运算符
LINGO具有9种逻辑运算符:
#not# 否定该操作数的逻辑值,#not#是一个一元运算符
#eq# 若两个运算数相等,则为true;否则为flase
#ne#若两个运算符不相等,则为true;否则为flase
#gt#若左边的运算符严格大于右边的运算符,则为true;否则为flase
#ge# 若左边的运算符大于或等于右边的运算符,则为true;否则为flase
#lt# 若左边的运算符严格小于右边的运算符,则为true;否则为flase
#le# 若左边的运算符小于或等于右边的运算符,则为true;否则为flase
#and# 仅当两个参数都为true时,结果为true;否则为flase
#or#仅当两个参数都为false时,结果为false;否则为true
这些运算符的优先级由高到低为:
高#not#
#eq##ne##gt##ge##lt##le#
低#and##or#
例4.2逻辑运算符示例
2#gt#3#and#4#gt#2,其结果为假(0)。
●模型求解状态
@status()
返回LINGO求解模型结束后的状态:
0GlobalOptimum(全局最优)
1Infeasible(不可行)
2Unbounded(无界)
3Undetermined(不确定)
4Feasible(可行)
5InfeasibleorUnbounded(通常需要关闭“预处理”选项后重新求解模型,以确定模型究竟是不可行还是无界)
6LocalOptimum(局部最优)
7LocallyInfeasible(局部不可行,尽管可行解可能存在,但是LINGO并没有找到一个)
8Cutoff(目标函数的截断值被达到)
9NumericError(求解器因在某约束中遇到无定义的算术运算而停止)
通常,如果返回值不是0、4或6时,那么解将不可信,几乎不能用。
该函数仅被用在模型的数据部分来输出数据。
解窗口说明
例5.1某家具公司制造书桌、餐桌和椅子,所用的资源有三种:
木料、木工和漆工。
生产数据如下表所示:
每个书桌
每个餐桌
每个椅子
现有资源总数
木料
8单位
6单位
1单位
48单位
漆工
4单位
2单位
1.5单位
20单位
木工
2单位
1.5单位
0.5单位
8单位
成品单价
60单位
30单位
20单位
若要求桌子的生产量不超过5件,如何安排三种产品的生产可使利润最大?
用DESKS、TABLES和CHAIRS分别表示三种产品的生产量,建立LP模型。
max=60*desks+30*tables+20*chairs;
8*desks+6*tables+chairs<=48;
4*desks+2*tables+1.5*chairs<=20;
2*desks+1.5*tables+.5*chairs<=8;
tables<=5;
求解这个模型,并激活灵敏性分析。
这时,查看报告窗口(ReportsWindow),可以看到如下结果。
“Globaloptimalsolutionfoundatiteration:
3”表示3次迭代后得到全局最优解。
“Objectivevalue:
280.0000”表示最优目标值为280。
“Value”给出最优解中各变量的值:
造2个书桌(desks),0个餐桌(tables),8个椅子(chairs)。
所以desks、chairs是基变量(非0),tables是非基变量(0)。
“SlackorSurplus”给出松驰变量的值:
第1行松驰变量=280(模型第一行表示目标函数,所以第二行对应第一个约束)
第2行松驰变量=24
第3行松驰变量=0
第4行松驰变量=0
第5行松驰变量=5
“ReducedCost”列出最优单纯形表中判别数所在行的变量的系数,表示当变量有微小变动时,目标函数的变化率。
其中基变量的reducedcost值应为0,对于非基变量Xj,相应的reducedcost值表示当某个变量Xj增加一个单位时目标函数减少的量(max型问题)。
本例中:
变量tables对应的reducedcost值为5,表示当非基变量tables的值从0变为1时(此时假定其他非基变量保持不变,但为了满足约束条件,基变量显然会发生变化),最优的目标函数值=280-5=275。
“DUALPRICE”(对偶价格)表示当对应约束有微小变动时,目标函数的变化率。
输出结果中对应于每一个约束有一个对偶价格。
若其数值为p,表示对应约束中不等式右端项若增加1个单位,目标函数将增加p个单位(max型问题)。
显然,如果在最优解处约束正好取等号(也就是“紧约束”,也称为有效约束或起作用约束),对偶价格值才可能不是0。
本例中:
第3、4行是紧约束,对应的对偶价格值为10,表示当紧约束
3)4DESKS+2TABLES+1.5CHAIRS<=20
变为3)4DESKS+2TABLES+1.5CHAIRS<=21
时,目标函数值=280+10=290。
对第4行也类似。
对于非紧约束(如本例中第2、5行是非紧约束),DUALPRICE的值为0,表示对应约束中不等式右端项的微小扰动不影响目标函数。
有时,通过分析DUALPRICE,也可对产生不可行问题的原因有所了解。
灵敏度分析的结果是
Rangesinwhichthebasisisunchanged:
ObjectiveCoefficientRanges
CurrentAllowableAllowable
VariableCoefficientIncreaseDecrease
DESKS60.000000.00.0
TABLES30.000000.00.0
CHAIRS20.000000.00.0
RighthandSideRanges
RowCurrentAllowableAllowable
RHSIncreaseDecrease
248.000000.00.0
320.000000.00.0
48.0000000.00.0
55.0000000.00.0
目标函数中DESKS变量原来的费用系数为60,允许增加(AllowableIncrease)=4、允许减少(AllowableDecrease)=2,说明当它在[60-4,60+20]=[56,80]范围变化时,最优基保持不变。
对TABLES、CHAIRS变量,可以类似解释。
由于此时约束没有变化(只是目标函数中某个费用系数发生变化),所以最优基保持不变的意思也就是最优解不变(当然,由于目标函数中费用系数发生了变化,所以最优值会变化)。
第2行约束中右端项(RightHandSide,简写为RHS)原来为48,当它在[48-24,48+∞]=[24,∞]范围变化时,最优基保持不变。
第3、4、5行可以类似解释。
不过由于此时约束发生变化,最优基即使不变,最优解、最优值也会发生变化。
灵敏性分析结果表示的是最优基保持不变的系数范围。
由此,也可以进一步确定当目标函数的费用系数和约束右端项发生小的变化时,最优基和最优解、最优值如何变化。
下面我们通过求解一个实际问题来进行说明。
例5.2一奶制品加工厂用牛奶生产A1,A2两种奶制品,1桶牛奶可以在甲车间用12小时加工成3公斤A1,或者在乙车间用8小时加工成4公斤A2。
根据市场需求,生产的A1,A2全部能售出,且每公斤A1获利24元,每公斤A2获利16元。
现在加工厂每天能得到50桶牛奶的供应,每天正式工人总的劳动时间480小时,并且甲车间每天至多能加工100公斤A1,乙车间的加工能力没有限制。
试为该厂制订一个生产计划,使每天获利最大,并进一步讨论以下3个附加问题:
1)若用35元可以买到1桶牛奶,应否作这项投资?
若投资,每天最多购买多少桶牛奶?
2)若可以聘用临时工人以增加劳动时间,付给临时工人的工资最多是每小时几元?
3)由于市场需求变化,每公斤A1的获利增加到30元,应否改变生产计划?
模型代码如下:
max=72*x1+64*x2;
x1+x2<=50;
12*x1+8*x2<=480;
3*x1<=100;
求解这个模型并做灵敏性分析,结果如下。
Globaloptimalsolutionfoundatiteration:
0
Objectivevalue:
3360.000
VariableValueReducedCost
X120.000000.000000
X230.000000.000000
RowSlackorSurplusDualPrice
13360.0001.000000
20.00000048.00000
30.0000002.000000
440.000000.000000
Rangesinwhichthebasisisunchanged:
ObjectiveCoefficientRanges
CurrentAllowableAllowable
VariableCoefficientIncreaseDecrease
X172.0000024.000008.000000
X264.000008.00000016.00000
RighthandSideRanges
RowCurrentAllowableAllowable
RHSIncreaseDecrease
250.0000010.000006.666667
3480.000053.3333380.00000
4100.0000INFINITY40.00000
结果告诉我们:
这个线性规划的最优解为x1=20,x2=30,最优值为z=3360,即用20桶牛奶生产A1,30桶牛奶生产A2,可获最大利润3360元。
输出中除了告诉我们问题的最优解和最优值以外,还有许多对分析结果有用的信息,下面结合题目中提出的3个附加问题给予说明。
3个约束条件的右端不妨看作3种“资源”:
原料、劳动时间、车间甲的加工能力。
输出中SlackorSurplus给出这3种资源在最优解下是否有剩余:
原料、劳动时间的剩余均为零,车间甲尚余40(公斤)加工能力。
目标函数可以看作“效益”,成为紧约束的“资源”一旦增加,“效益”必然跟着增长。
输出中DUALPRICES给出这3种资源在最优解下“资源”增加1个单位时“效益”的增量:
原料增加1个单位(1桶牛奶)时利润增长48(元),劳动时间增加1个单位(1小时)时利润增长2(元),而增加非紧约束车间甲的能力显然不会使利润增长。
这里,“效益”的增量可以看作“资源”的潜在价值,经济学上称为影子价格,即1桶牛奶的影子价格为48元,1小时劳动的影子价格为2元,车间甲的影子价格为零。
读者可以用直接求解的办法验证上面的结论,即将输入文件中原料约束milk)右端的50改为51,看看得到的最优值(利润)是否恰好增长48(元)。
用影子价格的概念很容易回答附加问题1):
用35元可以买到1桶牛奶,低于1桶牛奶的影子价格48,当然应该作这项投资。
回答附加问题2):
聘用临时工人以增加劳动时间,付给的工资低于劳动时间的影子价格才可以增加利润,所以工资最多是每小时2元。
目标函数的系数发生变化时(假定约束条件不变),最优解和最优值会改变吗?
这个问题不能简单地回答。
上面输出给出了最优基不变条件下目标函数系数的允许变化范围:
x1的系数为(72-8,72+24)=(64,96);x2的系数为(64-16,64+8)=(48,72)。
注意:
x1系数的允许范围需要x2系数64不变,反之亦然。
由于目标函数的费用系数变化并不影响约束条件,因此此时最优基不变可以保证最优解也不变,但最优值变化。
用这个结果很容易回答附加问题3):
若每公斤A1的获利增加到30元,则x1系数变为30×3=90,在允许范围内,所以不应改变生产计划,但最优值变为90×20+64×30=3720。
下面对“资源”的影子价格作进一步的分析。
影子价格的作用(即在最优解下“资源”增加1个单位时“效益”的增量)是有限制的。
每增加1桶牛奶利润增长48元(影子价格),但是,上9
面输出的CURRENTRHS的ALLOWABLEINCREASE和ALLOWABLEDECREASE给出了影子价格有意义条件下约束右端的限制范围:
milk)原料最多增加10(桶牛奶),time)劳动时间最多增加53(小时)。
现在可以回答附加问题1)的第2问:
虽然应该批准用35元买1桶牛奶的投资,但每天最多购买10桶牛奶。
顺便地说,可以用低于每小时2元的工资聘用临时工人以增加劳动时间,但最多增加53.3333小时。
需要注意的是:
灵敏性分析给出的只是最优基保持不变的充分条件,而不一定是必要条件。
比如对于上面的问题,“原料最多增加10(桶牛奶)”的含义只能是“原料增加10(桶牛奶)”时最优基保持不变,所以影子价格有意义,即利润的增加大于牛奶的投资。
反过来,原料增加超过10(桶牛奶),影子价格是否一定没有意义?
最优基是否一定改变?
一般来说,这是不能从灵敏性分析报告中直接得到的。
此时,应该重新用新数据求解规划模型,才能做出判断。
所以,从正常理解的角度来看,我们上面回答“原料最多增加10(桶牛奶)”并不是完全科学的。
LINGO是用来求解线性和非线性优化问题的简易工具。
LINGO内置了一种建立最优化模型的语言,可以简便地表达大规模问题,利用LINGO高效的求解器可快速求解并分析结果。
§1LINGO快速入门
当你在windows下开始运行LINGO系统时,会得到类似下面的一个窗口:
外层是主框架窗口,包含了所有菜单命令和工具条,其它所有的窗口将被包含在主窗口之下。
在主窗口内的标题为LINGOModel–LINGO1的窗口是LINGO的默认模型窗口,建立的模型都都要在该窗口内编码实现。
下面举两个例子。
例1.1如何在LINGO中求解如下的LP问题:
在x1+x2>=350,x1>=100,2*x1+x2<=600的条件下求2*x1+3*x2的最小值.
在模型窗口中输入如下代码:
min=2*x1+3*x2;
x1+x2>=350;
x1>=100;
2*x1+x2<=600;
然后点击工具条上的按钮
即可。
例1.2使用LINGO软件计算6个发点8个收点的最小费用运输问题。
产销单位运价如下表。
单
位销地
运
价
产地
B1
B2
B3
B4
B5
B6
B7
B8
产量
A1
6
2
6
7
4
2
5
9
60
A2
4
9
5
3
8
5
8
2
55
A3
5
2
1
9
7
4
3
3
51
A4
7
6
7
3
9
2
7
1
43
A5
2
3
9
5
7
2
6
5
41
A6
5
5
2
2
8
1
4
3
52
销量
35
37
22
32
41
32
43
38
使用LINGO软件,编制程序如下:
model:
!
6发点8收点运输问题;
sets:
warehouses/wh1..wh6/:
capacity;
vendors/v1..v8/:
demand;
links(warehouses,vendors):
cost,volume;
endsets
!
目标函数;
min=@sum(links:
cost*volume);
!
需求约束;
@for(vendors(J):
@sum(warehouses(I):
volume(I,J))=demand(J));
!
产量约束;
@for(warehouses(I):
@sum(vendors(J):
volume(I,J))<=capacity(I));
!
这里是数据;
data:
capacity=605551434152;
demand=3537223241324338;
cost=62674295
49538582
52197433
76739271
23957265
55228143;
enddata
end
然后点击工具条上的按钮
即可。
为了能够使用LINGO的强大功能,接着第二节的学习吧。
§2LINGO中的集
对实际问题建模的时候,总会遇到一群或多群相联系的对象,比如工厂、消费者群体、交通工具和雇工等等。
LINGO允许把这些相联系的对象聚合成集(sets)。
一旦把对象聚合成集,就可以利用集来最大限度的发挥LINGO建模语言的优势。
现在我们将深入介绍如何创建集,并用数据初始化集的属性。
学完本节后,你对基于建模技术的集如何引入模型会有一个基本的理解。
2.1为什么使用集
集是LINGO建模语言的基础,是程序设计最强有力的基本构件。
借助于集,能够用一个单一的、长的、简明的复合公式表示一系列相似的约束,从而可以快速方便地表达规模较大的模型。
2.2什么是集
集是一群相联系的对象,这些对象也称为集的成员。
一个集可能是一系列产品、卡车或雇员。
每个集成员可能有一个或多个与之有关联的特征,我们把这些特征称为属性。
属性值可以预先给定,也可以是未知的,有待于LINGO求解。
例如,产品集中的每个产品可以有一个价格属性;卡车集中的每辆卡车可以有一个牵引力属性;雇员集中的每位雇员可以有一个薪水属性,也可以有一个生日属性等等。
LINGO有两种类型的集:
原始集(primitive set)和派生集(derivedset)。
一个原始集是由一些最基本的对象组成的。
一个派生集是用一个或多个其它集来定义的,也就是说,它的成员来自于其它已存在的集。
2.3模型的集部分
集部分是LINGO模型的一个可选部分。
在LINGO模型中使用集之前,必须在集部分事先定义。
集部分以关键字“sets:
”开始,以“endsets”结束。
一个模型可以没有集部分,或有一个简单的集部分,或有多个集部分。
一个集部分可以放置于模型的任何地方,但是一个集及其属性在模型约束中被引用之前必须定义了它们。
2.3.1定义原始集
为了定义一个原始集,必须详细声明:
·集的名字
·可选,集的成员
·可选,集成员的属性
定义一个原始集,用下面的语法:
setname[/member_list/][:
attribute_list];
注意:
用“[]”表示该部分内容可选。
下同,不再赘述。
Setname是你选择的来标记集的名字,最好具有较强的可读性。
集名字必须严格符合标准命名规则:
以拉丁字母或下划线(_)为首字符,其后由拉丁字母(A—Z)、下划线、阿拉伯数字(0,1,…,9)组成的总长度不超过32个字符的字符串,且不区分大小写。
注意:
该命名规则同样适用于集成员名和属性名等的命名。
Member_list是集成员列表。
如果集成员放在集定义中,那么对它们可采取显式罗列和隐式罗列两种方式。
如果集成员不放在集定义中,那么可以在随后的数据部分定义它们。
①当显式罗列成员时,必须为