sets:
series/1..15/: u, znorm, zt; endsets
!第一个均匀分布随机数是任意的; u( 1) = @rand( .1234); !产生其余的均匀分布的随机数; @for(series( I)| I #GT# 1: u( I) = @rand( u( I - 1)) );
@for( series( I): !正态分布随机数;
@psn( znorm( I)) = u( I); !和自由度为2的t分布随机数; @ptd( 2, zt( I)) = u( I); !ZNORM 和 ZT 可以是负数;
@free( znorm( I)); @free( zt( I)); ); end
5.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的约束。
例:5.5.1求函数z=(x+2)2+(y-2)2的最小值。 显然,X=-2,Y=2时,z取得最小值0。 为了允许X取负数,用@free函数,程序如下: MIN=(X+2)^2+(Y-2)^2; @FREE(X);
页 第41
运行,求解结果为:目标函数最小值应该为0 ,求得的结果是很小的数0.4999617E-12,这是计算精度引起的误差。
如果在实际问题中知道变量的取值范围,就尽量告诉LINGO,不要让软件帮你大海捞针,例如,如果X的取值范围在实际中只是大于30小于50,就不要让软件在整个实数范围内去寻求最优解。有时候实际问题中还能知道或者大概感觉到最优解大致在哪个解附近,那就以初始值的形式告诉LINGO,这对于问题的求解时很有帮助的,毕竟软件是死的,而人要比计算机聪明的多。
练习:在lingo软件中输入例4.9(P39)的数学问题,熟悉LINGO的数学函数。 5.6 集操作函数
LINGO提供了几个函数帮助处理集。 1.@in(s:e1)
如果元素在指定集中,返回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(s:ek)
该函数返回在集s中原始集成员ek的索引。该值在1和集合s的成员个数之间,如果集合s 中没有该元素,则给出出错信息。
例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
页 第42
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(s)
该函数返回集s的成员个数。在模型中明确给出集大小时最好使用该函数。它的使用使模型更加数据中立,集大小改变时也更易维护。 5.7 集循环函数
集循环函数遍历整个集进行操作。 1.@for(s,e) 该函数
该函数用来产生对集成员的约束。基于建模语言的标量需要显式输入每个约束,不过@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(s:e)
该函数返回遍历指定的集成员的一个表达式的和。 例4.11 求向量[5,1,3,4,6,10]前5个数的和。 model: data: N=6; enddata
页 第43
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(s:e)和@max(s:e)
返回指定的集成员的一个表达式的最小值或最大值。
例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; enddata
minv=@min(number(I) | I #le# 5: x); maxv=@max(number(I) | I #ge# N-2: x); end
5.8 辅助函数
1.@if(logical_condition,true_result,false_result)
@if函数将评价一个逻辑表达式logical_condition,如果为真,返回true_ result,否则返回false_result。常用来表示分段函数。 例4.13 求解最优化问题
页 第44
mins.t.f(x)?g(y)x?0x?0y?0y?0?100?2x,f(x)???2x,?60?3y,g(y)???2y,x?y?30
x,y?0
其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; end
2.@warn(’text’,logical_condition)
如果逻辑条件logical_condition为真,则产生一个内容为’text’的信息框。 例4.14 示例。 model: x=1;
@warn('x是正数',x #gt# 0); End
上机练习2:
在lingo软件中输入例4.10-4.14(P45-P47),熟悉LINGO的集运算函数。 七、 综合举例(上机练习3)
例1.7.1; MODEL:
MIN=X1+X2+X3+X4+X5;
X1+X2>=100; X1+2*X3+X4>=200;
2*X2+X3+2*X4+4*X5>=400;
页 第45