MENU

lingo学习笔记

October 23, 2020 • Read: 24 • 杂谈阅读设置

Lingo学习笔记


1.求解简单线性规划问题

min=2*x1+3*x2;
x1+x2>=350;
x1>=100;
2*x1+x2<=600;

Lingo笔记(集部分、数据部分与初始部分)


1.集部分

1.1 集的概念

:由相联系的对象聚合而成,近似与其它语言中类的概念。Lingo包括两种类型的集:原始集(primitive set)和派生集(derived set)。

对象:集的成员。

属性:每个集成员之间一个或多个与之关联的特征。

原始集:由一些最基本的对象组成的。

派生集:用一个或多个其它集来定义的,也就是说,它的成员来自于其它已存在的集。

1.2 原始集的定义

//定义原始集
setname[/member_list/][:attribute_list]; //[]表示内容可选

//例子:
//使用集前需有集定义,一关键词“sets:”开始,“endsets”结束

//1.显式罗列
sets:
students/John Jill, Rose Mike/: sex, age;
endsets

//2.隐式罗列
     //格式
     setname/member1..memberN/[: attribute_list];
     //例子
     1.Oct...JAN 生成各月
     2.1...5 生成1到5
     3.car1...car10

1.3 派生集的定义

稠密集:成员由父集成员所有的组合构成的派生集。为父集的笛卡尔积。

稀疏集:为父集成员所有组合构成的集合的一个子集的派生集。为父集笛卡尔积的子集,即稠密集的子集。可以通过显式罗列或者设置成员资格过滤器来生成。

//定义派生集
setname(parent_set_list)[/member_list/][:attribute_list];

//例子:稠密集的生成
sets:
product/A B/;
  machine/M N/;
  week/1..2/;
  allowed(product,machine,week):x; //将会生成了三个父集的所有组合共八组作为 allowed 集的成员
endsets

//稀疏集的生成 显式罗列   当集合元素过多时难以操作
  allowed(product,machine,week)/A M 1,A N 2,B N 1/;

//稀疏集的生成 过滤器 竖线(|)为过滤器的判断开始  #eq#,#and#为逻辑运算符

sets:
  //学生集:性别属性 sex,1 表示男性,0 表示女性;年龄属性 age. ;
  students/John,Jill,Rose,Mike/:sex,age;
  //男学生和女学生的联系集:友好程度属性 friend,[0,1]之间的数。 ;
  linkmf(students,students)|sex(&1) #eq# 1 #and# sex(&2) #eq# 0: friend;
  //男学生和女学生的友好程度大于 0.5 的集;
  linkmf2(linkmf) | friend(&1,&2) #ge# 0.5 : x;
endsets
data: sex,age = 1 16
                0 14
                0 17
                0 13;
friend = 0.3 0.5 0.6;
enddata

1.4 集与c中结构体的对比

结构体
setname结构体标签
member_list结构体实例
attribute_list结构体中变量定义

1.5 关于集的关系图

2.数据部分

2.1 基本语法:

object_list = value_list;

对象列(object_list):包含要指定值的属性名、要设置集成员的集名,用逗号或空格隔开。一个对象列中至多有一个集名,而属性名可以有任意多。如果对象列中有多个属性名,那么它们的类型必须一致。如果对象列中有一个集名,那么对象列中所有的属性的类型就是这个集。

数值列(value_list):给定对应对象列对象的值,用逗号或空格分隔,属性值必须等于集成员个数。

2.2 数据说明

sets:
  set1/A,B,C/: X,Y;
endsets
data:
  X=1,2,3;
  Y=4,5,6;
enddata

//复合数据声明,作用效果同上
sets:
  set1/A,B,C/: X,Y;
endsets
data:
  X,Y=1 4
      2 5
      3 6;
enddata

2.3 数据部分值的设定

参数:即一个在数据部分确定的标量变量。

实时数据处理:有些数据在模型中值未定,需要在运行时输入,用 ? 表示值

设定集中所有成员的属性为同一数组

未知数值的设定:在求解时需要某些成员值为未知,采用设定未知值的方法,以相连逗号表示,逗号间可有空格

//参数:
data:
  interest_rate = .085;
enddata
//可同时指定多个参数
data:
  interest_rate,inflation_rate = .085 .03;
enddata

//实时数据处理 在每一次求解模型时,Lingo会弹出对话框填入参数
data:
    interest_rate,inflation_rate = .085 ?;
enddata

//设定集中所有成员的属性
sets:
  days /MO,TU,WE,TH,FR,SA,SU/:needs,cost;
endsets
data:
  needs cost= 20 100;  //这将设定days集中MO,TU等全部成员的need属性为20,cost属性为100
enddata

//未知值的设定
sets:
  years/1..5/: capacity;
endsets
data:
  capacity = ,34,20,,;
enddata

3.初始部分

初始部分输入的值仅被作为Lingo求解过程中的初始点来用,只对非线性模型有用

init:
  X, Y = 0, .1;
endinit
Y=@log(X);
X^2+Y^2<=1;  //求解该问题时,好的初始点会减小模型的求解时间

Lingo函数


1.基本运算符

1.1算数运算符

  • (取反) ^ * / + -

1.2.逻辑运算符

返回true或false

优先级排列
#not#  一元运算符,否定操作数的逻辑值

