Lingo学习笔记
1.求解简单线性规划问题
min=2*x1+3*x2;
x1+x2>=350;
x1>=100;
2*x1+x2<=600;
Lingo笔记(集部分、数据部分与初始部分)
1.集部分
1.1 集的概念
集:由相联系的对象聚合而成,近似与其它语言中类的概念。Lingo包括两种类型的集:原始集(primitive set)和派生集(derived set)。
对象:集的成员。
属性:每个集成员之间一个或多个与之关联的特征。
原始集:由一些最基本的对象组成的。
派生集:用一个或多个其它集来定义的,也就是说,它的成员来自于其它已存在的集。
1.2 原始集的定义
//定义原始集
setname[/member_list/][:attribute_list]; //[]表示内容可选
//例子:
//使用集前需有集定义,一关键词“sets:”开始,“endsets”结束
//1.显式罗列
sets:
students/John Jill, Rose Mike/: sex, age;
endsets
//2.隐式罗列
//格式
setname/member1..memberN/[: attribute_list];
//例子
1.Oct...JAN 生成各月
2.1...5 生成1到5
3.car1...car10
1.3 派生集的定义
稠密集:成员由父集成员所有的组合构成的派生集。为父集的笛卡尔积。
稀疏集:为父集成员所有组合构成的集合的一个子集的派生集。为父集笛卡尔积的子集,即稠密集的子集。可以通过显式罗列或者设置成员资格过滤器来生成。
//定义派生集
setname(parent_set_list)[/member_list/][:attribute_list];
//例子:稠密集的生成
sets:
product/A B/;
machine/M N/;
week/1..2/;
allowed(product,machine,week):x; //将会生成了三个父集的所有组合共八组作为 allowed 集的成员
endsets
//稀疏集的生成 显式罗列 当集合元素过多时难以操作
allowed(product,machine,week)/A M 1,A N 2,B N 1/;
//稀疏集的生成 过滤器 竖线(|)为过滤器的判断开始 #eq#,#and#为逻辑运算符
sets:
//学生集:性别属性 sex,1 表示男性,0 表示女性;年龄属性 age. ;
students/John,Jill,Rose,Mike/:sex,age;
//男学生和女学生的联系集:友好程度属性 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;
endsets
data: sex,age = 1 16
0 14
0 17
0 13;
friend = 0.3 0.5 0.6;
enddata
1.4 集与c中结构体的对比
集 | 结构体 |
---|---|
setname | 结构体标签 |
member_list | 结构体实例 |
attribute_list | 结构体中变量定义 |
1.5 关于集的关系图
2.数据部分
2.1 基本语法:
object_list = value_list;
对象列(object_list):包含要指定值的属性名、要设置集成员的集名,用逗号或空格隔开。一个对象列中至多有一个集名,而属性名可以有任意多。如果对象列中有多个属性名,那么它们的类型必须一致。如果对象列中有一个集名,那么对象列中所有的属性的类型就是这个集。
数值列(value_list):给定对应对象列对象的值,用逗号或空格分隔,属性值必须等于集成员个数。
2.2 数据说明
sets:
set1/A,B,C/: X,Y;
endsets
data:
X=1,2,3;
Y=4,5,6;
enddata
//复合数据声明,作用效果同上
sets:
set1/A,B,C/: X,Y;
endsets
data:
X,Y=1 4
2 5
3 6;
enddata
2.3 数据部分值的设定
参数:即一个在数据部分确定的标量变量。
实时数据处理:有些数据在模型中值未定,需要在运行时输入,用 ? 表示值
设定集中所有成员的属性为同一数组
未知数值的设定:在求解时需要某些成员值为未知,采用设定未知值的方法,以相连逗号表示,逗号间可有空格
//参数:
data:
interest_rate = .085;
enddata
//可同时指定多个参数
data:
interest_rate,inflation_rate = .085 .03;
enddata
//实时数据处理 在每一次求解模型时,Lingo会弹出对话框填入参数
data:
interest_rate,inflation_rate = .085 ?;
enddata
//设定集中所有成员的属性
sets:
days /MO,TU,WE,TH,FR,SA,SU/:needs,cost;
endsets
data:
needs cost= 20 100; //这将设定days集中MO,TU等全部成员的need属性为20,cost属性为100
enddata
//未知值的设定
sets:
years/1..5/: capacity;
endsets
data:
capacity = ,34,20,,;
enddata
3.初始部分
初始部分输入的值仅被作为Lingo求解过程中的初始点来用,只对非线性模型有用
init:
X, Y = 0, .1;
endinit
Y=@log(X);
X^2+Y^2<=1; //求解该问题时,好的初始点会减小模型的求解时间
Lingo函数
1.基本运算符
1.1算数运算符
- (取反) ^ * / + -
1.2.逻辑运算符
返回true或false
优先级排列
#not# 一元运算符,否定操作数的逻辑值
#eq# 两个运算数相等返回ture 不等返回flase
#ne# ≠
#gt# >
#ge# ≥
#lt# <
#le# ≤
#and# 都为true返回true
#or# 都为false返回false,其余情况返回true
1.3 关系运算符
Lingo有三种关系运算符:“=”、“<=”和“>=”。
Lingo中还能用“<”表示小于等于关系,“>”表示大于等于关系。但Lingo并不严格支持大于与小于关系,于是,为了A<B成立,可以将其变为小于等于表达式A+xile B,其中xi为一个很小的正数,它的值依赖于模型中A小于B多少算不等。
1.4 运算符优先级排列
#not# -(取反)
^
* /
+ -
#eq# #ne# #gt# #ge# #lt# #le#
#and# #or#
<= = >=
2.数学函数
@abs(x) @sin(x) @cos(x) @tan(x) mod(x,y) pow(x,y) sqrt(x)
@exp(x) //返回常数e的x次方
@log(x) //返回x的自然对数
@lgm(x) //返回x的gamma函数的自然对数
@sign(x) //如果 x<0 返回-1;否则,返回 1
@floor(x) //取整。当 x>=0 时,返回不超过 x 的最大整数;当 x<0时,返回不低于 x 的最大整数。
@smax(x1,x2...xn) //最大值
@smin(x1,x2...xn) //最小值
3.金融函数
3.1 @fpa(I,n)
返回一个净现值,其单位时间利率为I,连续支付n个时间段,该支付所对应的净现值。
贷款金额 50000 元,贷款年利率 5.31%,采取分期付款方式(每年年末还固定金额,直至还清)。问拟贷款 10 年,每年需偿还多少元?
50000 = x * @fpa(.0531,10);
解得X=6573.069
3.2 @fpl(I,n)
返回一个净现值,单位时段利率为 I,第 n 个时段支付单位费用。
$$两函数关系:\quad@fpa(I,n)=\sum_{k=1}^n@fpl(I,k)$$
4.概率函数
@pbn(p,n,x) 二项分布的累积分布函数。当 n 和(或)x 不是整数时,用线性插值法进行计算。
@pcx(n,x)
@peb(a,x)
......
5.变量界定函数
变量界定函数对变量的取值范围附加限制
//通常情况下Lingo规定变量非负,可以通过@free和@bnd取消该设定
@bin(x) 限制x为0或1
@bnd(L,x,U) 限制L≤x≤U
@free(x) 取消对变量x的默认下界为0的限制,即x可以取任意实数
@gin(x) 限制x为整数
6.集操作函数
1.
@in(set_name,primitive_index_1 [,primitive_index_2,„])
如果元素位于指定集中,返回1;否则返回0
eg.
I为全集,B为I的子集,C为B的补集
sets:
I/x1..x4/;
B(I)/x2/;
C(I)|#not#@in(B,&1):;
endsets
2.
@index([set_name,] primitive_set_element)
返回在集中原始集成员的索引。如果 set_name被忽略,那么 Lingo 将返回与 所给参数匹配的第一个原始集成员的索引。
如果找不到,则报错。
eg.
确定(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)); 返回1
3.
@wrap(index,limit)
该函数返回j=index-k*limit。相当于index模limit,如果取模结果不等于0,就返回该结果,否则返回limit。
参考: https://www.docin.com/p-1185198022.html
4.
@size(set_name)
返回集set_name中的成员个数
7.集循环函数
7.1 基本语法
@function(setname[(set_index_list)[|conditional_qualifier]]:expression_list);
其中function为以下四个函数
1.@for
model:
sets:
number/1..5/:x;
endsets
@for(number(I): x(I)=I^2);
end
2.@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
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);
maxv=@max(number(I) | I #ge# N-2: x);
end
8.输入和输出函数
@flie 从外部文件中输入数据
@text 输出操作
@ole 是从 EXCEL 中引入或输出数据的接口函数
@ranged(variable_or_row_name)
@rangeu(variable_or_row_name)
@status()
@dual
9.辅助函数
1.
@if(logical_condition,true_result,false_result)
如果逻辑表达式为true,则返回true_result,否则返回false_result
eg.
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
2.
@warn(’text’,logical_condition)
如果逻辑表达式为true,则产生内容为text的消息框
eg.
model:
x=1;
@warn('x 是正数',x #gt# 0);
end