Lingo 基本使用
作者:互联网
Lingo 语法
一、 概述
1、 简介
LINGO是用来解决优化问题的一个特别好用的软件,可以快速求解线性规划、非线性规划、线性和非线性方程组等等,是数学建模中求优化问题的解不可缺少的工具之一
(1)LINGO 的数学规划模型包含目标函数、决策变量、约束条件三个要素;
(2)LINGO 程序中,每一个语句都必须要用一个英文状态下的分号结束,一个语句可以分几行输入;
(3)LINGO 的注释以英文状态的!开始,必须以英文状态下的分号结束;
(4)LINGO 的变量不区分字母的大小写,必须以字母开头,可以包含数字和下划线,不超过32 个字符;
(5)LINGO 程序中,只要定义好集合后,其他语句的顺序是任意的;
(6)LINGO 中的函数以“@”开头;
(7)LINGO 程序默认所有的变量都是非负的;
(8)LINGO 程序中"<“或”>"号与 ""或 " " 号功能相同。
2、 文件格式
- 后缀“lg4”表示lingo格式的模型文件,只有lingo软件才可打开;
- 后缀“lng”表示文本格式的模型文件;
- 后缀“ldt”表示lingo数据文件;
- 后缀“ltf”表示lingo命令脚本文件;
- 后缀“lgr”表示lingo报告文件。
3、 窗口详解
4、 优化模型
通常,一个优化模型由以下三部分组成:
- 目标函数:一般表示成求某个数学表达式的最大值或最小值
- 决策变量:目标函数数字取决于哪些变量
- 约束条件:对变量附加一些条件限制(通常用等式或不等式表示)
注意: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
2、 比较运算符
关系运算符与逻辑运算符中的比较时截然不同的,前者是模型中该关系运算符所指定关系为真描述,而后者仅仅判断一个该关系是否被满足
Lingo中有三种运算符:=
,>=、>
,和<=、<
,Lingo中并不支持严格小于和严格大于关系运算符
A < B => A <= B
3、 算术运算符
运算符 | 描述 |
---|---|
- | 取反 |
^ | 乘方 |
* | 乘 |
/ | 除 |
+ | 加 |
- | 减 |
Lingo唯一的一元算术运算符是取反运算符
运算符的优先级由高到低为:取反-》减
优先级顺序可以通过括号改变
三、 常见函数
1、 数学函数
@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 中的最小值
2、 界定函数
@bin(x) 限制x 为0 或1 — 用于0-1规划
@bnd(L,x,U) 限制L≤x≤U
@free(x) 取消对变量x 的默认下界为0 的限制,即x 可以取任意实数
@gin(x) 限制x 为整数在默认情况下,LINGO 规定变量是非负的,也就是说下界为0,上界为+∞。@free 取消了默认的下界为0的限制,使变量也可以取负值。@bnd用于设定一个变量的上下界,它也可以取消默认下界为0的约束。
3、 集循环函数
@function(setname[(set_index_list)[|conditional_qualifier]]:
expression_list);
@function相对应于下面罗列的四个集循环函数之一;setname是要遍历的集;set_index_list是集索引列表;conditional_qualifier 是用来限制集循环函数的范围,当集循环函数遍历集的每个成员时,LINGO都要对conditional_qualifier 进行评价,若结果为真,则对该成员执行@function操作,否则跳过,继续执行下一次循环。expression_list是被应用到每个集成员的表达式列表,当用的是@for函数时,expression_list 可以包含多个表达式,其间用逗号隔开。这些表达式将被作为约束加到模型中。当使用其余的三个集循环函数时, expression_list 只能有一个表达式。如果省略set_index_list ,那么在expression_list中引用的所有属性的类型都是setname集。
-
@for
该函数用来产生对集成员的约束。基于建模语言的标量需要显式输入每个约束。@for函数允许只输入一个约束,然后LINGO 自动产生每个集成员的约束。 -
@sum
该函数返回遍历指定的集成员的一个表达式的和。
-
@min和@max
返回指定的集成员的一个表达式的最小值或最大值。
4、 辅助函数
-
@if(logical_condition,true_result,false_result)
@if 函数将评价一个逻辑表达式logical_condition,如果为真返回true_ result,否则返回false_result。
-
@warn(’text’,logical_condition),如果逻辑条件logical_condition为真,则产生一个内容为’text’的信息框
其余函数可以在用到的时候去文档查询
四、 模型建立
1、 集合段
这部分要以“SETS:”开始,以“ENDSETS”结束,作用在于定义必要的集合变量(SET)及其元素(member,含义类似于数组的下标)和属性(attribute,含义类似于数组)。
为了定义一个原始集,必须详细声明:
- 集的名字
- 可选,集成员
- 可选,集成员属性
定义一个原始集,用下面的语法:
setname[/member_list/][:attribute_list]
- 括号内容表示可选
成员罗列的几种方式
- 显示罗列集成员:把所有成员名列出,用逗号" , "或空格分隔。
- 隐式罗列集成员:
setname/member1..memberN/[: attribute_list]; !用".."表示省略
- 集成员不放在集定义中,而在随后的数据部分来定义
实例:
! 常用实例方法,创建一个罗列集
SETS:
QUARTERS/1,2,3,4/:DEM,RP,OP,INV; ! 生成四个属性,初始化值都为 [1 2 3 4]
factory /1..6/:a, b; ! 生成一个 1 x 6 的矩阵
! factory 称为数组的类型名,a, b 称为数组的变量名
plant /1..8/: c, d; ! 生成一个 1 x 8 的矩阵
Cooperation(factory,plant): e, f; ! 生成一个 6 x 8 的矩阵,如果交换一个位置,则,生成一个 8 x 6 的矩阵,也可以使用 link(factory, plant) 6 x 8
! Cooperation大工厂是由factory和plant两家小工厂合并而办,可生产6×8的矩阵
ENDSETS
! 初始化数据
DATA:
a = 1, 2, 3, 4, 5, 6
ENDDATA:
需要赋值的矩阵必须赋满,不能给6个元素的矩阵只赋3个数值。
Lingo中可以给矩阵赋整数,也可以赋小数。
2、 目标和约束段
这部分实际上定义了目标函数、约束条件等,但这部分并没有段的开始和结束标记,因此实际上就是除其它4个段(都有明确的段标记)外的lingo模型。
这里一般要用到函数。例如:
MIN = @SUM(QUARTERS:400*RP+450*OP+20*INV); ! @sum为一个求和函数,对这个一维数组求400*RP + 450*OP + 20*INV 的和,第一个参数传入集合的类型
@FOR(QUARTERS(I):RP(I)<40); ! 对 QUARTERS 进行遍历,传入类型名称,后面是操作,同时自动遍历PR里面的内容
@FOR(QUARTERS(I):I#GT#1:INV(I)=INV(I-1)+RP(I)+OP(I)-DEM(I););
INV(1) = 10+RP(1)+OP(1)-DEM(1);
五、 案例
1、 运输与选址
某公司有6个建筑工地,位置坐标为(ai, bi) (单位:公里),水泥日用量di (单位:吨)
i 1 2 3 4 5 6
a 1.25 8.75 0.5 5.75 3 7.25
b 1.25 0.75 4.75 5 6.5 7.75
d 3 5 4 7 6 11
现有2料场,位于A (5, 1), B (2, 7),记(xj,yj),j=1,2, / i=1~6日储量ej各有20吨。
假设料场和工地之间有直线道路,制定每天的供应计划,即从A, B两料场分别向各工地运送多少吨水泥,使总的吨公里数最小。
取决策变量c_ij表示i工地从j料场运来的水泥量。模型(线性模型)为:
\[ {matrix} \text{min} \sum_{j=1}^2{\sum_{i=1}^6{c_{ij}\sqrt{(x_j-a_i)^2+(y_j-b_i)^2}}}\\ s.t\left\{\begin{matrix} \sum_{j=1}^2 c_{ij}=d_i. i=1,2,...,6 \\ \sum_{i=1}^6 c_{ij} \le e_j,j=1,2 \end{matrix}\right. $$ {matrix} 则,求解可得: ```lingo MODEL: SETS: demand/1..6/: a, b, d; supply/1,2/:e, x, y; link(demand, supply): c; ENDSETS DATA: a=1.25 8.75 0.5 5.75 3 7.25; b=1.25 0.75 4.75 5 6.5 7.75; d=3 5 4 7 6 11; x=5 2; y=1 7; e=20 20; ENDDATA MIN=@SUM(link(i, j):c(i, j)*@SQRT((a(i)-x(j))^2+(b(i)-y(j))^2)); ! express; @FOR(demand(i):@SUM(supply(j):c(i,j))=d(i)); ! condition1; @FOR(supply(j):@SUM(demand(i):c(i,j)) < e(j)); ! condition2; END ``` ### 2、 最优选择 某钻井队要从10个可供选择的井位中确定5个钻井探油,使总的钻探费用为最小。若10个井位的代号为s1,s2…,s10,相应的钻探费用c1,c2,…,c10为5,8,10,6,9,5,7,6,10,8.并且井位选择上要满足下列限制条件: (1) 或选择s1和s7,或选择钻探s9; (2) 选择了s3或s4就不能选s5,或反过来也一样; (3) 在s5,s6,s7,s8中最多只能选两个. 试建立这个问题的整数规划模型,确定选择的井位。 可以采用真值表建立约束条件表达式 取0-1变量s_i,若s_i=1,则表示选取第i个井,若s_i=0,则表示不选取第i个井。建立数学模型如下: $$ {matrix} \text{min} \sum_{i=1}^{10} {s_ic_i}\\ s.t \left\{\begin{matrix} (s_1+s_7 - 2)(s_9)=0 \\ s_3s_5+s_4s_5=0\\ s_5+s_6+s_7+s_8 \le 2\\ \sum_{i=1}^{10}s_i=5\\ s_i \in {0, 1}(i=1,2,...,10)\end{matrix}\right. $$ {matrix} 则,求解可得: ```lingo MODEL: SETS: var/1..10/:s,c; ! 创建集合 ENDSETS DATA: c=5 8 10 6 9 5 7 6 10 8; ! 给集合赋值 ENDDATA MIN = @SUM(var(i):s(i)*c(i)); ! 求解结果 (s(1)+s(7)-2)*s(9) = 0; ! 条件1 s(3)*s(5)+s(4)*s(5)=0; ! 条件2 s(5)+s(6)+s(7)+s(8)<2; ! 条件3 @SUM(var(i):s(i))=5; ! 条件4 @FOR(var(i):@BIN(s(i))); ! 条件5,使用for循环对s的每一个值进行约束,1代表true END ```\]标签:基本,10,函数,list,运算符,Lingo,使用,true,LINGO 来源: https://www.cnblogs.com/liuzhongkun/p/16504677.html