第1讲 Lingo软件入门(2014)

更新时间:2023-10-14 07:32:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第1讲 Lingo软件入门

司守奎

烟台市,海军航空工程学院数学教研室

Email:sishoukui@163.com

1 Lingo软件的基本语法 1.1 集合

集合部分的语法为

sets:

集合名称1/成员列表1/:属性1_1,属性1_2,…,属性1_n1; 集合名称2/成员列表2/:属性2_1,属性2_2,…,属性2_n2; 派生集合名称(集合名称1,集合名称2):属性3_1,…,属性3_n3; endsets

例26

sets:

product/A B/; machine/M N/; week/1..2/;

allowed(product,machine,week):x; endsets

1.2 数据

数据部分的语法为 data:

属性1=数据列表; 属性2=数据列表; enddata 1.3 计算

计算段部分不能含有变量,必须是已知数据的运算。 calc: b=0; a=a+1; endcalc

1.4 模型的目标函数和约束条件

这里就不具体给出了,下面通过具体例子给出。 1.5 子模型

在 LINGO 9.0 及更早的版本中,在每个LINGO 模型窗口中只允许有一个优化模型,可以称为主模型(MAIN MODEL)。在LINGO 10.0 中,每个LINGO 模型窗口中除了主模型外,用户还可以定义子模型(SUBMODEL)。子模型可以在主模型的计算段中被调用,这就进一步增强了LINGO 的编程能力。

子模型必须包含在主模型之内,即必须位于以“MODEL:”开头、以“END”结束的模块内。同一个主模型中,允许定义多个子模型,所以每个子模型本身必须命名,其基本语法是:

SUBMODEL mymodel:

可执行语句(约束+目标函数); ENDSUBMODEL

其中 mymodel 是该子模型的名字,可执行语句一般是一些约束语句,也可能包含目标函数,但不可以有自身单独的集合段、数据段、初始段和计算段。也就是说,同一个主模型内的变量都是全局变量,这些变量对主模型和所有子模型同样有效。

如果已经定义了子模型 mymodel,则在计算段中可以用语句“@SOLVE( mymodel);”求解这个子模型。 2 Lingo函数 2.1 算术运算符

1

^ 乘方 ﹡ 乘 / 除 ﹢ 加 ﹣ 减

2.2 逻辑运算符

在Lingo中,逻辑运算符主要用于集循环函数的条件表达式中,来控制在函数中哪些集成员被包含,哪些被排斥。在创建稀疏集时用在成员资格过滤器中。

Lingo具有9种逻辑运算符

#not# 否定该操作数的逻辑值,#not#是一个一元运算符。 #eq# 若两个运算数相等,则为true;否则为false。 #ne# 若两个运算符不相等,则为true;否则为false。

#gt# 若左边的运算符严格大于右边的运算符,则为true;否则为false。 #ge# 若左边的运算符大于或等于右边的运算符,则为true;否则为false。 #lt# 若左边的运算符严格小于右边的运算符,则为true;否则为false。 #le# 若左边的运算符小于或等于右边的运算符,则为true;否则为false。 #and# 仅当两个参数都为true时,结果为true;否则为false。 #or# 仅当两个参数都为false时,结果为false;否则为true。 2.3 关系运算符

在Lingo中,关系运算符主要是被用在模型中来指定一个表达式的左边是否等于、小于等于、或者大于等于右边,形成模型的一个约束条件。关系运算符与逻辑运算符#eq#、#le#、#ge#截然不同,逻辑运算符仅仅判断一个关系是否被满足,满足为真,不满足为假。

Lingo有三种关系运算符:“=”、“<=”和“>=”。Lingo中还能用“<”表示小于等于关系,“>”表示大于等于关系。Lingo并不支持严格小于和严格大于关系运算符。 2.4 数学函数

Lingo提供了大量的标准数学函数 @abs(x)返回x的绝对值。

