LINGO教程精Word格式.docx
- 文档编号:18344614
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:26
- 大小:91.90KB
LINGO教程精Word格式.docx
《LINGO教程精Word格式.docx》由会员分享,可在线阅读,更多相关《LINGO教程精Word格式.docx(26页珍藏版)》请在冰豆网上搜索。
sex,age;
endsets
②当隐式罗列成员时,不必罗列出每个集成员。
可采用如下语法:
setname/member1..memberN/[:
attribute_list];
这里的member1是集的第一个成员名,memberN是集的最末一个成员名。
LINGO将自动产生中间的所有成员名。
LINGO也接受一些特定的首成员名和末成员名,用于创建一些特殊的集。
列表如下:
隐式成员
列表格式
示例
所产生集成员
1..n
1..5
1,2,3,4,5
StringM..
StringN
Car2..
car14
Car2,Car3,Car4,…,
Car14
DayM..DayN
Mon..Fri
Mon,Tue,Wed,Thu,Fri
MonthM..
MonthN
Oct..Jan
Oct,Nov,Dec,Jan
MonthYearM..
MonthYearN
Oct2001..
Jan2002
Oct2001,Nov2001,
Dec2001,Jan2002
③集成员不放在集定义中,而在随后的数据部分来定义。
例
students:
sex,age;
data:
students,sex,age=John116
Jill014
Rose017
Mike113;
enddata
在集部分只定义了一个集students,并未指定成员。
在数据部分罗列了集成员John、Jill、Rose和Mike,并对属性sex和age分别给出了值。
集成员无论用何种字符标记,它的索引都是从1开始连续计数。
在attribute_list可以指定一个或多个集成员的属性,属性之间必须用逗号隔开。
LINGO内置的建模语言是一种描述性语言,用它可以描述现实世界中的一些问题,然后再借助于LINGO求解器求解。
因此,集属性的值一旦在模型中被确定,就不可能再更改。
在LINGO中,只有在初始部分中给出的集属性值在以后的求解中可更改。
这与前面并不矛盾,初始部分是LINGO求解器的需要,并不是描述问题所必须的。
3定义派生集
为了定义一个派生集,必须详细声明:
父集的名字
可选,集成员
可用下面的语法定义一个派生集:
setname(parent_set_list)
[/member_list/][:
setname是集的名字。
parent_set_list是已定义的集的列表,多个时必须用逗号隔开。
如果没有指定成员列表,那么LINGO会自动创建父集成员的所有组合作为派生集的成员。
派生集的父集既可以是原始集,也可以是其它的派生集。
product/AB/;
machine/MN/;
week/1..2/;
allowed(product,machine,week):
x;
LINGO生成了三个父集的所有组合共八组作为allowed集的成员。
编号成员
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)
成员列表被忽略时,派生集成员由父集成员所有的组合构成,这样的派生集成为稠密集。
如果限制派生集的成员,使它成为父集成员所有组合构成的集合的一个子集,这样的派生集成为稀疏集。
同原始集一样,派生集成员的声明也可以放在数据部分。
一个派生集的成员列表有两种方式生成:
①显式罗列;
②设置成员资格过滤器。
当采用方式①时,必须显式罗列出所有要包含在派生集中的成员,并且罗列的每个成员必须属于稠密集。
使用前面的例子,显式罗列派生集的成员:
allowed(product,machine,week)/AM1,AN2,BN1/;
如果需要生成一个大的、稀疏的集,那么显式罗列就很讨厌。
幸运地是许多稀疏集的成员都满足一些条件以和非成员相区分。
我们可以把这些逻辑条件看作过滤器,在LINGO生成派生集的成员时把使逻辑条件为假的成员从稠密集中过滤掉。
!
学生集:
性别属性sex,1表示男性,0表示女性;
年龄属性age.;
students/John,Jill,Rose,Mike/:
男学生和女学生的联系集:
友好程度属性friend,[0,1]之间的数。
;
linkmf(students,students)|sex(&
1)#eq#1#and#sex(&
2)#eq#0:
friend;
男学生和女学生的友好程度大于0.5的集;
linkmf2(linkmf)|friend(&
1,&
2)#ge#0.5:
x;
sex,age=116
014
017
013;
friend=0.30.50.6;
用竖线(|)来标记一个成员资格过滤器的开始。
#eq#是逻辑运算符,用来判断是否“相等”,可参考§
4.&
1可看作派生集的第1个原始父集的索引,它取遍该原始父集的所有成员;
&
2可看作派生集的第2个原始父集的索引,它取遍该原始父集的所有成员;
3,&
4,……,以此类推。
注意如果派生集B的父集是另外的派生集A,那么上面所说的原始父集是集A向前回溯到最终的原始集,其顺序保持不变,并且派生集A的过滤器对派生集B仍然有效。
因此,派生集的索引个数是最终原始父集的个数,索引的取值是从原始父集到当前派生集所作限制的总和。
总的来说,LINGO可识别的集只有两种类型:
原始集和派生集。
在一个模型中,原始集是基本的对象,不能再被拆分成更小的组分。
原始集可以由显式罗列和隐式罗列两种方式来定义。
当用显式罗列方式时,需在集成员列表中逐个输入每个成员。
当用隐式罗列方式时,只需在集成员列表中输入首成员和末成员,而中间的成员由LINGO产生。
另一方面,派生集是由其它的集来创建。
这些集被称为该派生集的父集(原始集或其它的派生集)。
一个派生集既可以是稀疏的,也可以是稠密的。
稠密集包含了父集成员的所有组合(有时也称为父集的笛卡尔乘积)。
稀疏集仅包含了父集的笛卡尔乘积的一个子集,可通过显式罗列和成员资格过滤器这两种方式来定义。
显式罗列方法就是逐个罗列稀疏集的成员。
成员资格过滤器方法通过使用稀疏集成员必须满足的逻辑条件从稠密集成员中过滤出稀疏集的成员。
不同集类型的关系见下图。
模型的数据部分
在处理模型的数据时,需要为集指派一些成员并且在LINGO求解模型之前为集的某些属性指定值。
为此,LINGO为用户提供了两个可选部分:
输入集成员和数据的数据部分(DataSection)和为决策变量设置初始值的初始部分(InitSection)。
1数据部分入门
数据部分提供了模型相对静止部分和数据分离的可能性。
显然,这对模型的维护和维数的缩放非常便利。
数据部分以关键字“data:
”开始,以关键字“enddata”结束。
在这里,可以指定集成员、集的属性。
其语法如下:
object_list=value_list;
对象列(object_list)包含要指定值的属性名、要设置集成员的集名,用逗号或空格隔开。
一个对象列中至多有一个集名,而属性名可以有任意多。
如果对象列中有多个属性名,那么它们的类型必须一致。
如果对象列中有一个集名,那么对象列中所有的属性的类型就是这个集。
数值列(value_list)包含要分配给对象列中的对象的值,用逗号或空格隔开。
注意属性值的个数必须等于集成员的个数。
看下面的例子。
set1/A,B,C/:
X,Y;
X=1,2,3;
Y=4,5,6;
在集set1中定义了两个属性X和Y。
X的三个值是1、2和3,Y的三个值是4、5和6。
也可采用如下例子中的复合数据声明(datastatement)实现同样的功能。
X,Y=14
25
36;
看到这个例子,可能会认为X被指定了1、4和2三个值,因为它们是数值列中前三个,而正确的答案是1、2和3。
假设对象列有n个对象,LINGO在为对象指定值时,首先在n个对象的第1个索引处依次分配数值列中的前n个对象,然后在n个对象的第2个索引处依次分配数值列中紧接着的n个对象,……,以此类推。
模型的所有数据(属性值和集成员)被单独放在数据部分,这可能是最规范的数据输入方式。
2参数
在数据部分也可以指定一些标量变量(scalarvariables)。
当一个标量变量在数据部分确定时,称之为参数。
看一例,假设模型中用利率8.5%作为一个参数,就可以象下面一样输入一个利率作为参数。
interest_rate=.085;
也可以同时指定多个参数。
interest_rate,inflation_rate=.085.03;
3实时数据处理
在某些情况,对于模型中的某些数据并不是定值。
譬如模型中有一个通货膨胀率的参数,我们想在2%至6%范围内,对不同的值求解模型,来观察模型的结果对通货膨胀的依赖有多么敏感。
我们把这种情况称为实时数据处理(whatifanalysis)。
LINGO有一个特征可方便地做到这件事。
在本该放数的地方输入一个问号(?
)。
interest_rate,inflation_rate=.085?
;
每一次求解模型时,LINGO都会提示为参数inflation_rate输入一个值。
在WINDOWS操作系统下,将会接收到一个类似下面的对话框:
直接输入一个值再点击OK按钮,LINGO就会把输入的值指定给inflation_rate,然后继续求解模型。
除了参数之外,也可以实时输入集的属性值,但不允许实时输入集成员名。
4指定属性为一个值
可以在数据声明的右边输入一个值来把所有的成员的该属性指定为一个值。
days/MO,TU,WE,TH,FR,SA,SU/:
needs;
needs=20;
LINGO将用20指定days集的所有成员的needs属性。
对于多个属性的情形,见下例。
needs,cost;
needscost=20100;
5数据部分的未知数值
有时只想为一个集的部分成员的某个属性指定值,而让其余成员的该属性保持未知,以便让LINGO去求出它们的最优值。
在数据声明中输入两个相连的逗号表示该位置对应的集成员的属性值未知。
两个逗号间可以有空格。
years/1..5/:
capacity;
capacity=,34,20,,;
属性capacity的第2个和第3个值分别为34和20,其余的未知。
LINGO函数
LINGO有9种类型的函数:
1.
基本运算符:
包括算术运算符、逻辑运算符和关系运算符
2.
数学函数:
三角函数和常规的数学函数
3.
金融函数:
LINGO提供的两种金融函数
4.
概率函数:
LINGO提供了大量概率相关的函数
5.
变量界定函数:
这类函数用来定义变量的取值范围
6.
集操作函数:
这类函数为对集的操作提供帮助
7.
集循环函数:
遍历集的元素,执行一定的操作的函数
8.
数据输入输出函数:
这类函数允许模型和外部数据源相联系,进行数据的输入输出
9.
辅助函数:
各种杂类函数
1基本运算符
包括算术运算符、逻辑运算符、关系运算符。
这些运算符是非常基本的,甚至可以不认为它们是一类函数。
事实上,在LINGO中它们是非常重要的。
下面给三类操作符的优先级:
高 #not#﹣(取反)
^
﹡/
﹢﹣
#eq##ne##gt##ge##lt##le#
#and##or#
低<
==>
=
2数学函数
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函数的自然对数
@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中的最小值
例给定一个直角三角形,求包含该三角形的最小正方形。
解:
如图所示。
求最小的正方形就相当于求如下的最优化问题:
LINGO代码如下:
model:
object/1..3/:
f;
a,b=3,4;
!
两直角边,修改方便;
f
(1)=a*@sin(x);
f
(2)=b*@cos(x);
f(3)=a*@cos(x)+b*@sin(x);
min=@smax(f
(1),f
(2),f(3));
@bnd(0,x,1.57);
end
3金融函数
目前LINGO提供了两个金融函数。
1.@fpa(I,n)
返回如下情形的净现值:
单位时段利率为I,连续n个时段支付,每个时段支付单位费用。
若每个时段支付x单位的费用,则净现值可用x乘以@fpa(I,n)算得。
@fpa的计算公式为
。
净现值就是在一定时期内为了获得一定收益在该时期初所支付的实际费用。
例贷款买房问题贷款金额50000元,贷款年利率5.31%,采取分期付款方式(每年年末还固定金额,直至还清)。
问拟贷款10年,每年需偿还多少元?
50000=x*@fpa(.0531,10);
答案是x=6573.069元。
2.@fpl(I,n)
单位时段利率为I,第n个时段支付单位费用。
@fpl(I,n)的计算公式为
细心的读者可以发现这两个函数间的关系:
4概率函数(略)
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的约束。
6集操作函数
LINGO提供了几个函数帮助处理集。
1@in(set_name,primitive_index_1
[,primitive_index_2,…])
如果元素在指定集中,返回1;
否则返回0。
例全集为I,B是I的子集,C是B的补集。
I/x1..x4/;
B(I)/x2/;
C(I)|#not#@in(B,&
1):
2@index([set_name,]
primitive_set_element)
该函数返回在集set_name中原始集成员primitive_set_element的索引。
如果set_name被忽略,那么LINGO将返回与primitive_set_element匹配的第一个原始集成员的索引。
如果找不到,则产生一个错误。
例如何确定集成员(B,Y)属于派生集S3。
S1/ABC/;
S2/XYZ/;
S3(S1,S2)/AX,AZ,BY,CX/;
X=@in(S3,@index(S1,B),@index(S2,Y));
有时为@index指定集是必要的。
girls/debble,sue,alice/;
boys/bob,joe,sue,fred/;
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的成员个数。
在模型中明确给出集大小时最好使用该函数。
它的使用使模型更加数据中立,集大小改变时也更易维护。
7集循环函数
集循环函数遍历整个集进行操作。
其语法为
@function(setname[(set_index_list)
[|conditional_qualifier]]:
expression_list);
@function相应于下面罗列的四个集循环函数之一;
setname是要遍历的集;
set_index_list是集索引列表;
conditional_qualifier是用来限制集循环函数的范围,当集循环函数遍历集的每个成员时,LINGO都要对conditional_qualifier进行评价,若结果为真,则对该成员执行@function操作,否则跳过,继续执行下一次循环。
expression_list是被应用到每个集成员的表达式列表,当用的是@for函数时,expression_list可以包含多个表达式,其间用逗号隔开。
这些表达式将被作为约束加到模型中。
当使用其余的三个集循环函数时,expression_list只能有一个表达式。
如果省略set_index_list,那么在expression_list中引用的所有属性的类型都是setname集。
1.@for
该函数用来产生对集成员的约束。
基于建模语言的标量需要显式输入每个约束,不过@for函数允许只输入一个约束,然后LINGO自动产生每个集成员的约束。
例产生序列{1,4,9,16,25}
number/1..5/:
@for(number(I):
x(I)=I^2);
2.@sum
该函数返回遍历指定的集成员的一个表达式的和。
例求向量[5,1,3,4,6,10]前5个数的和。
N=6;
number/1..N/:
x=5134610;
s=@sum(number(I)|I#le#5:
x);
3.@min和@max
返回指定的集成员的一个表达式的最小值或最大值。
例求向量[5,1,3,4,6,10]前5个数的最小值,后3个数的最大值。
minv=@min(number(I)|I#le#5:
maxv=@max(number(I)|I#ge#N-2:
下面看一个稍微复杂一点儿的例子。
例职员时序安排模型一项工作一周7天都需要有人(比如护士工作),每天(周一至周日)所需的最少职员数为20、16、13、16、19、14和12,并要求每个职员一周连续工作5天,试求每周所需最少职员数,并给出安排。
注意这里我们考虑稳定后的情况。
days/mon..sun/:
required,start;
每天所需的最少职员数;
required=20161316191412;
最小化每周所需职员数;
min=@sum(days:
start);
@for(days(J):
@sum(days(I)|I#le#5:
start(@wrap(J+I+2,7)))>
=required
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LINGO 教程