#eq#   两个运算数相等返回ture 不等返回flase
#ne#   ≠
#gt#   >
#ge#   ≥
#lt#   <
#le#   ≤

#and#  都为true返回true
#or#   都为false返回false,其余情况返回true

1.3 关系运算符

Lingo有三种关系运算符:“=”、“<=”和“>=”。

Lingo中还能用“<”表示小于等于关系,“>”表示大于等于关系。但Lingo并不严格支持大于与小于关系,于是,为了A<B成立,可以将其变为小于等于表达式A+xile B,其中xi为一个很小的正数,它的值依赖于模型中A小于B多少算不等。

1.4 运算符优先级排列

#not# -(取反)
^
* /
+ -
#eq# #ne# #gt# #ge# #lt# #le#
#and# #or#
<= = >=

2.数学函数

@abs(x) @sin(x) @cos(x) @tan(x) mod(x,y) pow(x,y) sqrt(x)
@exp(x) //返回常数e的x次方
@log(x) //返回x的自然对数
@lgm(x) //返回x的gamma函数的自然对数
@sign(x) //如果 x<0 返回-1;否则,返回 1
@floor(x) //取整。当 x>=0 时,返回不超过 x 的最大整数;当 x<0时,返回不低于 x 的最大整数。
@smax(x1,x2...xn) //最大值
@smin(x1,x2...xn) //最小值

3.金融函数

3.1 @fpa(I,n)

返回一个净现值,其单位时间利率为I,连续支付n个时间段,该支付所对应的净现值。

贷款金额 50000 元,贷款年利率 5.31%,采取分期付款方式(每年年末还固定金额,直至还清)。问拟贷款 10 年,每年需偿还多少元?

50000 = x * @fpa(.0531,10);

解得X=6573.069

3.2 @fpl(I,n)

返回一个净现值,单位时段利率为 I,第 n 个时段支付单位费用。

$$两函数关系:\quad@fpa(I,n)=\sum_{k=1}^n@fpl(I,k)$$

4.概率函数

@pbn(p,n,x) 二项分布的累积分布函数。当 n 和(或)x 不是整数时,用线性插值法进行计算。

@pcx(n,x)

@peb(a,x)

......

5.变量界定函数

变量界定函数对变量的取值范围附加限制

//通常情况下Lingo规定变量非负,可以通过@free和@bnd取消该设定

@bin(x) 限制x为0或1
@bnd(L,x,U) 限制L≤x≤U
@free(x) 取消对变量x的默认下界为0的限制,即x可以取任意实数
@gin(x) 限制x为整数

6.集操作函数

1.
   @in(set_name,primitive_index_1 [,primitive_index_2,„])
   如果元素位于指定集中,返回1;否则返回0
eg.
   I为全集,B为I的子集,C为B的补集
   sets:
      I/x1..x4/;
      B(I)/x2/;
      C(I)|#not#@in(B,&1):;
   endsets

2.
   @index([set_name,] primitive_set_element)
   返回在集中原始集成员的索引。如果 set_name被忽略,那么 Lingo 将返回与 所给参数匹配的第一个原始集成员的索引。
   如果找不到,则报错。
eg.
   确定(B,Y)属于派生集S3
   sets:
      S1/A B C/;
      S2/X Y Z/;
      S3(S1,S2)/A X, A Z, B Y, C X/;
   endsets
   X=@in(S3,@index(S1,B),@index(S2,Y)); 返回1

3.
    @wrap(index,limit)
    该函数返回j=index-k*limit。相当于index模limit,如果取模结果不等于0,就返回该结果,否则返回limit。
    参考: https://www.docin.com/p-1185198022.html

4.
    @size(set_name)
    返回集set_name中的成员个数

7.集循环函数

7.1 基本语法

@function(setname[(set_index_list)[|conditional_qualifier]]:expression_list);
其中function为以下四个函数

1.@for
  model:
  sets:
    number/1..5/:x;
  endsets
    @for(number(I): x(I)=I^2);
  end

2.@sum
  model:
  data:
    N=6;
  enddata
  sets:
    number/1..N/:x;
  endsets
  data:
    x = 5 1 3 4 6 10;
  enddata
    s=@sum(number(I) | I #le# 5: x);
  end

3.@min和@max 返回指定的集成员的一个表达式的最小值或最大值
  model:
  data:
    N=6;
  enddata
  sets:
    number/1..N/:x;
  endsets
  data:
    x = 5 1 3 4 6 10;
  enddata
    minv=@min(number(I) | I #le# 5: x);
    maxv=@max(number(I) | I #ge# N-2: x);
  end

8.输入和输出函数

@flie 从外部文件中输入数据

@text 输出操作

@ole 是从 EXCEL 中引入或输出数据的接口函数

@ranged(variable_or_row_name)

@rangeu(variable_or_row_name)

@status()

@dual

9.辅助函数

1.
  @if(logical_condition,true_result,false_result)
  如果逻辑表达式为true,则返回true_result,否则返回false_result
eg.
  model:
    min=fx+fy;
    fx=@if(x #gt# 0, 100,0)+2*x;
    fy=@if(y #gt# 0,60,0)+3*y;
    x+y>=30;
  end

2.
  @warn(’text’,logical_condition)
  如果逻辑表达式为true,则产生内容为text的消息框
eg.
  model:
    x=1;
    @warn('x 是正数',x #gt# 0);
  end
Last Modified: December 23, 2024