22.4.7马上就要参加五一建模了,因此特意学习了lingo建模写下这篇学习笔记,也就当巩固自己的知识了。话不多说咱进入正题!

在此也特别感谢up主:爆肝杰哥

目录

前言:lingo软件安装下载

一、认识lingo软件界面

二、lingo变量

 三、线性规划基础

 四、使用矩阵结果多数据问题

4.1生成一维工厂

4.2矩阵的赋值

4.3for循环

4.4sum求和

4.5综合运用

五、二维矩阵

5.1工厂合并——生成二维矩阵

5.2二维矩阵的赋值

六、for、sum二维一维矩阵综合运用 

七、运算符

7.1算数运算符

7.2关系运算符 

 7.3逻辑运算符

八、Lingo内置函数 

8.1if判断 

8.2变量定界函数 

8.3数学函数 

前言:lingo软件安装下载

详情请参照文章LINGO 18.0安装教程_COCO56(徐可可)的博客-CSDN博客_lingo下载安装教程

一、认识lingo软件界面

我们先以一个简单的解方程来了解一下它的基本功能

解方程:X + 1 = 2 ;直接在空白页书写你的目标方程。

同时我们点击红色的靶子,就是点击进行运算的按钮

接着它会跳出两个界面,第一个我们只需要看它的运算时间,其他的都是浮云

 第二个界面是运算结果,我们也只需要重点关注一下结果,其他地方基本无用

 在这个例子里我们有几点需要特别注意:

1.lingo里的每一个语句都是要用‘ ; ’来结尾,否则系统报错

2.注意lingo下的输入的符号都要是英文符号,不能是中文符号!

3.在lingo里的加减乘除符号分别是:+、-、*、/

4.在lingo里的乘号不可以省略,比如2x是需要写成2*x的

我们再写一个方程组来说明一下:

在lingo内的代码则为:

二、lingo变量

在lingo里有几个系统自己定义的规则需要注意:

1)在lingo里系统默认变量都是大于等于0的,因此建模里非负的条件可以省略。但是当有的变量是有可能为负的时候那怎么办呢,我们可以用@free函数来定义这个变量使其定义域为R

2)在lingo里我们不区分大小写,因此aaa、aAa、AAA、aaA都是同一个变量。

3)在lingo里变量命名和大部分编程语言一样,由数字、字母和下划线组成,同时数字不能开头

同样我们用一个例题来感受一下:

在lingo里的代码则为:(注意非负条件可以省略)

 

 三、线性规划基础

1)一个线性规划只能含有一个目标函数(lingo无法直接解多目标函数)

2)求目标函数的最大值或最小值分别用max=...或min=...来表示

3)lingo内的注释格式是以‘ ! ’开始,以‘ ; ’来结束。

4)注意非线性解十分困难,基本得不到全局最优解。因此我们在遇到非线性解的时候,我们最好将非线性的转换为线性的来解。

我们这里用一个简单的线性模型来说明一下:

 同时我们在lingo里的代码则为:

 四、使用矩阵结果多数据问题

我们首先引用一道例题,是需要使用我们求和公式来解决的。

 我们先使用枚举法来解决一下

通过这个案例了解到我们的表达式很简单,但是我们的代码却十分繁琐,因此我们就要引入矩阵这个概念。

4.1生成一维工厂

我们首先看一个一位矩阵的代码:

 本代码所对应的知识点:

1)factory和plant都是制造矩阵的工厂,但是他们是两家不同的工厂。

2)factory工厂的/1..6/说明它是一个专门生产1x6的矩阵,那么它后面出现的a、b都是1x6的矩阵;那么同理我们plant这个工厂是一个生产1x3的矩阵的工厂,那么x、y都是1x3的矩阵。

3)工厂的名字和矩阵的名字都是可以随便起的,但是要注意一下命名的规则。

4)以上的语句本质上是定义四个行矩阵的大小,而矩阵工厂只是一个中介,用来告诉系统这是一个矩阵。

