Lingo 基本使用

Lingo 基本使用

目录Lingo 语法一、 概述1、 简介2、 文件格式3、 窗口详解4、 优化模型二、 基本运算符1、 逻辑运算符2、 比较运算符3、 算术运算符三、 常见函数1、 数学函数2、 界定函数3、 集循环函数4、 辅助函数四、 模型建立1、 集合段2、 目标和约束段五、 案例1、 运输与选址2、 最优选择

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料场运来的水泥量。模型(线性模型)为:

\[\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.

\]

则,求解可得:

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个井。建立数学模型如下:

\[\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.

\]

则,求解可得:

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

相关推荐