简学lingo(一)——基础篇

随着建模培训的进程,越来越发现自己所知有限。这里记录下自己学习LINGO的过程,一点一点来呗!

 

1 模型的集部分

集部分是LINGO模型的可选部分。在使用LINGO模型中使用集之前,必须在集部分事先定义。集部分以关键字“sets:”开始,以“endsets”结束。一个模型可以没有集部分。

 

1.1 定义原始集

定义一个原始集。用下面的语法:

       setname[/member_list/][:attribute_list];     注意:用"[ ]"表示部分内容可选

setname是你选择标记集的名字,最好具有较强的可读性。member_list是集成员列表。如果集成员放在集定义中,那么可以对他们进行显示罗列和隐式罗列,也可以在随后的数据本分定义它们。当显示罗列成员时,用逗号或者是空格来隔开,如:

sets:
  students/John Jill,Rose,Mike/:sex,age;
endsets


当隐式显示成员是,则可采用下面的语法:

setname/membew1..memberN/[:attribute_list];

此时LINGO将自动产生member1到memberN中间的所有成员名。

另外,我也可以这样定义数据:

sets:
  products/A B/;
  machine/M N/;
  week/1..2/;
  allowed(product,machine,week):x;
endsets

 

1.2派生集

 另外,除了原始集外还有派生集

students/Jhon,Jill,Rose,Mike/:sex,age;
linkmf(students,students)|sex(&1)#eq#1and#sex(&2)#eq#0:friend;

用竖线(|)表示成员资格过滤器的开始。

2.模型的数据部分和初始部分

2.1模型的数据部分

数据部分以关键字“data:”开始,以关键字“enddata”结束,在这里可以指定集成员,集的属性。其语法如下

object_list=value_list;

这里给出例子

sets:
  set1/A,B,C/:X<Y;
endsets
data:               !这里也可以这样复制赋值
  X=1,2,3;          X,Y=1 4
  Y=4,5,6;              2 5
enddata                 3 6;   

另外,我们也可以指定参数

data:
  interest_rate,inflation_rate=.085




 

 2.2 模型的初始部分

一个初始部分以“init:”开始,以“endinit”结束。初始部分的初始声明规则和数据部分的数据声明的规则相同。也就是说,我们可以再声明的左边同时初始化多个集属性,可以吧集属性初始化为一个值,可以用问号实现实时数据处理,还可以用逗号指定未知数据。

 

init:
  X,Y=0,.1;
endinit
Y=@log(X);
X^2+Y^2<=1;


 

3. LINGO函数

 

3.1 逻辑运算符

#not#    否定该操作数的逻辑值

#eq#     若两个运算数相等,则为true,否则false;

#ne#     若两个运算符不相等,则为true,否则为false

#gt#      若左边的运算符严格大于右边的运算符,则为true,否则为false

#ge#     若左边的运算符严格大于或等于右边的运算符,则为true,否则为false

#lt#       若左边的运算符严格小于右边的运算符,则为true,否则为false

#lg#       若左边的运算符严格大于右边或等于的运算符,则为true,否则为false

#and#    即逻辑且

#or#      逻辑或

 

 优先级由高到低

高   #not#

       #eq#  #ne#  #gt#  #ge#  #lt#  #le#

低   #and#  #or#

 

3.2 数学函数

@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)  返回x1x2…,xn中的最大值
 
@smin(x1,x2,…,xn)  返回x1,x2,…,xn中的最小值

这里给出一个例子

model:
sets:
object/1..3/:f;
endsets
data:
  a,b=3,4;
enddata
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.3变量界定函数

变量界定函数实现对变量取值范围附加限制,共4中:

@bin(x)           限制x为0或1

@bnd(L,x,U)        限制L<=x<<U

@free(x)         取消变量x的默认下届为0的限制,即x可以为任意数

@gin(x)           限制x为整数

 

 

3.4 集操作函数

 

(1)@in(set_name,primitive_index_1[,primitive_index_2,...])

如果元素在指定集内则返回1,否则返回0;

sets:                          全集为I,C为B的补集
  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被忽略,那么它将返回第一个原是集成员的索引。

sets:                 如何确定集成员(B,Y)属于派生集S3
  S1/A B C/;
  S2/X Y Z/;
  S3(S1,S2)/A X,A Z,B,Y,C X/;
endsets
  <a target=_blank href="mailto:X=@in(S3,@index(S1,B),@index(S2,Y));">X=@in(S3,@index(S1,B),@index(S2,Y));
</a>


 3.5集循环函数

集循环函数整个集进行操作。其语法是

@function(setname[(set_index_list))[|conditional_qualifier]]:expression_list);</span>

其中@function是对应的四个集循环之一;setname是要遍历的集;set_index_list是集索引列表;conditional_qualifier是用来限制集循环函数范围,当集循环函数遍历集的每个成员时,LINGO都要对其进行评价,只有当结果为真时,才会执行@function操作,否则跳过,进行到下一次循环。expression_list是被应用到每个及成员函数的表达式列表。当是@for时,它可以包含多个表达式,用逗号隔开;否则其只能含有一个函数。这些表达式将被作为约束加到模型中去。


下面使用例子依次介绍四个集循环函数

(1)@for

该函数用来产生对集成员的约束。@for函数允许只输入一个约束,然后LINGO自动产生每个集成员的约束。

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

model:
sets:
  number/1..5/:x;
endsets
  @for(number(I):x(I)=I^2);
end

 


 

(2)@sum

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

例:求向量【5,1,3,4,6,10】前五个数的和。

model:
data:
  N=6;
enddata
sets:
  number/1..N/:x;
endsets
data:
  x=5 1 3 4 6 10;
enddata
  <a target=_blank href="mailto:s=@sum(number(I)|I#le#5:x);end">s=@sum(number(I)|I#le#5:x);
end</a>


(3)@min和@max

该函数返回指定的集成员的一个表达式的最小值或者是最大值

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";                                                                                         <span style="color:#000000;"> </span>     <a target=_blank href="mailto:maxv=@max(number(I)|I#ge#N-2:x);end">   maxv=@max(number(I)|I#ge#N-2:x);
end</a>


 

 

(4)检测

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

例:职员时序安排模型  一项工作一周七天都需要有人,每天(周一至周日)所需的最少职员数位20,16,13,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));    !@WRAP(INDEX, LIMIT)返回的是 INDEX - K * LIMIT 其中K是一个整数 它使得返回值落到[1,LIMIT]上;
end


 

 

 

 

  • 37
    点赞
  • 180
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值