5)lingo里的代码和其他编程语言略有不同的是,lingo的代码并不是一行一行读代码的,所以用sets:和endsets表示矩阵工厂生产流程的起止。

4.2矩阵的赋值

矩阵工厂不能只生产矩阵,还要给矩阵赋初值才行,那么我们要怎么赋值呢,请看我的截图

本代码所对应的知识点:

1)不是每个矩阵都需要赋值,你也可以不赋值,比如我们的x矩阵。有些矩阵就是我们要求的解

2)需要赋值的矩阵必须赋满,不能给6个元素的矩阵你只赋值3个

3)lingo中可以给矩阵赋多种类型的数据(整数和小数)

4)lingo不是一行一行读代码的,所以我们一定要用data:和enddata表示矩阵赋值的起止。 

4.3for循环

在我们建模的过程中,不可避免会有这样的约束表达式

在遇到这样的表达式的时候,我们如果没有学习for循环就需要自己一条一条的输入,这实在是太麻烦了,因此我们需要引入for循环来解决这个问题

 先直接上lingo代码替换上式再来解释

 1)for循环,括起整行语句,因为S=aixi,i=1,2,... ,5,其实是相当于5个约束条件

2)for循环内部,先写工厂来告诉for循环几次,之后再加上约束条件

3)此处的i可带可不带,但最好带上方便代码查看。同时这个i不是固定的,也可以是j,k,m等等。

4)二维矩阵工厂出现后,同时出现i,j,那时不可以省略必须要带上i,j。

for循环使用的标志:约束条件后面有i=1,2,... ,5,一定在最外面套上for。

4.4sum求和

在建模过程中,最最经常用的就是求和公式的使用,比如

 

那么在这里我们就不可避免地要使用sum求和公式使用

 

 1)sum求和不可以括起完整地约束条件,说人话就是这个等号后面地东西咱不能放在括号里面。!!这里请注意和for循环区分开,for循环等号后面的内容是需要被括号括起来的。

2)sum求和内部,先写工厂,告诉sum求和几次,之后再上接约束条件。

3)此处的i规则和for循环相同,可带可不带,但是二维矩阵不可以省略

在这里咱浅解释一下关于for循环和sum求和等号内容不同的原因:

在for循环里,我们的表达式是完整的,我们就是想表达S=a1x1,S=a2x2,...,因此我们在循环的时候,我们是需要带上这个S=在括号里面的,不然整个表达式循环就是a1x1,a2x2这样。

而我们的sum求和不一样,我们的sum就不需要,因为我们这个式子其实就是想表达x1,x2,...,到x5全部加起来等于5000,如果把5000放进括号里,那么我们整个式子就是5个5000相加。

sum求和出现的标志:当出现求和公式的时候,我们必须要使用sum

4.5综合运用

 学完两个函数,我们将他们综合运用起来

ps:使用了矩阵工厂创建矩阵后,整个程序都需要用model:和end包起来

在lingo的代码

 

五、二维矩阵

5.1工厂合并——生成二维矩阵

我们首先来看一个6x8的矩阵在lingo里的代码

 1)由代码可以看出(看不出也没关系听我说),cooperation是一个大工厂,它是由factory和plant两家小工厂合并举办的,可以生产6x8的矩阵

2)a是1x6的矩阵,d是1x8的矩阵,c和x都是6x8的矩阵。

3)如果将cooperation(factory,plant)中的factory与plant调换位置,则生产8x6的矩阵

4)工厂合并的名字cooperation是随便取的,为了方便理解,它的名字只要符合命名规则的都可以

5.2二维矩阵的赋值

二维矩阵的赋值规则和一维的一样

具体的相信大家看了图片就会懂了!

 

六、for、sum二维一维矩阵综合运用 

咱先来看看题目是个什么鬼样

 ok我们现在开整来写代码

这就是我们在建模过程中将会使用的完整lingo代码,那么我也来浅解释一下for与sum的嵌套使用