@sin(x)返回x的正弦值,x采用弧度制。 @cos(x)返回x的余弦值。 @tan(x)返回x的正切值。

@exp(x)返回常数e的x次方。 @log(x)返回x的自然对数。

@lgm(x)返回x的gamma函数的自然对数。

@mod(x,y)返回x除以y的余数。 @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中的最小值。 2.5 变量界定函数

变量界定函数实现对变量取值范围的附加限制,共4种 @bin(x)限制x为0或1; @bnd(L,x,U)限制L≤x≤U;

@free(x)取消对变量x的默认下界为0的限制,即x可以取任意实数; @gin(x)限制x为整数。

在默认情况下,Lingo规定变量是非负的,也就是说下界为0,上界为+∞。@free取消了默认的下界为0的限制,使变量也可以取负值。@bnd用于设定一个变量的上下界,它也可以取消默认下界为0的约束。 2.6 集循环函数

@for:该函数用来产生对集成员的约束。

@sum:该函数返回遍历指定的集成员的一个表达式的和。

2

@min和@max:返回指定的集成员的一个表达式的最小值或最大值。

2.7 其他函数

(1)函数@TABLE

该函数以表格形式输出与集合和集合的属性相关的数据,并且只能在数据段(DATA)中使用。目前该函数仅用于将数据输出到结果报告窗口或文本文件中,而不能输出到数据库或电子表格(EXCEL)文件中。也就是说,只能输出到@TEXT 函数,而不能输出到@OLE和@ODBC 函数。

(2)函数@WRITE和@WRITEFOR

函数@WRITE和@WRITEFOR在LINGO9.0用在程序的数据段(DATA)方便用户控制输出格式,所输出的变量的取值是程序运行结束后最后结果的相关数据, 并且输出必须定向到@TEXT 函数,即通过@TEXT 函数输出到缺省的输出设备(通常就是报告窗口)或文本文件。LINGO10.0中,这两个函数也是为了方便用户控制输出格式,但它们还可以出现在计算段(CALC)随时输出中间结果,并且不需要使用@TEXT 函数,输出的结果也是被定向到缺省的输出设备(通常就是标准的报告窗口)。如果希望改变缺省的输出设备,可以采用@DIVERT函数。

注:(1)Lingo中是不区分大小写字符的。

(2)Lingo中数据部分不能使用分式,例如数据部分不能使用1/3。 (3)Lingo中的注释是使用!引导的。 (4)Lingo中默认所有的变量都是非负的。

(5)Lingo中矩阵数据是逐行存储的,Matlab中数据是逐列存储的。

例1 使用LINGO软件计算6个产地8个销地的最小费用运输问题。单位商品运价如

表1所示。

表1 单位商品运价表 单位运价 销地 产地 A1 A2 A3 A4 A5 A6 销量 B1 6 4 5 7 2 5 35 B2 2 9 2 6 3 5 37 B3 6 5 1 7 9 2 22 B4 7 3 9 3 5 2 32 B5 4 8 7 9 7 8 41 B6 2 5 4 2 2 1 32 B7 5 8 3 7 6 4 43 B8 9 2 3 1 5 3 38 产量 60 55 51 43 41 52 解 设xij(i?1,2,?6;j?1,2,?,8)表示产地Ai运到销地Bj的量,cij表示产地Ai到销地Bj的单位运价,dj表示销地Bj的需求量,ei表示产地Ai的产量,建立如下线性规划模型

min??cxi?1j?168ijij,

?6??xij?dj,j?1,2,?,8,?i?1?8s.t. ??xij?ei,i?1,2,?,6,

?j?1?x?0,i?1,2,?,6;j?1,2,?,8.?ij?3

(1)用Lingo编程,程序和数据放在同一个文件中。

计算的Lingo程序如下 model:

!6产地8销地运输问题; sets:

warehouses/1..6/: e; vendors/1..8/: d;

links(warehouses,vendors): c,x; endsets !目标函数;

min=@sum(links: c*x); !需求约束;

