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#
注:算数运算符(+,-,×,/)和关系运算符(=,>=,<=)与其他语言等类似,特殊之处为LINGO不严格支持大于或者等于关系,若需要表示A<B则可以表示为A+o<B,其中o为一个很小的正数,其值依赖于模型中A小于B多少才算不等。
所有操作符的优先级:
高 #not# -(取反)
^
* /
+ -
#eq# #ne# #gt# #ge# #lt# #le#
#and# #or#
低 <==>=
2. 数学函数
@abs(x) 返回x的绝对值
@cos(x) 返回x的余弦值
@sin(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. 变量界定函数
变量界定函数实现对变量取值范围附加限制,共4中:
@bin(x) 限制x为0或1
@bnd(L,x,U) 限制L<=x<<U
@free(x) 取消变量x的默认下届为0的限制,即x可以为任意数
@gin(x) 限制x为整数
4.概率函数
-
@pbn(p,n,x):二项分布的函数,当n或x不是整数时,用线性插值法进行计算
-
@pcx(n,x):自由度为n的 分布函数
-
@peb(a,x):当到达负荷为a,服务系统有x个服务器且允许无穷插队时的Erlang繁忙概率
-
@pel(a,x):当到达负荷为a,服务系统有x个服务器且不允许排队时的Erlang繁忙概率
-
@pfd(n,d,x):自由度为n和d的F分布的分布函数
-
@pfs(a,x,c):当负荷上限为a,顾客数为c,平行服务器数量为x时有限资源的Possion服务系统的等待或返修顾客数的期望值,a是顾客数乘以平均服务时间,再除以平均返修时间。当c或x不是整数时,采用线性插值进行计算
-
@phg(pop,g,n,x):超几何分布的分布函数。pop表示产品总数,g是正品数。从所有产品中任意取出n(n<=pop件),其中有x件是正品的概率。pop,g,n,x都可以是非整数,此时采用线性插值进行计算
-
@ppl(a,x):Poisson分布的线性损失函数,即返回max{0,z-x}的期望值,其中随机变量z服从均值为a的Poisson分布
-
@pps(a,x):Poisson分布的分布函数,当x不是整数时,采用线性插值进行计算
-
@psl(x):单位正态线性损失函数,即返回max{0,z-x}的期望值,其中随机变量z服从标准正态分布
-
@psn(x):标准正态分布的分布函数
-
@ptd(n,x):自由度为n的t分布函数
-
@qrand(seed):产生服从(0,1)区间的拟随机数。@qrand只允许在模型的数据段使用,它将用拟随机数填满集的属性。通常声明一个m×n的二维表,m表示运行中实验的次数,n表示每次实验所需要的随机数的个数。在行内,随机数是独立分布的;在行间,随机数是均匀分布的。模型中的参数不能用此函数赋值
-
@rand(seed):产生0~1的伪随机数,依赖于指定的种子。典型用法是U(I+1)=@rand(U(I)).注意,如果seed不变,那么产生的随机数也不变
5.集操作函数
- @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
- @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
- @wrap(index,limit):
该函数返回j=index-limit×k,相当于index模limit再加1
- size(set_name):
该函数返回名为"set_name"的集的成员个数
6. 集循环函数
集循环函数整个集进行操作。其语法是
@function(setname[(set_index_list))[|conditional_qualifier]]:expression_list);
其中@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
s=@sum(number(I)|I#le#5:x);
end
(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";
end
下面来看一个稍微复杂一点的例子
例:职员时序安排模型 一项工作一周七天都需要有人,每天(周一至周日)所需的最少职员数位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
(4)@prod:内积
7. 输入输出函数
-
@file('filename')
-
txt读取函数
-
当文件中的数据读完以后,若程序运行中还遇到从文件中读数据的语句,将报告1017号系统错误
-
注意防止文件双重拓展名,即打开系统文件显示中的文件拓展名选项
-
.txt可以用LINGO自带的文本编辑器的ldt文件代替
-
文件名不可以用引号“”括起来
-
在Lingo中不允许嵌套调用@file函数
-
-
@text('filename')
-
将运行结果写入文本文件中的函数
-
-
@ole('filename')
-
EXCEL读写函数
-
-
@ranged(varieble_or_row_name)
-
为了保持最优基不变,变量的费用系数或约束行右端项允许减少的量
-
-
@rangeu(varieble_or_row_name)
-
为了保持最优基不变,变量的费用系数或约束行的右端项允许增加的量
-
-
@status()
-
返回LINGO模型求解结束后的状态,返回值分别表示以下意义:
-
0 Global Optimum(全局最优)
-
1 Infeasible(不可行)
-
2 Unbounded(无界)
-
3 Undetermined(不确定)
-
4 Feasible(可行)
-
5 Infeasible or Unbouded(通常需要关闭"预处理"选项后重新求解模型,以确定模型究竟时不可行还是无界)
-
6 Local Optimun(局部最优)
-
7 Localli Infeasible(局部不可行,尽管可行解可能存在,但是Lingo并没有找到一个)
-
8 Cut Off(目标函数的截断值被达到)
-
9 Numeric Error(求解器因在某约束中遇到无定义的算数运算而停止)
-
-
@dual(varieble_or_row_name)
-
返回变量的判别数(又称检验数)或约束行的对偶(又称影子价格)
-
8. 辅助函数
-
@if(logical_condition,true_result,flase_result)
-
作用如变量名
-
-
@warn('text',logical_condition)
-
如果logical_condition为真,则产生一个内容为'text'的信息框
-
Lingo学习笔记,参考《数学模型与实验》——王绍恒,王良伟与博客https://blog.csdn.net/duxinyuhi/article/details/51698391