【数学建模】【lingo】lingo的基本操作

整体结构

lingo的代码主要分为预定义、数据的输入、目标函数、决策变量、约束条件五个板块。

注:
1、lingo代码需要以model开始,以end作为结束,但是在简单的模型中,这两个语句都可以省略。

2、每行代码后面都需要一个英文状态下的分号。

3、lingo中不区分大小写,变量名可以超过8个,但是不能超过32个,命名方式与其他编程语言要求一样,必须以字母开头,由字母、数字、和下划线组成,代码中的命名以清晰作为要求,即看到名称就可以辨认出这个变量所代表的意义。

4、lingo中的注释需要用“!”,并且在最后也需要加上分号。

5、lingo解优化模型时已经假定所有变量非负,如果想解除限制需要使用函数@free(x),这样x可以取到任意实数。

6、lingo的每个语句可以加标号,例如[OBJ],这样在输出的时候也会输出,使得我们便于识别输出结果的含义。

常用符号及语句

逻辑运算符

'''
#not# ! 否定该操作数的逻辑值;
#eq# ! 若两个运算数相等,则为true,否则为flase(equal);
#ne# ! 若两个运算符不相等,则为true,否则为flase(not equal);
#gt# ! 若左 > 右,则为true,否则为flase(greater than);
#ge# ! 若左 >= 右,则为true,否则为flase(greater than or equal than);
#lt# ! 若左 < 右,则为true,否则为flase(less than);
#le# ! 若左 <= 右,则为true,否则为flase(less than or equal than);
#and# ! 当两个参数都为true时,则为true,否则为flase(并且);
#or# ! 当两个参数都为flase,则为flase,否则为true(或者);'''

在这里插入图片描述
例如这种情况中,i本身的范围是1 ~ 20,而此处需要将其限制在1 ~ 2的范围内:

'''
@sum(link(i,j)|i#le#2:x(i,j))=1000;'''

关系运算符

关系运算符分为三种“=”, “<=”,“>=”。这三种运算符,也就是数学含义。

注:lingo中“<”,“>”分别表示小于等于和大于等于,如果需要严格小于或者严格大于,例如A < B,可以表达成
A + x <= B的形式,此处x是一个很小的正数,它的值依赖于模型中A小于B多少才符合要求。

数学函数

数学函数有很多,在这边仅列出几个常用的,在实际操作过程中如果有需要的可以自行上网查询

'''
abs(x) ! 返回x的绝对值;
exp(x) ! 返回常数e的x次方;
sin(x) ! 返回x的正弦值,x采用弧度制;
log(x) ! 返回x的自然对数;
cos(x) ! 返回x的余弦值;
lgm(x) ! 返回x的log的自然对数;
tan(x) ! 返回x的正切值;
sign(x) ! 如果x<0,返回-1,否则返回1;
smax(x1, x2, x3, x4, ...xn) ! 返回xn中的最大值;
smin(x1, x2, x3, x4, ...xn) ! 返回xn中的最小值;
floor(x) ! 向接近于0的方向取整;'''

输入输出

1、@text函数:该函数用于把数据部分分解输出到文本文件中。

'''
@text(['filename'])'''

filename是文件名,可以采用相对路径和绝对路径两种表达方式,如果忽略filename,那么数据就被输出到标准输出设备(大多情况是屏幕),右边为需要输出的集合。

用法实例:

model:
sets:
 days/mon..sun/: required,start;
endsets
data:
 !每天所需的最少职员数;
 required = 20 16 13 16 19 14 12;
 @text('d:out.txt')=days '至少需要的职员数为' start;
enddata
!最小化每周所需职员数;
 min=@sum(days: start);
 @for(days(J):
   @sum(days(I) | I #le# 5:
     start(@wrap(J+I+2,7))) >= required(J));
end

运行该代码可以在lingo所在的位置得到如下一个名为“out”的文本文件
在这里插入图片描述
2、@ole函数:从excel中引入或输出数据的接口函数

'''
x = @ole('路徑', '表格中的名字');'''

这边需要讲一下“表格中的名字”是什么意思,以excel为例,选中需要导入的数字,然后点击“公式”-“定义名称”,最后把名称改为你希望的名称即可。单击“名称管理器”可以查看所有的名称,并对其进行统一操作。

用法实例:

   x = @OLE('D:/cost.xls',f)

这个代码意思是从D盘名为“cost”的excel表格中,获取表格名为“f”的数据,并将其赋值给x。

集合的概念:

sets:
supply/1..2/:s;
demand/1..3/:d;
link(supply, demand):road, g;
endsets

初始集合分别为一维数组supply和demand,其中取值范围分别为1 ~ 2和1 ~ 3,supply和deman分别为数组的类型名,后面代表变量名。

link:衍生集合将两个集合合起来形成一个二维集合,可以理解成表格的形式,例如此题中的road和g的形式就是一个2行3列的表格。

@sum函数

@sum(数组类型名(下标) : 计算公式)

在这里插入图片描述
首先要知道在第一部分我们可以知道,求和是对i的求值,并且i为数组supply的下标范围,所以为

@sum(supply(i) : g(i, j))

同理可得:
在这里插入图片描述

@sum(link(i, j) : g(i, j) * L(i, j))

@for函数

@for(数组类型名(下标) : 具体操作)

在这里插入图片描述
我最初学的时候很难理解这个等式的意思,现在知道是:

在j分别=1、2、3的时候,对i = 1,2的情况进行累加求和判断达到相等的要求。

@for(demand(j) : @sum(supply(i) : g(i, j)) = d(j)) 

运行结果分析

在这里插入图片描述
以这个运行结果为例

Global optimal solution

整个代码运行2次得到了如下结果

Objective value

目标函数的最值,也就是运行结果为29000.00

第一个表格

两个变量的值分别取到100.0000, 和30.00000的时候得到上面所说的目标函数的值。

Reduced cost:缩减成本系数,表示变量有微小变动的时候,目标函数的变化率,如果是最优解那就自动取零。

第二个表格

Slack or Surplus:松弛或者剩余,约束条件为“<=”时,右边减左边的差值称为松弛,对于“>=”的不等式,左边减右边的差值称为剩余,当约束条件的左右两边相等,也就是理想状态时,松弛或剩余的值为0,如果约束条件无法满足,则松弛或剩余的值为0。

Dual price:影子价格,表示对应约束有微小变动的时候,目标函数的变化率。
比如说第二行:因为松弛或者剩余的值为0,所以影子价格才有意义(如果不为0,那本身都不紧,十分松的情况下+1, -1就没有这个必要),假设第二行代表的不等式是:x2 <= 10,那影子价格50的含义就是,如果把10变成11,目标函数的结果就会+50。
在这里插入图片描述

  • 25
    点赞
  • 270
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值