一般来说,我们都是先使用for循环在最外层,同样的我们先写上工厂的名字,那么到底是写哪个工厂呢。我们的方法其实就是看你这个循环你需要循环几次,你要循环几次,你就使用哪个工厂。因为对于for来说一维工厂生产的矩阵的列数就是循环的次数。接着我们写上表达式,其实都是一样的,只是这个表达式用sum来代替了,因此我们开始使用sum求和。sum求和里使用的工厂其实判断方法和for的一样,注意一下等号后面的不要进括号!

七、运算符

7.1算数运算符

两张图帮助你理解完

题目:

lingo代码 :

7.2关系运算符 

1)关系运算符往往用于约束条件中,用来指定约束条件左右两边必须满足的关系

2)lingo只有三种关系运算符:‘=’、‘>=’以及‘<=’

lingo里没有单独的‘>’和'<',若出现了lingo则视为省略了‘=’。 

 7.3逻辑运算符

分类运算符理解作用
数字间#eq#equal两个运算对象相等为真
数字间#ne#not equal两个运算对象不相等为真
数字间#gt#greater than左边大于右边为真
数字间#ge#greater equal左边大于等于右边为真
数字间#lt#less than左边小于右边为真
数字间#le#less equal左边小于等于右边为真
表达式间#not#非门单目运算符,表示取反
表达式间#and#与门左右两边均正确才为真
表达式间#or#或门左右两边均错误才为假

 逻辑运算符唯一出现的位置:

1)for循环与sum求和

2)if判断中(极少用)

这么看这个表格宛如天书一般,那么现在我们用三个例题来解释与使用一下表格里的这些东西

题目1:

 我们的lingo代码

 

其中1#ge#5的意思就是要让左边的i大于等于5时开始运算

题目2:

 lingo代码:

 这里表示的就是,当i小于3以及当i大于等于5时,要让a(i)>5,最后结果为20。有小伙伴疑惑了为什么会是20呢,那4个5相加可不就是20嘛。那明明说了大于5怎么会等于5呢,原因就是请看前面的内容

题目3:

lingo代码:

这里就不用我多解释了吧,懂的都懂

八、Lingo内置函数 

8.1if判断 

提示:

1)if判断通常仅仅在分段函数出现,一般其出现的频率、使用次数十分之低。

 2)Lingo中的if函数必须自带一个else,好基友不分家

那么我们通过例题来理解这个简简单单的if函数

题目1:

 lingo代码:

8.2变量定界函数 

函数作用记忆
@bin(x);限制x只能取0或1,0-1规划中特别有用有bin就是1,没bin就是0
@gin(x);限制x为整数,在整数规划中有用哽成整数
@bnd(x);限制a<=x<=b,推荐直接替换两个约束条件b和d对称,两边夹住变量n
@free(x);取消对变量x非负的限制,使其定义域自由好家伙这还用记?

ok话不多说咱直接题目上理解:

题目1:

 

lingo代码:

 大家觉得答案是什么呢,没有错就是6!!!

题目2:

 lingo代码:(大家有看到xi的取值为1或0,此时我们就要使用0-1规划) 

 @gin(x)与@bin(x)的用法相同!

8.3数学函数 

类别函数名返回值
三角函数@sin(x)返回x的正弦值
三角函数@cos(x)返回x的余弦值
三角函数@tan(x)返回x的正切值
指数对数@log(x)返回x的自然对数值,其他底数用换底公式
指数对数@exp(x)返回e^x的值,因e的数值无法敲入而诞生
其它@abs(x)返回x的绝对值
其它@sigh(x)返回x的符号值,x>=0为1,x<0为-1
其它@floor(x)返回x的整数部分,向靠近0的方向取整
比较大小@smax(x1,x2,..,xn)返回其中的最大值
比较大小@smin(x1,x2,..,xn)返回其中的最小值

 它们的用法其实和上面的函数其实差不多

Lingo基础到这就差不多结束啦,有机会咱再出进阶内容!