lingo11入门到精通(4)

2019-04-21 17:34

LINGO教程

1.@in(set_name,primitive_index_1 [,primitive_index_2,?]) 如果元素在指定集中,返回1;否则返回0。

例4.7 全集为I,B是I的一个子集,C是B的补集。 sets:

I/x1..x4/; B(I)/x2/;

C(I)|#not#@in(B,&1):; endsets

2.@index([set_name,] primitive_set_element)

该函数返回在集set_name中原始集成员primitive_set_element的索引。如果set_name被忽略,那么LINGO将返回与primitive_set_element匹配的第一个原始集成员的索引。如果找不到,则产生一个错误。 例4.8 如何确定集成员(B,Y)属于派生集S3。 sets:

S1/A B C/; S2/X Y Z/;

S3(S1,S2)/A X, A Z, B Y, C X/; endsets

X=@in(S3,@index(S1,B),@index(S2,Y));

看下面的例子,表明有时为@index指定集是必要的。 例4.9 sets:

girls/debble,sue,alice/; boys/bob,joe,sue,fred/; endsets

I1=@index(sue);

I2=@index(boys,sue);

I1的值是2,I2的值是3。我们建议在使用@index函数时最好指定集。

3.@wrap(index,limit)

该函数返回j=index-k*limit,其中k是一个整数,取适当值保证j落在区间[1,limit]内。该函数相当于index模limit再加1。该函数在循环、多阶段计划编制中特别有用。

4.@size(set_name)

该函数返回集set_name的成员个数。在模型中明确给出集大小时最好使用该函数。它的使用使模型更加数据中立,集大小改变时也更易维护。

4.7 集循环函数

集循环函数遍历整个集进行操作。其语法为

@function(setname[(set_index_list)[|conditional_qualifier]]:

expression_list);

@function相应于下面罗列的四个集循环函数之一;setname是要遍历的集;set_ index_list是集索引列表;conditional_qualifier是用来限制集循环函数的范围,当集循环函数遍历集的每个成员时,LINGO都要对conditional_qualifier进行评价,若结果为真,则对该成员执行@function操

16 /66

LINGO教程

作,否则跳过,继续执行下一次循环。expression_list是被应用到每个集成员的表达式列表,当用的是@for函数时,expression_list可以包含多个表达式,其间用逗号隔开。这些表达式将被作为约束加到模型中。当使用其余的三个集循环函数时,expression_list只能有一个表达式。如果省略set_index_list,那么在expression_list中引用的所有属性的类型都是setname集。

1.@for

该函数用来产生对集成员的约束。基于建模语言的标量需要显式输入每个约束,不过@for函数允许只输入一个约束,然后LINGO自动产生每个集成员的约束。

例4.10 产生序列{1,4,9,16,25} model: sets:

number/1..5/:x; endsets

@for(number(I): x(I)=I^2); end

2.@sum

该函数返回遍历指定的集成员的一个表达式的和。 例4.11 求向量[5,1,3,4,6,10]前5个数的和。 model: data: N=6; enddata sets:

number/1..N/:x; endsets data:

x = 5 1 3 4 6 10; enddata

