Lingo编写格式
lingo程序以model开始,以end结束。中间的语句分为四大部分:
(1)集合部分(sets)
这部分以“sets”开始,以“endsets”结束
这部分的作用为:定义必要的变量
分为两类:一类是原始集合,语法为:
集合name1/成员列表1/:属性1_1,属性1_2,……,属性1_n1;
集合name2/成员列表2/:属性2_1,属性2_2,……,属性2_n2;
另一类是导出集合,语法为:
导出集合名称(集合名称1,集合名称2):属性3_1,……,属性3_n3;
示例:
(2)数据部分(data)
这部分以“data”开始,以“enddata”结束
其作用在于对集合的属性(数组)输入必要的数值
语法为:
data:
属性1=数据列表;
属性2=数据列表;
enddata
(3)变量的初始化(init)
这部分以"init"开始,以”endinit“结束
其作用在于对集合的属性(数值)定义初值
示例:
(4)目标与约束
这部分定义目标函数,约束条件等。一般要用到lingo的内部函数。
注:
- Lingo中是不区分大小写字符的
- Lingo中数据部分不能用分式(列入1/3一类的式子都是”非法“的)
- LIngo中的注释使用”!“引导
- Lingo中默认所有的变量都是非负的
Lingo 常用数学函数:
@abs(x)@sin(x)@cos(x)@tan(x)@exp(x)@log(x)@lgm(x)@mod(x,y)@sign(x)@floor(x)@smax(x1,x2,…,xn)@smin(x1,x2,…,xn)
变量界定函数
变量界定函数实现对变量取值范围的附加限制,共 4 种:
@bin(x)@bnd(L,x,U)@free(x)@gin(x)
@free@bnd
集循环函数
集合函数的用法如下:
其中set_operator是集合函数名字(相应于下面罗列的四个集循环函数之一)
set_name是数据集合名
condition是条件,用逻辑表达式描述(无条件时可省略)
可以用三种逻辑算符:#AND#(与),#OR#(或),#NOT#(非)
和六种关系运算符:#EQ#(等于),#NE#(不等于),#GT#(大于),#GE#(大于等于),#LT#(小于),#LE#(小于等于)
expression是表达式
集循环函数具体有:
对集合(set_name)的每个元素独立生成约束,约束由约束表达式(constraint_expressions)描述
示例:将数组{1,3,5,7,9}中所有元素翻倍
结果如下图:
- @sum(set_name,set_element):返回遍历指定的集成员的一个表达式(set_element)的和。
- @min和@max(set_name,set_element):返回指定的集成员的一个表达式(set_element)的最小值或最大值。
- @size(set_name):返回数据集中包含的元素个数
- @in(set_name,set_element):如果数据集setname中包含元素set_element则返回1,否则返回0。
示例:
求向量[5,4,2,1,7,6]前四个数的最小值以及后三个数的最大值,以及向量的总和
概率函数
@pbn(p,n,x)@pcx(n,x)@peb(a,x)@pel(a,x)@pfd(n,d,x)@pfs(a,x,c)@phg(pop,g,n,x)@ppl(a,x) Poisson@pps(a,x)@psl(x)@psn(x)@ptd(n,x)@qrand(seed)@qrand
必看!!!必定动手做一遍!!!
用lingo求解规划类问题示例,以及知识点补充
有四种资源被用于生成三种产品,资源量,产品单件可变费用,单件售价,资源单耗量及组织三种商品生成的固定费用见下表:
现要求制定一个生产计划,使总收益最大。
求解过程:
设Xj是第j种产品的产量,j=1,2,3;
设Yj=1代表生产第j种产品(即Xj>0),若不生产第j种产品则Yj=0(Xj=0)
第I种产品销量一件可收入7-4=3元
第II种产品销量一件可收入10-6=4元
第III种产品销量一件可收入20-12=8元
则可以得到整数规划模型为:
目标函数:
max Z = 3x_{1}+4x_{2}+8x_{3}-100y_{1}-150y_{2}-200y_{3}
约束条件:
2x_{1}+4x_{2}+8x_{3}\leq500
2x_{1}+3x_{2}+4x_{3}\leq300
x_{1}+2x_{2}+3x_{3}\leq100
3x_{1}+5x_{2}+7x_{3}\leq700
x_{1}\leq M_{1}y_{1}
x_{2}\leq M_{2}y_{2}
x_{3}\leq M_{3}y_{3}
x_{j}\geq0 且为整数,j=1,2,3
y_{1}=0 或1,j=1,2,3
M_{j}为x_{j} 的上界,可取M=50
lingo代码:
结果如图:
X1=100,X2=0,X3=0,最大收入Z=200
补充部分:
导入Excel数据
Lingo通过@OLE函数实现于Excel文件传递数据,既可以导出数据也可以写入数据
(1)变量名1,变量名2=@OLE(‘文件名’,‘数据块名称1’,‘数据块名称2’)
若变量是初始集合的属性,则对应的数据块应当是一列数据,若变量是二维导出集合的属性,则对应数据块应当包含类型相同的两列数据。
@OLE函数无法读取三维数据区域
(2)变量名1,变量名2=@OLE(‘文件名’,‘数据快名称’)
左边的两个变量必须定义在同一个集合中,@OLE的参数仅指定一个数据快名称,该数据快应当包含类型相同的两列数据,第一列赋值给变量1,第二列赋值给变量2.
(3)变量名1,变量名2=@OLE(’文件名‘)
没有指定数据块名称,默认使用Excel中于属性同名的数据块。
注:
Excel中数据块的命名,具体做法是
1,先选中数据区域
2,从菜单上选择”插入“,”名称“,”定义“命令
3,弹出”定义名称“对话框,输入适当的名称,然后单击”确定“。