@for(vendors(J):@sum(warehouses(I): x(I,J))=d(J)); !产量约束;

@for(warehouses(I):@sum(vendors(J): x(I,J))<=e(I)); !下面是数据; data:

e=60 55 51 43 41 52;

d=35 37 22 32 41 32 43 38; c=6 2 6 7 4 2 9 5 4 9 5 3 8 5 8 2 5 2 1 9 7 4 3 3 7 6 7 3 9 2 7 1 2 3 9 5 7 2 6 5 5 5 2 2 8 1 4 3; enddata end

(2)用Lingo编程,要求数据文件放在纯文本文件中。

使用Lingo函数@file,@text进行纯文本文件数据的输入和输出。 注:执行一次@file,输入1个记录,记录之间的分隔符为~。

计算的Lingo程序如下 model: sets:

warehouses/1..6/: e; vendors/1..8/: d;

links(warehouses,vendors): c, x; endsets

min=@sum(links: c*x);

@for(vendors(J):@sum(warehouses(I): x(I,J))=d(J)); @for(warehouses(I):@sum(vendors(J): x(I,J))<=e(I)); data:

e=@file(sdata.txt); d=@file(sdata.txt); c=@file(sdata.txt);

@text(sdata2.txt)=@table(x); !把计算结果以表格形式输出到外部纯文本文件; enddata end

其中纯文本数据文件sdata.txt中的数据格式如下

60 55 51 43 41 52~ !~是记录分割符,该第一个记录是产量; 35 37 22 32 41 32 43 38~ !该第二个记录是需求量; 6 2 6 7 4 2 9 5

4

4 9 5 3 8 5 8 2 5 2 1 9 7 4 3 3 7 6 7 3 9 2 7 1 2 3 9 5 7 2 6 5

5 5 2 2 8 1 4 3 !最后一个记录是单位运价;

(3)用Lingo编程,要求数据文件放在Excel文件中。

Lingo通过@OLE函数实现与Excel文件传递数据,使用@OLE函数既可以从Excel文件中导入数据,也能把计算结果写入Excel文件。

从Excel文件中导入数据的格式如下

属性名1=@OLE(?Excel文件名?,?数据块名称1?);

使用@OLE函数也能把计算结果写入Excel文件,使用格式如下 @OLE(?Excel文件名?,?数据块名称2?)=属性名2; 如数据块名称与属性名相同时,可以省略数据块名称。

计算的Lingo程序如下 model: sets:

warehouses/1.. 6/: e; vendors/1..8/: d;

links(warehouses,vendors): c, x; endsets

min=@sum(links: c*x);

@for(vendors(J):@sum(warehouses(I): x(I,J))=d(J)); @for(warehouses(I):@sum(vendors(J): x(I,J))<=e(I)); data:

e=@ole(sdata3.xls); d=@ole(sdata3.xls);

c=@ole(sdata3.xls,cc); !Excel中不允许使用域名“c”,对应的数据块定义成“cc”; @ole(sdata.xls)=x; enddata end

例2 Lingo中的子模型

求解下列最小值问题

3min4x1?ax1?2x2, s.t.x1?x2?4,2x1?x2?5,?x1?bx2?2, x1,x2?0,a?0,1,2,3,4;b?2,4,6,7. 把完整的一个数学规划问题作为一个子模型的Lingo程序: model: sets:

var1/1..5/:aa; var2/1..4/:bb; var3/1 2/:x;

link(var1,var2): tobj; endsets

5

?16?17 C???24??16152122191919182220?18??. 17??23?3. 求解下列线性规划问题(要求分别用Matlab和Lingo编程),其中的矩阵A?(aij)500?300是服从N(5,9)的正态分布随机数所构成的矩阵。

maxv

?500??aijxi?v,j?1,2,?,300?i?1s.t. ?m ??xi?1?i?1??xi?0,i?1,2,?,m?

16

本文来源:https://www.bwwdw.com/article/nemf.html

Top