第10章Lingo软件包及其应用.docx
《第10章Lingo软件包及其应用.docx》由会员分享,可在线阅读,更多相关《第10章Lingo软件包及其应用.docx(31页珍藏版)》请在冰豆网上搜索。
![第10章Lingo软件包及其应用.docx](https://file1.bdocx.com/fileroot1/2023-2/9/9ed07351-b98d-4c83-9e79-2b0971d090b4/9ed07351-b98d-4c83-9e79-2b0971d090b41.gif)
第10章Lingo软件包及其应用
第十章Lingo软件包及其应用
Lingo软件包是一种专门用来求解数学规划和优化问题的软件包,由美国芝加哥大学的LinusSchrage教授创立的Lindo系统公司开发出来,可以在Windows和Linux环境下运行,同一版次具有不同的版本,如:
演示版(试用版)、学生班、高级版、超级版、工业版、扩展版等等,不同的版本对求解问题的规模、变量数目和约束条件的限制不同。
对于Lingo软件包来说,编写很简单的程序就能调用大量的外部已有数据进行优化计算,是其出色的亮点。
§9.1Lingo软件包的基础知识
(一)Lingo软件包的运算符
(1)算术运算符(ArithmeticOperators)
—取反(negation)^乘方(Exponentiation)
*乘法(Multiplication)/除(Division)
+加(Addition)—减(Subtraction)
(2)逻辑运算符
Lingo软件包的逻辑运算符,主要用于优化计算中定义各种逻辑条件。
逻辑运算符为:
#NOT#非运算
#EQ#相等
#NE#不相等
#GT#严格大于
#GE#大于等于
#LT#严格小于
#LE#小于等于
#AND#与
#OR#或
(3)关系运算符
Lingo软件包中的关系运算符用在数学表达式中。
=等号
<=小于等于
>=大于等于
注:
Lingo软件包不支持严格大于和严格小于,即,在Lingo软件包的数学表达式中“>”等价于“>=”,“<”等价于“<=”。
运算符的运算优先级(PriorityLevel)由高到低依次为:
优先级运算符
最高级#NOT#—(negation)
^
*/
+-
#EQ##NE##GT##GE##LT##LE#
#AND##OR#
最低级<==>=
(4)Lingo软件包的内部函数
Lingo软件包提供下列内部函数:
@ABS(X)绝对值函数
@COS(X)余弦函数
@EXP(X)
函数
@FLOOR(X)小于X的最大整数
@LGM(X)
,即
的自然对数
@LOG(X)自然对数
@SIGN(X)符号函数,当X<0时,取值-1,否则取值+1
@SIN(X)正弦函数
@SMAX(X1,X2,...,XN)求最大
@SMIN(X1,X2,...,XN)求最小
@TAN(X)正切函数
@IFIf函数,使用格式为:
@IF(条件,T,F),即,条件为真时,得到T,否则得到F。
@SUM求和函数
@FREE(X)取消变量X的非负限制(Lingo在求解优化问题时,默认所有变量非负)
@FOR优化计算时,用于限定约束条件
@bin(X)限定X是(0,1)变量
@bnd(下界,X,上界)限定下界
X
上界
@gin(X)限定X为整数变量
例如,@FOR(A(i,j)|a(i,j)#gt#0:
@bin(x(i,j)))表示限定矩阵A中元素:
当
时,对应的变量
是(0,1)变量。
注:
(1)在Lingo软件包中调用内部函数,一定要以@符号开头。
(2)在Lingo软件包中,model、sets、data以“:
”结尾,其它语句每行都以“;”结尾,endsets、enddata、end尾部不加任何符号。
(3)以!
开头,书写注释行,结尾用“;”。
(4)在Lingo软件包中,不能写100x,要写成100*x
(5)无论是否是求解优化问题,Lingo的结果中都有松弛分析(SlackorSurplus)
(6)Lingo软件包求解时,已经假设所有变量
0
例10-1在Lingo软件包中编写如下程序:
model:
data:
m=?
;
n=?
;
enddata
f=@sin(m)+@cos(n);
end
执行后,依次输入
、
,得到结果:
Feasiblesolutionfoundatiteration:
0
VariableValue
M1.000000
N2.000000
F0.4253241
RowSlackorSurplus
10.000000
注:
如果输入
、
,则,得不到有效的结果,这说明Lingo软件包不能做通常的数学计算,它的优点在于优化计算。
(5)Lingo软件包编程的基本格式
格式1model:
开头,end结尾
格式2model:
开头,结尾省略end
格式3省略model:
和end
例10-2在Lingo软件包中,求解下列线性规划问题:
Lingo软件包中优化程序如下:
model:
max=100*x+150*y;
x<=100;
y<=120;
x+2*y<=160;
end
执行后得到结果:
Globaloptimalsolutionfoundatiteration:
0
Objectivevalue:
14500.00
VariableValueReducedCost
X100.00000.000000
Y30.000000.000000
RowSlackorSurplusDualPrice
114500.001.000000
20.00000025.00000
390.000000.000000
40.00000075.00000
即,目标函数
,最优解
。
例10-3在Lingo软件包中,利用FREE函数的功能,可以求解变量可取负值的优化问题;利用IF函数,可以求解分段函数的优化问题:
Lingo软件包中优化程序如下:
model:
min=fx+fy;
fx=@if(x#gt#0,100,0)+2*x;
fy=@if(y#gt#0,60+3*y,2*y);
x+y>30;
@free(x);@free(y);
end
执行后得到结果:
Linearizationcomponentsadded:
Constraints:
30
Variables:
20
Integers:
12
Globaloptimalsolutionfoundatiteration:
34
Objectivevalue:
150.0000
VariableValueReducedCost
FX0.0000000.000000
FY150.00000.000000
X0.0000000.000000
Y30.000000.000000
RowSlackorSurplusDualPrice
1150.0000-1.000000
20.000000-1.000000
30.000000-1.000000
40.000000-3.000000
即,目标函数
,最优解
。
注:
在Mathematica软件包中,编程画图如下:
Plot[{0,If[x>0,2x+100,2x]+If[x<30,60+3(30-x),2(30-x)]},{x,-40,40}]
执行后得到图形如下:
例10-4在Lingo软件包中,求解下列变量可取负值的优化问题:
在Lingo软件包中编程如下:
min=4*x1^2-x2^2+2*x3^2+12;
3*x1+2*x2+x3=9;
x1+x2+x3=-1;
@free(x1);@free(x2);@free(x3);
执行后得到结果:
Localoptimalsolutionfoundatiteration:
6
Objectivevalue:
152.0000
VariableValueReducedCost
X10.9999950-0.5434437E-08
X28.0000100.000000
X3-10.000010.000000
RowSlackorSurplusDualPrice
1152.0000-1.000000
20.000000-23.99999
30.00000064.00000
即,目标函数
,最优解
。
§9.2利用Lingo求解不等式组和方程组
Lingo软件包可以有效地求解不等式组,特别是非线性不等式组,这是Lingo软件包的特色之一。
不过,Lingo求解不等式组只能给出单独的解,而不能给出区间解。
在求解方程组时,只能求解实数解。
例10-5在Lingo软件包中,求解下列非线性不等式组:
在Lingo软件包中编程如下:
model:
3*x1*y1+x3*y1+3*x2*y2+x3*y2>=3*y1;
3*x1*y1+x3*y1+3*x2*y2+x3*y2>=3*y2;
3*x1*y1+x3*y1+3*x2*y2+x3*y2>=y1+y2;
x1*y1+2*x2*y1+3*x3*y1+2*x1*y2+3*x2*y2+x3*y2>=x1+2*x2+3*x3;
x1*y1+2*x2*y1+3*x3*y1+2*x1*y2+3*x2*y2+x3*y2>=2*x1+3*x2+x3;
x1+x2+x3=1;
y1+y2=1;
执行后得到结果:
Feasiblesolutionfoundatiteration:
72
VariableValue
X10.000000
Y10.000000
X30.000000
X21.000000
Y21.000000
RowSlackorSurplus
13.000000
20.000000
32.000000
41.000000
50.000000
60.000000
70.000000
即,得到此不等式组的一组解:
例10-6在Lingo软件包中,求解下列方程组:
解:
在Lingo软件包中编程如下:
model:
x1^3+x2^3+x3^3=3;
x1^2+x2^2+x3^2=2;
x1+x2+x3=1;
@free(x1);
@free(x2);
@free(x3);
执行后,Lingo提示没有得到可行解(即,没有得到实数解),给出的结果是:
VariableValue
X1-0.2228950
X21.445790
X3-0.2228950
RowSlackorSurplus
10.000000
2-0.1896733
30.000000
我们可以验证
不是方程组的解。
例10-7在Lingo软件包中
(1)求解
,其中
表示自然对数。
在Lingo软件包中编程如下:
@log(x)-@sin(x)=0;
执行后得到结果:
Feasiblesolutionfoundatiteration:
0
VariableValue
X2.219107
RowSlackorSurplus
10.000000
即,得到方程的根
。
(2)求解
,其中
表示以10为底的常用对数。
在Lingo软件包中编程如下:
@log(x)/@log(10)-@sin(x)=0;
执行后得到结果:
Feasiblesolutionfoundatiteration:
0
VariableValue
X2.696257
RowSlackorSurplus
10.000000
即,得到方程的根
。
注:
此方程共有3个根(用Mathematica软件包求出的根是:
,
,
),Lingo软件包只能求出一个根。
§9.3应用Lingo软件包求解大型优化问题
(1)关于数据的输入
Lingo软件包的一大特点是,可以调用外部已有的大型数据进行优化计算,这些数据可以是以Excel格式存盘,也可以是以TEXT文本格式存盘,或者是数据库中的已有数据。
在Lingo软件包中,调用外部数据的函数有:
@FILE('filename')调用TEXT文本数据;
@OLE('spreadsheet_file'[,range_name_list])调用以Excel格式存盘的数据,其中range_name_list表示Excel数据的范围。
@ODBC(['data_source'[,'table_name'[,'col_1'[,'col_2'...]]]])调用数据库中的数据文件。
例10-8在Lingo软件包中,数据部分可以如下编写程序:
①
data:
c=@file(‘f:
\pianai.tex’);
enddata
②
data:
ca=@file(‘d:
\b.txt’);
a=@ole(‘d:
\data.xls’,ca);
enddata
其中ca表示Excel数据的取值范围。
(2)关于集的定义
①定义向量
在Lingo软件包中,以下列格式定义向量:
集合名称/集合的维数/:
向量名称
例如:
set1/1..3/:
x,y;
set2/1..4/:
a,b;
表示定义了第一类集合set1,维数是3,具体向量名称为x和y,即,定义了
和
同时定义了第二类集合set2,维数是4,具体向量名称为a和b,即,定义了
和
②定义矩阵
在Lingo软件包中,利用已经定义的向量来定义矩阵,格式为:
矩阵名称(集合名称1,集合名称2)/:
矩阵名称
例如:
set1/1..3/:
x,y;
set2/1..4/:
a,b;
link(set1,set2)/:
A,Q;
表示定义了3×4阶的矩阵link,具体矩阵的名称为A和Q
③定义超级矩阵
下面的程序定义了一个2×3×2的超级矩阵x:
sets:
student/A,B/;
class/1..3/;
subject/Math,English/;
score(student,class,subject):
x;
endsets
执行后得到结果:
Feasiblesolutionfoundatiteration:
0
VariableValue
X(A,1,MATH)1.234568
X(A,1,ENGLISH)1.234568
X(A,2,MATH)1.234568
X(A,2,ENGLISH)1.234568
X(A,3,MATH)1.234568
X(A,3,ENGLISH)1.234568
X(B,1,MATH)1.234568
X(B,1,ENGLISH)1.234568
X(B,2,MATH)1.234568
X(B,2,ENGLISH)1.234568
X(B,3,MATH)1.234568
X(B,3,ENGLISH)1.234568
其中Value的值是随机取值的,在具体问题中需要使用Data命令赋值。
例10-9在Lingo软件包中,求解下列不等式组:
其中,
表示矩阵
的第
行,
表示矩阵
的第
列。
解:
在Lingo软件包中,编写程序如下:
model:
sets:
set1/1..2/:
x;
set2/1..2/:
y;
link(set1,set2):
a,b;
endsets
@for(set1(i):
@sum(set1(k):
x(k))=1);
@for(set2(j):
@sum(set2(k):
y(k))=1);
@for(link(i,j):
@sum(link(p,q):
x(p)*a(p,q)*y(q))
>=@sum(link(i,q):
a(i,q)*y(q)));
@for(link(i,j):
@sum(link(p,q):
x(p)*b(p,q)*y(q))
>=@sum(link(t,j):
x(t)*b(t,j)));
data:
a=70100
40140;
b=7040
100140;
enddata
end
执行后得到结果如下:
Feasiblesolutionfoundatiteration:
8
VariableValue
X
(1)1.000000
X
(2)0.000000
Y
(1)1.000000
Y
(2)0.000000
A(1,1)70.00000
A(1,2)100.0000
A(2,1)40.00000
A(2,2)140.0000
B(1,1)70.00000
B(1,2)40.00000
B(2,1)100.0000
B(2,2)140.0000
RowSlackorSurplus
10.000000
20.000000
30.000000
40.000000
50.000000
60.000000
730.00000
830.00000
90.000000
1030.00000
110.000000
1230.00000
即,得到不等式组的解
。
例10-10一家工厂生产甲乙两种产品(单位:
吨),生产甲每吨需要消耗煤20吨、电30千瓦小时、人工30个,净利润11万元,生产乙每吨需要消耗煤30吨、电25千瓦小时、人工35个,净利润15万元,另外,在一个生产周期中,这家工厂拥有可调配的资源为煤360吨、电2000千瓦小时、人工300个。
求最优生产方案。
解:
假设生产甲x1吨、乙x2吨,则,数学模型为
在这个例子中,有两个2维向量:
利润lirun=(11,15),和x=(x1,x2),一个3维向量b=(360,2000,300),以及一个3×2的系数矩阵
①在Mathematica软件包中,求得最优解(精确值)为
,
化为近似值是
。
②在Lingo软件包中输入程序如下:
model:
sets:
set1/1..2/:
lirun,x;
set2/1..3/:
b;
link(set2,set1):
A;
endsets
max=@sum(set1(j):
lirun(j)*x(j));
@for(set2(i):
[supply]@sum(link(i,j):
A(i,j)*x(j))<=b(i));
!
这里的supply是把约束条件命名(自己的意愿),方便分析灵敏度;
data:
lirun=1115;
b=3602000300;
A=2030
3025
3035;
enddata
执行后得到结果:
Globaloptimalsolutionfoundatiteration:
1
Objectivevalue:
128.5714
VariableValueReducedCost
LIRUN
(1)11.000000.000000
LIRUN
(2)15.000000.000000
X
(1)0.0000001.857143
X
(2)8.5714290.000000
B
(1)360.00000.000000
B
(2)2000.0000.000000
B(3)300.00000.000000
A(1,1)20.000000.000000
A(1,2)30.000000.000000
A(2,1)30.000000.000000
A(2,2)25.000000.000000
A(3,1)30.000000.000000
A(3,2)35.000000.000000
RowSlackorSurplusDualPrice
1128.57141.000000
SUPPLY
(1)102.85710.000000
SUPPLY
(2)1785.7140.000000
SUPPLY(3)0.0000000.4285714
可见,Lingo软件包不光求出了最优解,而且还给出了剩余变量(slack)的值,以及对偶问题(Dual)的解。
尤其是,当系数矩阵A很大时,用Lingo软件包编写简单的程序,就可调用外部A的数据,十分方便。
例10-11长500Cm的条材,截长分别为98Cm、78Cm的毛坯,要98Cm的1万根,78Cm的2万根。
怎样截,材料最省?
解:
截法C1:
截98Cm的0根、78Cm的6根、废料32Cm;
C2:
98Cm的1根、78Cm的5根、废料12Cm;
C3:
98Cm的2根、78Cm的3根、废料70Cm;
C4:
98Cm的3根、78Cm的2根、废料50Cm;
C5:
98Cm的4根、78Cm的1根、废料30Cm;
C6:
98Cm的5根、78Cm的0根、废料10Cm;
假设xj根条材按Cj法截,则,数学模型为:
此模型中有一个2维向量
,一个6维向量
,以及一个2×6的系数矩阵A。
首先将系数矩阵A的数据作为Excel数据存盘,目录为:
C:
\Lingo8\gangguan.xls
注意:
数据范围是A1到F2。
然后,在Lingo软件包中,输入下列程序:
model:
sets:
set1/1..2/:
b;
set2/1..6/:
x;
link(set1,set2):
A;
endsets
min=@sum(set2(i):
x(i));
@for(set1(i):
@sum(link(i,j):
A(i,j)*x(j))>b(i));
@for(set2(i):
@gin(x(i)));
data:
b=1000020000;
A=@ole('c:
\lingo8\gangguan.xls','A1:
F2');
enddata
其中@for(set2(i):
@gin(x(i)));表示限定变量x(i)都是整数变量;
A=@ole('c:
\lingo8\gangguan.xls','A1:
F2');表示调用外部数据A,并且指明了数据的取值范围,从A1到F2。
执行后得到下列结果:
Globaloptimalsolutionfoundatiteration:
4
Objectivevalue:
5200.000
VariableValueReducedCost
B
(1)10000.000.000000
B
(2)20000.000.000000
X
(1)0.0000001.000000
X
(2)4000.0001.000000
X(3)0.0000001.000000
X(4)0.0000001.000000
X(5)0.0000001.000000
X(6)1200.0001.000000
A(1,1)0.0000000.000000
A(1,