本文转载于本文为CSDN博主「ChasingdreamLY」的原创文章。原文链接:原文链接
Lingo软件中存在各种各样的运算符及相关函数,能够有效的帮助我们建立并求解复杂的优化模型。
Lingo中包含9个类型的函数:
基本运算符:包含算术运算符,逻辑运算符和关系运算符
数学函数:三角函数和常规的数学函数
金融函数:Lingo提供了两种金融函数
概率函数:Lingo提供了大量的概率函数
变量界定函数:这类函数用来定义变量的取值范围
集操作函数:这类函数对集的操作提供帮助
集循环函数
数据输入输出函数
辅助函数:各种杂类函数
1.基本运算符:
算术运算符:^ (乘方);*(乘);/(除);+(加);-(减);-(一元运算符取反函数)
逻辑运算符(对应的运算优先级从高到低):
#not# 否定该操作数的逻辑值,#not#是一个一元运算符
#eq# 若两个运算数相等,则为 true;否则为 flase
#ne# 若两个运算符不相等,则为 true;否则为 flase
#gt# 若左边的运算符严格大于右边的运算符,则为 true;否则为 flase
#ge# 若左边的运算符大于或等于右边的运算符,则为 true;否则为 flase
#lt# 若左边的运算符严格小于右边的运算符,则为 true;否则为 flase
#le# 若左边的运算符小于或等于右边的运算符,则为 true;否则为 flase
#and# 仅当两个参数都为 true 时,结果为 true;否则为 flase
#or# 仅当两个参数都为 false 时,结果为 false;否则为 true
关系运算符:
Lingo中有三种关系运算符:“=”,“<=”,”>=”,需要注意的是,Lingo中不支持严格大于和严格小于关系运算符。
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 中的最小值
3.金融函数:
@fpa(I,,n):返回一个现值,其单位时间利率为I,连续支付n个时间段,该支付所对应的现值,示例程序如下:
贷款金额 50000 元,贷款年利率 5.31%,采取分期付款方式(每
年年末还固定金额,直至还清)。问拟贷款 10 年,每年需偿还多少元?
50000 = x * @fpa(.0531,10)
@fpl(I,n):返回如下情形的净现值,单位时间的利率为I,第n个时间段支付单位费用的现值,可以认为对它求和得到@fpa(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.集操作函数
7.集循环函数:
这里重点提供四个函数
@for:该函数用来产生对集成员的约束。基于建模语言的标量需要显式输入每个约束,不过@for 函数允许只输入一个约束,然后 LINGO 自动产生每个集成员的约束,示例程序如下:
model:
sets:
number/1..5/:x;
endsets
@for(number(I): x(I)=I^2);
end
@sum:该函数返回遍历指定的集成员的一个表达式的和,示例程序如下:
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
@max和@min:返回指定的集成员的一个表达式的最小值或最大值,示例程序如下:
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
————————————————
下面提供一个复杂一点的例子:
例 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
8.输入和输出函数
9.辅助函数:
@if(logical_condition,true_result,false_result):@if 函数将评价一个逻辑表达式 logical_condition,如果为真,返回 true_ result,
否则返回 false_result。
求解最优化问题,其问题的约束条件中含有分段函数,示例代码如下:
model:
min=fx+fy;
fx=@if(x #gt# 0, 100,0)+2*x;
fy=@if(y #gt# 0,60,0)+3*y;
x+y>=30;
end
下面提供一个比较基础但综合应用的例子:
例 1.2 使用 LINGO 软件计算 6 个发点 8 个收点的最小费用运输问题。产销单位运价如下表。
单
位 销地
运
价
产地
B1 B2 B3 B4 B5 B6 B7 B8 产量
A1 6 2 6 7 4 2 5 9 60
A2 4 9 5 3 8 5 8 2 55
A3 5 2 1 9 7 4 3 3 51
A4 7 6 7 3 9 2 7 1 43
A5 2 3 9 5 7 2 6 5 41
A6 5 5 2 2 8 1 4 3 52
销量 35 37 22 32 41 32 43 38
使用 LINGO 软件,编制程序如下:
model:
!6 发点 8 收点运输问题;
sets:
warehouses/wh1..wh6/: capacity;
vendors/v1..v8/: 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=60 55 51 43 41 52;
demand=35 37 22 32 41 32 43 38;
cost=6 2 6 7 4 2 9 5
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;
enddata
end
大自然的搬运工---------------------s