s=@sum(number(I) | I #le# 5: x); end

3.@min和@max

返回指定的集成员的一个表达式的最小值或最大值。

例4.12 求向量[5,1,3,4,6,10]前5个数的最小值,后3个数的最大值。 model: data: N=6; enddata sets:

number/1..N/:x; endsets data:

x = 5 1 3 4 6 10;

17 /66

LINGO教程

enddata

minv=@min(number(I) | I #le# 5: x); maxv=@max(number(I) | I #ge# N-2: x); end

下面看一个稍微复杂一点儿的例子。

例4.13 职员时序安排模型 一项工作一周7天都需要有人(比如护士工作),每天(周一至周日)所需的最少职员数为20、16、13、16、19、14和12,并要求每个职员一周连续工作5天,试求每周所需最少职员数,并给出安排。注意这里我们考虑稳定后的情况。 model: sets:

days/mon..sun/: required,start; endsets data:

!每天所需的最少职员数;

required = 20 16 13 16 19 14 12; enddata

!最小化每周所需职员数; min=@sum(days: start); @for(days(J):

@sum(days(I) | I #le# 5:

start(@wrap(J+I+2,7))) >= required(J)); end

计算的部分结果为

Global optimal solution found at iteration: 0 Objective value: 22.00000

Variable Value Reduced Cost REQUIRED( MON) 20.00000 0.000000 REQUIRED( TUE) 16.00000 0.000000 REQUIRED( WED) 13.00000 0.000000 REQUIRED( THU) 16.00000 0.000000 REQUIRED( FRI) 19.00000 0.000000 REQUIRED( SAT) 14.00000 0.000000 REQUIRED( SUN) 12.00000 0.000000 START( MON) 8.000000 0.000000 START( TUE) 2.000000 0.000000 START( WED) 0.000000 0.3333333 START( THU) 6.000000 0.000000 START( FRI) 3.000000 0.000000 START( SAT) 3.000000 0.000000 START( SUN) 0.000000 0.000000 从而解决方案是:每周最少需要22个职员,周一安排8人,周二安排2人,周三无需安排人,周四安排6人,周五和周六都安排3人,周日无需安排人。

18 /66

LINGO教程

4.8 输入和输出函数

输入和输出函数可以把模型和外部数据比如文本文件、数据库和电子表格等连接起来。

1.@file函数

该函数用从外部文件中输入数据,可以放在模型中任何地方。该函数的语法格式为@file(’filename’)。这里filename是文件名,可以采用相对路径和绝对路径两种表示方式。@file函数对同一文件的两种表示方式的处理和对两个不同的文件处理是一样的,这一点必须注意。

例4.14 以例1.2来讲解@file函数的用法。

注意到在例1.2的编码中有两处涉及到数据。第一个地方是集部分的6个warehouses集成员和8个vendors集成员;第二个地方是数据部分的capacity,demand和cost数据。

为了使数据和我们的模型完全分开,我们把它们移到外部的文本文件中。修改模型代码以便于用@file函数把数据从文本文件中拖到模型中来。修改后(修改处代码黑体加粗)的模型代码如下: model:

!6发点8收点运输问题; sets:

warehouses/ @file('1_2.txt') /: capacity; vendors/ @file('1_2.txt') /: 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 = @file('1_2.txt') ; demand = @file('1_2.txt') ; cost = @file('1_2.txt') ; enddata end

模型的所有数据来自于1_2.txt文件。其内容如下: !warehouses成员;

WH1 WH2 WH3 WH4 WH5 WH6 ~

!vendors成员;

19 /66

LINGO教程

V1 V2 V3 V4 V5 V6 V7 V8 ~ !产量;

60 55 51 43 41 52 ~ !销量;

35 37 22 32 41 32 43 38 ~

!单位运输费用矩阵; 6 2 6 7 4 2 5 9 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

把记录结束标记(~)之间的数据文件部分称为记录。如果数据文件中没有记录结束标记,那么整个文件被看作单个记录。注意到除了记录结束标记外,模型的文本和数据同它们直接放在模型里是一样的。

我们来看一下在数据文件中的记录结束标记连同模型中@file函数调用是如何工作的。当在模型中第一次调用@file函数时,LINGO打开数据文件,然后读取第一个记录;第二次调用@file函数时,LINGO读取第二个记录等等。文件的最后一条记录可以没有记录结束标记,当遇到文件结束标记时,LINGO会读取最后一条记录,然后关闭文件。如果最后一条记录也有记录结束标记,那么直到LINGO求解完当前模型后才关闭该文件。如果多个文件保持打开状态,可能就会导致一些问题,因为这会使同时打开的文件总数超过允许同时打开文件的上限16。

当使用@file函数时,可把记录的内容(除了一些记录结束标记外)看作是替代模型中@file(’filename’)位置的文本。这也就是说,一条记录可以是声明的一部分,整个声明,或一系列声明。在数据文件中注释被忽略。注意在LINGO中不允许嵌套调用@file函数。

2.@text函数

该函数被用在数据部分用来把解输出至文本文件中。它可以输出集成员和集属性值。其语法为

@text([’filename’])

这里filename是文件名,可以采用相对路径和绝对路径两种表示方式。如果忽略filename,那么数据就被输出到标准输出设备(大多数情形都是屏幕)。@text函数仅能出现在模型数据部分的一条语句的左边,右边是集名(用来输出该集的所有成员名)或集属性名(用来输出该集属性的值)。

我们把用接口函数产生输出的数据声明称为输出操作。输出操作仅当求解器求解完模型后才执行,执行次序取决于其在模型中出现的先后。 例4.15 借用例4.12,说明@text的用法。 model: sets:

days/mon..sun/: required,start;

20 /66


lingo11入门到精通(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:松材线虫病防治技术方案(修订版)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: