Lingo软件使用指南.docx

上传人:b****6 文档编号:4443939 上传时间:2022-12-01 格式:DOCX 页数:27 大小:143.53KB
下载 相关 举报
Lingo软件使用指南.docx_第1页
第1页 / 共27页
Lingo软件使用指南.docx_第2页
第2页 / 共27页
Lingo软件使用指南.docx_第3页
第3页 / 共27页
Lingo软件使用指南.docx_第4页
第4页 / 共27页
Lingo软件使用指南.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

Lingo软件使用指南.docx

《Lingo软件使用指南.docx》由会员分享,可在线阅读,更多相关《Lingo软件使用指南.docx(27页珍藏版)》请在冰豆网上搜索。

Lingo软件使用指南.docx

Lingo软件使用指南

Lingo软件使用指南

摘要:

本文介绍了Lingo软件的基本使用方法。

从最基本的使用到复杂问题的解决,本文给出了比较详细的介绍。

Lingo软件是美国Lindo公司的产品,主要用来求解优化问题。

它是一个非常强大的软件,可以求解大部分优化问题,包括线性规划、二次规划、整数规划、运输问题等,是目前全球应用最广泛的优化软件之一。

这里我们简单介绍它的使用方法。

一进入Lingo

如果你的计算机已经安装了Lingo,只需要在桌面上双击Lingo的快捷方式,就可以进入Lingo。

为了使自己的程序易于阅读,经常需要有一些注释,因此在编写程序中,每一行前面有感叹号的表示这一行是注释行,在程序运行中不起作用,希望初学者养成注释的好习惯。

二建立数学模型和Lingo模型语言

例1 在Lingo的命令窗口中输入下面的线性规划模型

!

目标函数;

MAX=100*x1+150*x2;  

!

第一个约束;

X1<=100;

!

第二个约束;         

X2<=120; 

!

第三个约束;        

X1+2*x2<=160;    

!

end可有可无;

end

求解可得全局最优解:

  

Objectivevalue:

  14500.00

Variable  Value   

X1     100.0000    

X2     30.00000            

从这个例子可以看出,用Lingo软件求解一个简单的优化问题是非常容易的。

我们只需要输入优化问题的两个主要部分:

目标函数和约束,就可以直接求解。

对于比较简单的问题,我们可以采取这种直接的方式去求解,但是,对于比较复杂的问题,用这种方式就不现实。

比如下面的例2,这就必须要使用Lingo的模型语言。

例2一个运输问题

假设WWW公司有6个仓库,储存着8个分厂生产所需要的原材料。

要求每一个仓库的供应量不能超过储存量,而且每一个分厂的需求必须得到满足。

问:

如何组织运输,使总运输费用最小?

已知从6个仓库到8个分厂的运输费用表。

表1 供应                  表2 需求

分厂标号

需求量

V1

35

V2

37

V3

22

V4

32

V5

41

V6

32

V7

43

V8

38

 

 

仓库标号

供应能力

Wh1

60

Wh2

55

Wh3

51

Wh4

43

Wh5

41

Wh6

52

 

 

表3 运输费用

 

V1

V2

V3

V4

V5

V6

V7

V8

Wh1

6

2

6

7

4

2

5

9

Wh2

4

9

5

3

8

5

8

2

Wh3

5

2

1

9

7

4

3

3

Wh4

7

6

7

3

9

2

7

1

Wh5

2

3

9

5

7

2

6

5

Wh6

5

5

2

2

8

1

4

3

 

 

 

 

 

 

 

 

 

这个问题是一个典型的优化问题,通常称为运输问题。

具体求解过程如下。

第一步:

写出模型语言

1 构造目标函数。

根据问题要求,可以设VOLUME_I_J表示从第I个仓库到第J个分厂运输原材料数。

那么,总运费最小的目标函数为

MIN=6*VOLUME_1_1+2*VOLUME_1_2+

6*VOLUME_1_3+7*VOLUME_1_4+

4*VOLUME_1_5+

·

·

·

8*VOLUME_6_5+VOLUME_6_6+4*VOLUME_6_7+

3*VOLUME_6_8;      

很显然,这样输入太麻烦,如果用Lingo模型语言来描述则简洁的多。

首先将目标函数表示为我们熟悉的数学语言

Minimize

然后将其转化为Lingo模型语言

MIN=@SUM(LINKS(I,J):

COST(I,J)*VOLUME(I,J));

数学语言和Lingo模型语言之间的关系为:

数学语言     Lingo模型语言    

Minimize     MIN=

@SUM(LINKS(I,J):

 )

COSTij     COST(I,J)

*        *

VOLUMEij   VOLUME(I,J)

2 构造约束函数。

第j个分厂的需求:

VOLUME_1_j+VOLUME_2_j+VOLUME_3_j+

VOLUME_4_j+VOLUME_5_j+VOLUME_6_j=35;

则每一个分厂的需求用数学语言描述为

VOLUMEij=DEMANDj,对所有j分厂

Lingo模型语言描述为

@FOR(VENDORS(J):

@SUM(WAREHOUSES(I):

VOLUME(I,J))=DEMAND(J));

数学语言和Lingo模型语言之间的关系为:

数学语言        Lingo模型语言

foralljinVENDORS   @FOR(VENDORS(J):

@SUM(WAREHOUSES(I):

VOLUMEij      VOLUME(I,J)

=            =

DEMANDj        DEMAND(J)

第i个仓库的供应:

VOLUMEij<=CAPi,

每一个仓库的供应能力约束为

VOLUMEij<=CAPi,对所有i仓库

Lingo模型语言描述为

@FOR(WAREHOUSES(I):

@SUM(VENDORS(J):

VOLUME(I,J))<=CAPACITY(I));

这样,我们就把运输问题的两个约束都用Lingo模型语言写出来了。

从而就得到了一个完整的模型:

MODEL:

MIN=@SUM(LINKS(I,J):

COST(I,J)*VOLUME(I,J));

@FOR(VENDORS(J):

@SUM(WAREHOUSES(I):

VOLUME(I,J))=DEMAND(J));

@FOR(WAREHOUSES(I):

@SUM(VENDORS(J):

VOLUME(I,J))<=CAPACITY(I));

END

但是,我们还没有定义模型中的变量,且没有把已知数据传进来。

第二步:

定义变量集合

在这个问题中,我们要定义三个集合,即:

仓库集合、分厂集合及运输集合。

定义方式如下:

SETS:

WAREHOUSES/WH1WH2WH3WH4WH5WH6/:

CAPACITY;

VENDORS/V1V2V3V4V5V6V7V8/:

DEMAND;

LINKS(WAREHOUSES,VENDORS):

COST,VOLUME;

ENDSETS

在这个定义中,三个变量集合包含在SETS和ENDSETS之间。

仓库集合命名为WAREHOUSES,其中包含六个元素WHi(即六个仓库),且每个元素都有一个共同属性是供应量,命名为CAPACITY。

分厂集合命名为VENDORS,其中包含八个元素Vj(即八个分厂),每个元素都有一个共同属性是需求量,命名为DEMAND。

运输集合是由前两个集合派生出来的,用LINKS(WAREHOUSES,VENDORS)来表示这种派生关系,它中间包含48个元素,表示了从6个仓库到8个分厂之间的运输情况,其中每一个元素有两个属性,运输费用COST和运输量VOLUME。

这样,我们就把模型中需要的所有变量都定义过了。

第三步:

输入模型数据

按照所定义的变量,输入数据,格式如下:

DATA:

CAPACITY=605551434152;

DEMAND=3537223241324338;

COST=62674259

49538582

52197433

76739271

23957265

55228143;

ENDDATA

可以看出,所有输入的数据都必须包含在DATA和ENDDATA之间。

经过这三步之后,我们就可以得到一个完整的Lingo文件。

MODEL:

!

六个仓库供应八个分厂的一个运输问题;

SETS:

WAREHOUSES/WH1WH2WH3WH4WH5WH6/:

CAPACITY;

VENDORS/V1V2V3V4V5V6V7V8/:

DEMAND;

LINKS(WAREHOUSES,VENDORS):

COST,VOLUME;

ENDSETS

!

目标函数;

MIN=@SUM(LINKS(I,J):

COST(I,J)*VOLUME(I,J));

!

分厂需求约束;

@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=62674259

49538582

52197433

76739271

23957265

55228143;

ENDDATA

END

求解可得:

Optimalsolutionfoundatstep:

    16

Objectivevalue:

        664.0000

求解报告(非零解)  

Variable     Value    ReducedCost

VOLUME(WH1,V2)    19.00000     0.0000000

VOLUME(WH1,V5)    41.00000     0.0000000

VOLUME(WH2,V4)    32.00000     0.0000000

VOLUME(WH2,V8)    1.000000     0.0000000

VOLUME(WH3,V2)    12.00000     0.0000000

VOLUME(WH3,V3)    22.00000     0.0000000

VOLUME(WH3,V7)    17.00000     0.0000000

VOLUME(WH4,V6)    6.000000     0.0000000

VOLUME(WH4,V8)    37.00000     0.0000000

VOLUME(WH5,V1)    35.00000     0.0000000

VOLUME(WH5,V2)    6.000000     0.0000000

VOLUME(WH6,V6)    26.00000     0.0000000

VOLUME(WH6,V7)    26.00000     0.0000000

通过前面两个例题,我们已经知道了如何利用Lingo软件去求解简单优化问题和比较复杂的优化问题。

但是,这还不够,在变量集合的定义中,如果集合中的元素比较多,那么,采用枚举的定义方式就显得不合适;在输入数据时,如果数据量比较大,那么,采用在命令窗口中直接输入的方式就不可取,因此,我们必须去寻找更好的方法。

下面我们就针对这两个问题来展开讨论。

三.定义变量集合

在Lingo模型语言中,变量集合分为两种类型:

原始集合(Primitive)和派生集合(Derived)。

在前面的例2中,仓库集合WAREHOUSES和分厂集合VENDORS就是原始集合,而运输集合是由这两个原始集合派生出来的,通常用LINKS(WAREHOUSES,VENDORS)来表示这个派生集合,这种派生属于完全派生,集合中包含了所有两个原始集合元素之间的各种可能搭配,因此,在例题中,这个派生集合中就包含了68=48个元素。

1.原始集合

一个原始集合的定义包含三部分,即

●集合名称setname,

●集合元素member,

●集合元素的属性attribute.

定义原始集合的语法为:

setname/member_list/[:

attribute_list];

[]表示可选项,以下相同。

原始集合命名按照一般程序设计语言的命名规则。

元素列表中罗列出了集合中的元素,有两种方式,一是详细列表,即给每一个元素一个名字,把所有元素罗列出来,就象例2中仓库集合元素列表一样。

WAREHOUSES/WH1WH2WH3WH4WH5WH6/:

CAPACITY;

另一种是简略列表,在简略列表中,不把集合中的元素按名字一一列出,而是采用下面的方式:

setname/1..n/[:

attribute_list];

仓库集合定义可以表示为

WAREHOUSES/1..6/:

CAPACITY;

对于元素比较多的集合,采用这样的方式是比较好的,但是,缺点就是元素名字只是用1,2…给出,不够直观。

元素属性列表中罗列出了集合中元素的所有属性,属性命名时按照一般程序设计语言的命名规则。

属性可以有多个,例如我们对仓库集合元素增加一个位置属性LOCATION,则仓库集合定义可以表示为

WAREHOUSES/1..6/:

CAPACITY,LOCATION;

2派生集合

一个派生集合的定义包含四部分,即

●集合名称setname,

●父亲集合,

●集合元素列表,

●集合元素的属性attribute.

定义派生集合的语法为:

setname(parent_set_list)[/member_list/][:

attribute_list];

我们用下面的例子来说明,

SETS:

PRODUCT/AB/;

MACHINE/MN/;

WEEK/1..2/;

ALLOWED(PRODUCT,MACHINE,WEEK);

ENDSETS

集合PRODUCT,MACHINE和WEEK是原始集合,集合ALLOWED是由父亲集合PRODUCT,MACHINE和WEEK派生出来的.它的元素为

ALLOWEDSetMembership:

Index  Member

1   (A,M,1)

2   (A,M,2)

3   (A,N,1)

4   (A,N,2)

5   (B,M,1)

6   (B,M,2)

7   (B,N,1)

8(B,N,2)

元素列表是可选项,如果省略掉,则默认为集合包含所有由父亲集合派生出来的元素,这种派生集合称之为稠密集合。

就象上面的例子,包含8个元素。

有时不需要派生集合中的所有元素,我们可以采用所谓的稀疏集合的方法,这时只需要指定派生集合的一个子集合即可。

可以用两种方式来实现,一是详细列出子集合的所有元素,如

ALLOWED(PRODUCT,MACHINE,WEEK)/AM1,AN2,BN1/;

这时,派生集合中的元素只有三个,即(A,M,1),(A,N,2),和(B,N,1).

另一种是采用过滤技术来实现,我们仍然用一个例子来说明。

考虑一个汽车集合TRUCKS,它是原始集合,集合中元素有属性CAPACITY,表示汽车的最大运载量,我们想得到运载量超过50000的所有汽车,这时可以采用过滤技术来实现。

HEAVY_DUTY(TRUCKS)|CAPACITY(&1)#GT#50000;

集合HEAVY_DUTY是由TRUCKS派生出来的,它中的元素都是运载量超过50000的汽车,是元素过滤的开始标志;&1表示在过滤时把第一个父亲集合的元素放在其中,如果有第二个父亲集合,可以把第二个父亲集合的元素放在&2中;#GT#表示过滤的条件是‘大于’;50000是过滤的下界。

上面的语句表示了由父亲集合TRUCKS派生出集合HEAVY_DUTY,它中间的元素的属性(即汽车的运载量)都是满足大于50000的。

LINGO中的逻辑运算符包括:

#EQ#    equal

#NE#    notequal

#GE#    greaterthanorequalto

#GT#    greaterthan

#LT#    lessthan

#LE#    lessthanorequalto

我们简单的总结集合之间的关系如下:

四.输入原始数据

在LINGO中,一个重要的部分就是数据部分,我们要输入的所有原始数据都要在这部分完成。

数据部分以‘DATA:

’开始,以‘ENDDATA’结束,所有输入数据包含在其中。

数据输入的格式是:

attribute_list=value_list;

即我们需要把在变量集合部分定义好的集合赋以初值,给每一个集合属性列表赋以初值列表。

我们以下面的例子来说明。

SETS:

SET1/1..3/:

X,Y;

ENDSETS

DATA:

X=123;

Y=456;

ENDDATA

首先定义了集合SET1,其中包含三个元素1,2,3,每个元素有两个属性X,Y。

在数据部分,我们分别给两个属性赋初值,结果是元素1的X属性为1,Y属性为4,元素2的X属性为2,Y属性为5,元素3的X属性为3,Y属性为6。

我们也可以采用下面的紧凑格式:

SETS:

SET1/1..3/:

X,Y;

ENDSETS

DATA:

XY=14

25

36;

ENDDATA

这样的数据输入方式对于比较小的问题是可行的,但是,对于规模比较大的问题,采用这样的数据输入方式显然是不可取的。

LINGO提供了OLE连接到Excel,ODBC连接到databases,以及与文本类型的数据文件的连接。

1.与文本型数据文件的连接

LINGO与文本数据文件的连接函数中的数据载入函数是@FILE,使用这个函数可以把外部的文本型数据文件传入LINGO模型语言中来,它的语法为:

@FILE('filename')。

我们仍然以运输问题为例来说明。

在前面的例题中,模型语言如下:

MODEL:

!

六个仓库供应八个分厂的一个运输问题;

SETS:

WAREHOUSES/WH1WH2WH3WH4WH5WH6/:

CAPACITY;

VENDORS/V1V2V3V4V5V6V7V8/:

DEMAND;

LINKS(WAREHOUSES,VENDORS):

COST,VOLUME;

ENDSETS

!

目标函数;

MIN=@SUM(LINKS(I,J):

COST(I,J)*VOLUME(I,J));

!

分厂需求约束;

@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=62674259

49538582

52197433

76739271

23957265

55228143;

ENDDATA

END

我们使用函数@FILE来简化模型语言的书写

MODEL:

!

六个仓库供应八个分厂的一个运输问题;

SETS:

WAREHOUSES/@FILE('WIDGETS2.LDT')/:

CAPACITY;

VENDORS/@FILE('WIDGETS2.LDT')/ :

DEMAND;

LINKS(WAREHOUSES,VENDORS):

COST,VOLUME;

ENDSETS

!

目标函数;

MIN=@SUM(LINKS(I,J):

COST(I,J)*VOLUME(I,J));

!

分厂需求约束;

@FOR(VENDORS(J):

@SUM(WAREHOUSES(I):

VOLUME(I,J))=DEMAND(J));

!

仓库供应约束;

@FOR(WAREHOUSES(I):

@SUM(VENDORS(J):

VOLUME(I,J))<=CAPACITY(I));

!

输入数据;

DATA:

CAPACITY=@FILE('WIDGETS2.LDT');

DEMAND=@FILE('WIDGETS2.LDT');

COST=@FILE('WIDGETS2.LDT');

ENDDATA

END

原始数据存放在文本型数据文件WIDGETS2.LDT中,该文件的内容如下:

!

仓库列表;

WH1WH2WH3WH4WH5WH6~

!

分厂列表;

V1V2V3V4V5V6V7V8~

!

仓库储存量列表;

605551434152~

!

分厂需求列表;

3537223241324338~

!

单位运输费用列表;

62674259

49538582

52197433

76739271

23957265

55228143

文件WIDGETS2.LDT的结构最好按照模型中的调用顺序来组织。

文件中经常出现的符号‘~’是记录结束标志,每一次调用文件WIDGETS2.LDT传进去一条记录,最后一条记录没有结束标志‘~’,调用结束后系统会自动关闭文件,如果给最后一条记录加上记录结束标志‘~’,那么调用结束后系统不会关闭数据文件,这

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1