模板
直接通过例子来看lingo的写法,下面有三种常见类型
sets:
person/X,Y,Z/:old;
index/x,y/:i;
endsets
data:
i=1,3;
old=2,3,4;
enddata
min=@sum(index(j):old(i));
sets:
yu/1..3/:y,x;
endsets
data:
y=2,?,4;
enddata
init:
x=1,,3;
endinit
min=@max(yu(i):x*y);
@for(yu(i):@bnd(1,x,3));
sets:
yu/Nov2012..Jan2013/:y;
cong/w,q/:i;
meng(yu,cong);
zhu(yu,meng);
endsets
data:
y=1,2,3;
i=1,3;
enddata
min=@sum(zhu(l,j,k):y(i));
对于左边这个模型,cong、zhu、zhe是person集里的成员(其实设置成员名称一般没有什么实际意义,更多是为了起标识符作用,因此,一般采用隐式成员写法),cong、zhe是集index里的成员,old是person集里每个成员的通用属性,i是index集里每个成员的通用属性,1,3则对应index集里每个成员的i属性值,2,3,4则对应person集里每个成员的old属性值。目标函数的index(j)为遍历index集(j从1取到n——index集中成员的个数,j为默认的遍历系数,默认的遍历系数一般为i,j,k,l等,因此,除非特殊情况,不要把属性名写成这些默认的遍历系数),每一次遍历,以j为每项最底层属性脚标,然后向外扩展,得到响应返回值(因此,这就是为什么可以略去脚标的原因),最后通过集函数对所有返回值进行处理(例如,最左边i为最底层属性,遍历后依次返回i(1),i(2),然后向外层扩展,依次做old的脚标,即old(1),old(3),最后sum函数对old(1),old(3)进行相加处理)。
对于中间这个模型,用的就是隐式成员说明,y,x是每个成员的通用属性,2,?,4对应每个成员的y属性值(?指在运行时输入值)。当数据不确定或故意缺省时采用,,记录。init代表初始化值,一般用于比较确定条件下的初始化或者非线性规划中。
右边为连续派生集,遍历效果相当于嵌套for循环,若表达式某单项最底层属性没有脚标,则默认用派生集最右边的集脚标。
隐式成员
隐式成员用于有规律的多成员的表示,下面为常用类型
隐式成员列表形式 | 示例 | 所产生的集成员 |
---|---|---|
1..n | 1..5 | 1,2,3,4,5 |
StringM..StringN | Car2..Car14 | Car2,Car3,Car4,…,Car14 |
DayM..DayN | Mon..Fri | Mon,Tue,Wed,Thu,Fri |
MonthM..MonthN | Oct..Jan | Oct,Nov,Dec,Jan |
MonthYearM..MonthYearN | Oct2001..Jan2002 | Oct2001,Nov2001,Dec2001,Jan2002 |
结果分析
object value: 目标函数结果
Global optimal solution found at iteration: 迭代的次数
Variable:模型中的变量
Variable Value:对应最优解
Reduced Cost:对应最优解的微小变化带来的目标函数的变化率
Row:约束条件的对应编号
Row Slack or Surplus:对应约束条件的剩余值
Dual Price:对应约束的微小变动带来的目标函数变化率
灵敏度分析
当系数或者限制条件变化时的最优解、最优基、最优值变化情况,只针对线性规划
最优基:
Variable:模型中的变量
Current Coefficient:当前目标函数系数
Allowable Increase:系数允许增加量(保证最优解不变,但最优值改变)
Allowable Decrease:系数允许减少量
Row:约束条件的对应编号
Current RHS:当前约束条件右边常数项
Allowable Increase:常数项允许增加量(保证最优基不变,但最优解、最优值均改变)
Allowable Decrease:常数项允许减少量
运算符
主要有算数运算符、关系运算符、逻辑运算符三种
算数运算符
符号 | 说明 |
---|---|
- | 取反 |
^ | 乘方 |
* | 乘 |
/ | 除 |
+ | 加 |
- | 减 |
关系运算符
符号 | 说明 |
---|---|
= | 等于 |
<= | 小于等于 |
>= | 大于等于 |
逻辑运算符
符号 | 说明 |
---|---|
#not# | 否定,一元运算符 |
#eq# | 相等返回true |
#ne# | 不相等返回true |
#gt# | 大于返回true |
#ge# | 大于等于返回true |
#lt# | 小于返回true |
#le# | 小于等于返回true |
#and# | 与操作 |
#or# | 或操作 |
运算符优先级
高 #not# -
| ^
| * /
| + -
| #eq# #ne# #gt# #ge# #lt# #le#
| #and# #or#
低 <= = >=
函数
主要分辅助函数、循环函数、集操作函数、变量定界函数、数学函数、文件函数和概率函数
辅助函数
@if(条件|约束条, 成立返回值, 不成立返回值):约束条件用逻辑运算符,条件用逻辑运算符
@warn('...', 条件):条件为真时显示warn
循环函数
@for(集名|约束条件:表达式):约束条件用逻辑运算符,条件用逻辑运算符
@sum(集名|约束条件:表达式):同上
@min(集名|约束条件:表达式):同上(@max)
集操作函数
@in(集名, a, b... ):a,b...在集中返回1,不在返回0
@size(集名):查看集成员的个数
@index(集名):返回集成员在派生集中的脚标,不能用于派生集
@wrap(a,b):返回a(mod)b+1
变量定界函数
@bin(x):限制x为0或1
@bnd(L,x,U):限制L<=x<=U
@free(x):取消对变量x的默认下界为0的限制
@gin(x):限制x为整数
数学函数
@abs(x):返回x的绝对值
@sin(x):返回x的正弦值,x采用弧度制(@cos(x)、@tan(x))
@exp(x):返回常数e的x次方
@log(x):返回x的自然对数
@sign(x):如果x<0返回-1;否则,返回1
@floor(x):返回小于x的最大整数(无论正负)
@smax(x1,x2,...,xn):返回x1,x2,...,xn中的最大值(@smin)
文件函数
@file('filename'):导入txt文件数据
@text('filename'):导出txt文件数据
概率函数
a=@qrand():产生随机矩阵返回给a,a必须是集,返回矩阵的元素都在0~1之间
@psn(x):标准正态分布在x累计函数值(@ptd(x)——t分布)
总结
- title: 模型取名函数,可有可无
- model/end: 模型开始、结束的标志,可有可无
- 要想以一个符号代表一个长式子,直接写等式即可,lingo默认为约束条件
- 为使求解速度加快,可以使用变量初始化,init: … endinit,因为lingo是上下震荡找最优解的
- 数据初始化和数据输入部分不能给集中单独的元素赋值,要想赋值,其它值可以缺省,但还是需以集属性名作为输入部分
- 最好只用lingo解线性规划,非线性规划除非变量非常少使用,否则即使多加几万个变量也要转换为线性规划(P-中位问题