极力推荐观看教程作者视频,不止包含知识点,同时包含随堂练习帮助你巩固知识。我自己记的笔记肯定没有视频教程讲的仔细。链接
LINGO可以建立 简单模型 和 基于集合的专业模型 两种模型。
对于LINGO,所有参数默认非负,不区分大小写。注释以 ! 开始, ; 结束。
简单模型只是由目标函数和约束条件组成。最大最小以MAX、MIN表示。
基于集合的专业模型(一般包含下面三部分)
MODEL:
SETS:
!集合段(集合定义)
ENDSETS
DATA:
!数据段(数据定义)
ENDDATA
!约束段(目标函数与约束条件定义部)
END
线性规划模型的三种形式
一般形式
向量形式
矩阵形式
LINGO窗口。
查看运行结果时的几个标志
Global optimal soluion:全局最优解
Objectie alue:目标函数值
Infeasibilities:不可行性,不满足约束方程的个数,未满足的约束条件总数(最好情况为0)
Total soler iterations:迭代次数(越复杂,次数越多)
Variable:变量
Reduced Cost:各个变量的检验数
Slack or Surplus:松弛或剩余(对于约束条件中不等式的式子,小于号的表示宽松,大于的表示宽松)
Dual Price:对偶价格
线性规划解的类型:
唯一最优解——Global Optimal Solution
多重最优解,LINGO只会找到其中一个,且不会提示你这种情况。
退化解,基变量取值为0的最优解(结果中包含很多0)
无边界——Unbounded solution
无可行解——No feasible solution
LINGO建模语言
标识符
给对象命名使用的字符串(对象包括集合、元素、常量、变量、约束(非必须))
命名规范
字母、下划线***开头,后续字符只能是***字母、数字或下划线。
最长32字符,不区分大小写。
算数运算符
符号 | 含义 |
---|---|
- | 取相反数 |
- | 减法 |
^ | 乘方 |
* | 乘法 |
/ | 除法 |
+ | 加法 |
取反和减法都是用 - 号,对于弹幕运算符表示取反,双目运算符表示减法。
运算符优先级别:取反>乘方>乘法>除法>加法>减法
加()会改变次序。
逻辑运算符
运算对象是两个数 | 含义 | 运算规则 |
---|---|---|
#EQ# | 相等 | 两个运算对象相等时为真,否为假 |
#NE# | 不相等 | 两个运算对象不相等时为真,否为假 |
#GT# | 大于 | 左边大于右边为真,否为假 |
#GE# | 大于或等于 | 左边大于或等于右边时为真,否为假 |
#LT# | 小于 | 左边小于右边时Wie真,否则为假 |
#LE# | 小于或等于 | 左边小于或等于右边时为真,否为假 |
运算对象必须是逻辑值或逻辑表达式 | 含义 | 运算规则 |
---|---|---|
#NOT | 逻辑取反 | 单目运算符,表示对运算对象取反,真——假,假——真 |
#AND | 逻辑与 | 只有两个运算对象都是真,结果才真,否则为假 |
#OR | 逻辑或 | 两个对象中有一个真就真,否则假 |
逻辑运算符优先级 | 运算符 |
---|---|
高 | #NOT# |
中 | #EQ# #NE# #GT# #GE# #LT# #LE# |
低 | #AND# #OR# |
关系运算符
运算符 | 规则 |
---|---|
= | 相等 |
<= | 小于等于 |
>= | 大于等于 |
LINGO中没有严格的小于、大于,在LINGO中小于被看作小于等于,大于被看作大于等于。如果非要表示小于,需要在一侧加上一个足够小的值。
常用函数
幂函数
函数名 | 返回值 | 数学公式 |
---|---|---|
@SQR(X) | 返回X的平方。与X^2等价 | x2 |
@SQRT(X) | 返回X的正平方根。与X^0.5等价 | √X |
@POW(X,Y) | 返回X的Y次方。与X^Y等价。 | XY |
指数函数和对数函数
函数名 | 返回值 | 数学公式 |
---|---|---|
@EXP(X) | 返回eX,其中e是自然常数,e=2.718281828…… | eX |
@LOG(X) | 返回X的自然对数值 | lnX |
@LOG10(X) | 返回X的常用对数值 | log10X=lgX |
@LGM(X) | 返回X的Gamma函数的自然对数值。当X为整数时,LGM(X)=LOG(X-1)!,当X不是整数时,采用线性插值得到结果 | ln[(X-1)!] |
如果想输入logab怎么办?logab=lnb/lna=lgb/lga
三角函数与反三角函数
函数名 | 返回值 | 数学公式 |
---|---|---|
@SIN(X) | 返回X的正弦函数值,其中X的单位是弧度 | sinx |
@COS(X) | 返回X的余弦函数值,其中X的单位是弧度 | cosx |
@TAN(X) | 返回X的正切函数值,其中X的单位是弧度 | tanx |
@ASIN(X) | 返回X的反正弦函数值,其中X的单位是弧度 | arcsinx |
@ACOS(X) | 返回X的反余弦函数值,其中X的单位是弧度 | arccosx |
@ATAN(X) | 返回X的反正切函数值,其中X的单位是弧度 | arctanx |
@ATAN2(Y,X) | 返回Y/X的反正切函数值,其中返回值的单位是弧度 | arctan(y/x) |
注意,如果你输入的是角度(15°),使用时需要转成弧度(15/180*3.14159265)
双曲函数与反双曲函数
函数名 | 返回值 | 数学公式 |
---|---|---|
@SINH(X) | 返回X的双曲正弦函数值,其中X的单位是弧度 | sinhx=(eX-e-X)/0.5 |
@COSH(X) | 返回X的双曲余弦函数值,其中X的单位是弧度 | coshx=(eX+e-X)/0.5 |
@TANH(X) | 返回X的双曲正切函数值,其中X的单位是弧度 | tanhx=(eX-e-X)/(eX+e-X) |
@ASIN(X) | 返回X的双曲反正弦函数值,其中X的单位是弧度 | arsinhx |
@ACOSH(X) | 返回X的双曲反余弦函数值,其中X的单位是弧度 | arcoshx |
@ATANH(X) | 返回X的双曲反正切函数值,其中X的单位是弧度 | artanhx |
其他数学函数
函数名 | 返回值 |
---|---|
@ABS(X) | 返回X的绝对值 |
@SIGN(X) | 返回X的符号值(如果X<0,返回-1,否则,返回+1,0直接返回0) |
@MOD(X,Y) | 返回X除以Y的余数 |
@FLOOR(X) | 返回X的整数部分(想最靠近0的方向取整) |
@SMAX(X1,X2……XN) | 返回X1,X2……XN这若干参数的最大值 |
@SMIN(X1,X2……XN) | 返回X1,X2……XN这若干参数的最小值 |
变量定界函数
函数名 | 返回值 |
---|---|
@BIN(X) | 限制X为0-1变量,即X的值只能取0或1.用于0-1规划 |
@GIN(X) | 限制X只取整数。用于整数规划 |
@FREE(X) | X为自由变量(X可取任意实数值) |
@BND(L,X,U) | 限制X的上下界,L≤X≤U,L和U可以是负数 |
杂函数
@IF(logical_condition,true_result,false_result)——计算logical_condition的值,如果真返回true_result,否则返回false_result。
原始集合
例子:背包问题
给定n个物品,在每件物品重量、价值、背包最大载重已知的情况下,如何进行选择才能使装入背包的物品总价值最高。对于所有物品,在不能拆开的情况下,物品只有装与不装两个选择,就可以简化为0(不装),1(装)。这样的问题就是0-1问题。
如果只考虑重量这一约束条件就称为一维背包问题;考虑重量和容积两个约束条件就称为二维背包问题。
例:有10件货物要从甲地运送到乙地,每件货物的重量(单位:吨)和利润(单位:元)如下表所示:
物品 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
重量(t) | 6 | 3 | 4 | 5 | 1 | 2 | 3 | 5 | 4 | 2 |
利润(元) | 540 | 200 | 180 | 350 | 60 | 150 | 280 | 450 | 320 | 120 |
只有一辆最大载重量30t的货车来运货,所以,只能选择一部分货物运送。确定运送哪些货物,总利润最大。
分析:这是一个一维0-1背包问题。只考虑容量这一束缚条件。
引入0-1决策变量xi,1表示运,0表示不运。则10件货物有x1……x10。
这里讲i=1 ~ 10写作集合的形式。
再转化为向量形式。
一般建立模型并求解的过程
定义集合
给常量赋值
目标函数的表达式
约束条件的表达
模型求解
定义货物的集合:
集合元素可以是数字也可以是字符串。
ITEM/1 2 3 4 5 6 7 8 9 10/;!ITEM为集合名字,集合元素可以用空格、制表符或逗号隔开(显示罗列);
ITEM/1,2,3,4,5,6,7,8,9,10/;也可以这样写(显示罗列);
ITEM/1..10/;还可以这样写,表示1到10的整数(隐式罗列);
定义向量:
向量与集合一起定义,在LINGO中称为集合的属性(Attribute)。向量和前面集合的元素一一对应。
给常量赋值:
给常量赋值要在DATA段(数据段中赋值)。在数据段赋过值的就是常量,没有的就是变量。
DATA: !数据段起始;
WEGHT =6 3 4 5 1 2 3 5 4 2;
PROFIT =540 200 180 350 60 150 280 450 320 120;
ENDDATA !数据段结束;
目标函数的表达:
MAX=@SUM(ITEM(I):PROFIT(I)*X(I));
约束条件的表达:
@SUM(ITEM(I):WEIGHT(I)*X(I))<=30;
变量取值范围的约束:
xi只能是0-1变量。
@FOR函数用于在集合的成员之间生成约束。
@FOR(ITEM(I):@BIN(X(I)));
整段程序
MODEL:
SETS:
ITEM/1 2 3 4 5 6 7 8 9 10/:WEIGHT,PROFIT,X;
ENDSETS
DATA:
WEIGHT=6 3 4 5 1 2 3 5 4 2;
PROFIT=540 200 180 350 60 150 280 450 320 120;
ENDDATA
MAX=@SUM(ITEM(I):PROFIT(I)*X(I));
@SUM(ITEM(I):WEIGHT(I)*X(I))<=30;
@FOR(ITEM(I):@BIN(X(I)));
END
最终结果
这是有10个x的情况下,当参数庞大的时候这样并不好查看。
工具栏点击solution按钮(前面讲过)
设置查看的参数
就可以单独查看某一参数。
还可以勾选非0,这样就只显示装的物品。
原始集合的语法规则
定义:通过举例全部元素所定义的集合(Primary Set)是原始集合,又称为基本集合。
通过原始集合派生的集合是派生集合。
原始集合和派生集合都在集合段中定义。
集合段以 SETS: 开始 ,以 ENDSETS 结束。
定义原始集合的方法集合名/集合的元素列表/:集合的属性列表;
集合命名
起始字符只能是字母或下划线,后续支付只能是字母、数字或下划线。
标识符最长32个字符。
标识符不区分大小写。
集合元素的命名
起始字符只能是字母或下划线,后续支付只能是字母、数字或下划线。
标识符最长32个字符。
标识符不区分大小写。
另外,集合元素可以是整数。
罗列方式:有显示罗列和隐式罗列。
显示罗列 | 隐式罗列 |
---|---|
将集合的没哟个元素都列出来 | 集合元素有一定的递增规律,就可以写成起始元素…终止元素 |
隐式罗列的全部表示形式
格式 | 实例 | 集合元素 |
---|---|---|
1…n | 1…6 | 1,2,3,4,5,6 |
alphM…alphN | a…h | a,b,b,d,e,f,g,h |
stringM…stringN | truck6…truck12 | truck6,truck7,truck8…,truck12 |
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 |
集合的属性列表
就是上面例子中后面那几个,属性之间只能用逗号分隔开。
给常量赋值的三种形式
在数据段总,有三种方法:
每个向量单独赋初值(上面的例子)
相同集合的属性(相同结构的向量)共同赋予初值。
集合与集合的属性共同赋予初值
集合遍历函数
函数名 | 返回值 |
---|---|
@FOR(s:e) | 对集合s的每一个元素都生成一个约束条件表达式,具体约束有e描述 |
@SUM(s:e) | 对集合s中的每一个元素,计算表达式e的值,然后返回这些值的和 |
@MAX(s:e) | 对集合s中的每一个元素,计算表达式e的值,然后返回最大值 |
@MIN(s:e) | 对集合s中的每一个元素,计算表达式e的值,然后返回最小值 |
@PROD(s:e) | 对集合s中的每一个元素,计算表达式e的值,然后返回这些值的乘积 |
***如果集合遍历函数中只有一个集合,而且是对这个集合中所有袁术进行相同操作,可以省略其中的集合元素变量(或下标)。
@FOR(ITEM(I):@BIN(X(I)));
!可以写成;
@FOR(ITEM:@BIN(X));
派生集合
例子:运输问题
某糖果公司有三个加工厂A1、A2、A3,没听的糖果生产量分别是7吨,4吨和9吨,该公司要讲这些糖果分别运送到四个地区的门市部B1B2B3B4销售,每天的销售量分别是3吨,6吨,5吨,6吨,现在已知从每个加工厂Ai到各个销售门市部Bj之间每吨糖果的运价(单位:百元)如下表所示。该糖果厂应该如何调运糖果,在满足各门市部销售需要的情况下,使总的运费支出最少。
B1 | B2 | B3 | B4 | 产量 | |
---|---|---|---|---|---|
A1 | 3 | 11 | 3 | 10 | 7 |
A2 | 1 | 9 | 2 | 8 | 4 |
A3 | 7 | 4 | 10 | 5 | 9 |
销量 | 3 | 6 | 5 | 6 |
用ai(i=1,2,3)表示第i个加工厂的产量(单位:吨)
用bj(j=1,2,3,4)表示第j个门市部的销量(单位:吨)
用cij(i=1,2,3;j=1,2,3,4)表示单位运价,即从第i个加工厂向第j个门市部宋一吨糖果的价格(百元)
设决策变量xij(i=1,2,3;j=1,2,3,4)为从第i加工厂给第j门市部的糖果数量(吨)
一般形式数学模型
整段程序:
LINK(FACTORY,SHOP):C,X;就是派生集合。体现了两个集合之间的关系。
MODEL:
SETS:
FACTORY/1..3/:A;
SHOP/1..4/:B;
LINK(FACTORY,SHOP):C,X;
ENDSETS
DATA:
A=7 4 9;
B=3 6 5 6;
C=
3 11 3 10
1 9 2 8
7 4 10 5;
ENDDATA
MIN=@SUM(LINK(I,J):C(I,J)*X(I,J));
@FOR(FACTORY(I):
@SUM(SHOP(J):X(I,J))=A(I));
@FOR(SHOP(J):
@SUM(FACTORY(I):X(I,J))=B(J));
END
构造派生集合的方法
派生集合的名字(父集合1,父集合2,…,父集合N)[/元素列表/][:属性列表];