lingo使用笔记(仅入门)

lingo使用教程

㈠,大致描述(平白无趣的科普)

Lingo 是一款用于线性规划、整数规划和非线性规划的优化软件。以下是一些常见的 Lingo 语法和写法的笔记,帮助你快速上手。

1. 基本结构

Lingo 模型通常由以下几个部分组成:

  • 集合定义:定义模型中使用的集合。
  • 数据输入:定义模型中的参数和数据。
  • 变量定义:定义决策变量。
  • 目标函数:定义优化目标。
  • 约束条件:定义模型的约束条件。
  • 求解命令:告诉 Lingo 进行求解。

2. 集合定义

集合用于定义索引,通常用于变量和约束的索引。

SETS:
    Warehouse /W1, W2, W3/;
    Customer /C1, C2, C3, C4/;
ENDSETS

3. 数据输入

数据可以通过 DATA 部分输入,或者从外部文件读取。

DATA:
    Demand = 100, 200, 150, 300;
    Supply = 500, 600, 700;
ENDDATA

4. 变量定义

变量可以是连续的、整数的或二进制的。

VARIABLES:
    X(Warehouse, Customer);  ! 连续变量
    Y(Warehouse);            ! 二进制变量
    Z;                       ! 连续变量

5. 目标函数

目标函数可以是最大化或最小化。

MIN = @SUM(Warehouse(i): @SUM(Customer(j): Cost(i,j) * X(i,j)));

或者

MAX = @SUM(Warehouse(i): Profit(i) * Y(i));

6. 约束条件

约束条件使用 @FOR@SUM 等函数来定义。

@FOR(Warehouse(i):
    @SUM(Customer(j): X(i,j)) <= Supply(i));

@FOR(Customer(j):
    @SUM(Warehouse(i): X(i,j)) >= Demand(j));

7. 求解命令

在模型定义完成后,使用 SOLVE 命令进行求解。

SOLVE;

8. 输出结果

可以使用 @WRITE@WRITEFOR 输出结果。

@WRITE('Optimal Objective Value: ', Z, '\n');
@WRITEFOR(Warehouse(i): 'Warehouse ', i, ' ships ', @SUM(Customer(j): X(i,j)), '\n');

9. 常用函数

  • @SUM:求和
  • @FOR:循环
  • @IF:条件判断
  • @BIN:定义二进制变量
  • @GIN:定义整数变量
  • @FREE:定义无界变量

10. 示例模型

以下是一个简单的运输问题模型:

MODEL:
    SETS:
        Warehouse /W1, W2, W3/;
        Customer /C1, C2, C3, C4/;
    ENDSETS

    DATA:
        Demand = 100, 200, 150, 300;
        Supply = 500, 600, 700;
        Cost = 2, 4, 5, 3,
              3, 1, 2, 4,
              5, 3, 2, 1;
    ENDDATA

    VARIABLES:
        X(Warehouse, Customer);
    ENDVARIABLES

    MIN = @SUM(Warehouse(i): @SUM(Customer(j): Cost(i,j) * X(i,j)));

    @FOR(Warehouse(i):
        @SUM(Customer(j): X(i,j)) <= Supply(i));

    @FOR(Customer(j):
        @SUM(Warehouse(i): X(i,j)) >= Demand(j));

    SOLVE;
END

11. 注意事项

  • Lingo 对大小写不敏感。
  • 注释使用 ! 开头。
  • 确保所有集合、变量和约束的定义正确无误。

12. 进一步学习

  • 参考 Lingo 官方文档和用户手册。
  • 练习不同类型的优化问题,如线性规划、整数规划、非线性规划等。

希望这些笔记对你使用 Lingo 有所帮助!

㈡,新手教程

一. 基本界面与解方程

1. 基本界面
  1. 点击瞄准,即运行按钮。
  2. 运行后看右下角的运行时间。
  3. 关闭后,可以看到运行的结果,以及右下角给出了变量即对应的值。
2. lingo变量
  1. 默认所有变量为非0的数字,因此非负条件不必多写。
  2. 遇到可以小于0的变量,有一个函数@free,用来使其定义域为R。
  3. Lingo 对大小写不敏感。不区分字母大小写,mm,Mm,MM为同一个变量。
  4. 无论是C,matlab,还是lingo,变量都由字母,数字,下划线组成。
  5. 命名规范:首位不能为数字,下划线,只能为字母。
3. 线性规划基础
  1. 一个线性规划中只含有一个目标函数。(两个以上是多目标线性规划,lingo无法求解,需整合为一个线性规划)
  2. 求目标函数的最值用max=…或min=…来表示。
  3. 注释以!开头,以;结尾。
  4. 线性规划与非线性规划的本质区别是目标函数是否线性,其余一致,不需要区分。

    值得注意的是,非线性规划的求解非常困难,基本得不到全局最优解。
    做建模的同学建议转化为线性来解,不然速度会很慢,并且很难得到最优解。

二. 集合VS矩阵工厂

1. 一维矩阵
sets:
factory/1..6/:a,b;
plant/1..3/:x,y;
endsets
  1. factory和plant都是制造矩阵的工厂,但是是两家不同的工厂。
  2. factory后面的/1…6/表示产生1$\times 6 的矩阵。后面的 a , b 表示生产的 1 6的矩阵。后面的a,b表示生产的1 6的矩阵。后面的ab表示生产的1\times$6的矩阵,plant同理。
  3. factory和plant是随意起的名字,a,b,x,y也是。
  4. lingo不是一行一行读代码的,sets,endsets表示矩阵生产流程的开始与终止。
2. 矩阵赋值
data:
a=1,2,3,4,5,6;
x=1,2,3;
enddata
  1. 不是所有矩阵都要赋值,有的矩阵是需要求解的变量。
  2. 赋值不能少赋值,或者多赋值。
  3. lingo中可以赋整数或者小数,不能赋分数。
  4. lingo不是一行一行读代码的,data,enddata表示赋值流程的开始与终止。
3. 函数
  • @for:循环
@for(gc(i):s=a(i)*x(i));
  1. for循环括起整个语句。
  2. for循环内部:先写工厂,表示循环次数,再写约束条件。
  3. 此时为一维矩阵,i可加可不加,也可以替换为j,k等其他字母。
  4. 二维矩阵出现时,会同时出现i,j,此时,必须加以i或j进行区分。
  • @sum:求和
@sum(gc(i):x(i))=5000;
  1. sum循环括起整个语句。
  2. sum循环内部:先写工厂,表示矩阵大小,再写约束条件。
  3. 此时为一维矩阵,i可加可不加,也可以替换为j,k等其他字母。
  4. 二维矩阵出现时,会同时出现i,j,此时,必须加以i或j进行区分。
model:

sets:
gc/1..5/:a,x;
endsets

data:
a=1,2,3,4,5;
enddata

max=s;

@for(gc(i):s=a(i)*x(i));
@sum(gc(i):x(i))=5000;

end
4. 工厂合并
sets:
factory/1..6/:a;
plant/1..2/:x;
cooperation(factory,plant):c;
endsets
  1. cooperation大工厂由factory和plant两个小工厂合并而成,生产6×2的矩阵。
  2. 名字随意起。
5. 例题

m i n z = ∑ i = 1 6 ∑ j = 1 8 c i j ⋅ x i j min \quad z=\sum_{i=1}^{6}\sum_{j=1}^{8}c_{ij}\cdot x_{ij} minz=i=16j=18cijxij

{ ∑ j = 1 8 x i j ≤ a i , i = 1 , 2 , ⋯   , 6 ∑ i = 1 6 x i j = d j , j = 1 , 2 , ⋯   , 8 x i j ≥ 0 , i = 1 , ⋯   , 6 , j = 1 , ⋯   , 8 \begin{cases} \sum_{j=1}^{8}x_{ij} \leq a_{i},i=1,2,\cdots,6 \\ \sum_{i=1}^{6}x_{ij} =d_{j},j=1,2,\cdots,8 \\ x_{ij} \geq 0,i=1,\cdots,6,j=1,\cdots,8 \end{cases} j=18xijai,i=1,2,,6i=16xij=dj,j=1,2,,8xij0,i=1,,6,j=1,,8

model:

sets:
factory/1..6/:a;
plant/1..8/:d;
coo(factory,plant):c,x;
endsets

data:
a=60,55,51,43,41,52;
d=35,37,22,32,41,32,43,38;
c=6,2,6,7,4,2,5,8
  4,9,5,3,8,5,8,2
  5,2,1,9,7,4,3,3
  7,6,7,3,9,2,7,1
  2,3,9,5,7,2,6,5
  5,5,2,2,8,1,4,3;
enddata

min=@sum(coo(i,j):c(i,j)*x(i,j));

@for(factory(i):@sum(plant(j):x(i,j))<=a(i));
@for(plant(j):@sum(factory(i):x(i,j))=d(j));

end

三. 运算符与内置函数

1. 运算符
  1. 算术运算符
  • @aqrt:开平方
  1. 关系运算符
  • lingo中只有三种关系运算符:“=”,“>=”,“<=”。
    若要严格表达A>B,可采取以下方式:
b=10;
e=0.000001;
A-e=b;
因为在求最优化方案时,x>2与x>=2的相差非常小
  1. 逻辑运算符

    • 两个数字之间
    运算符 理解 作用
    #eq# equal 相等为真
    #ne# not equal 不相等为真
    #gt# greater than A>B为真
    #ge# greater equal A>=B为真
    #lt# less than A
    #le# less equal A<=B为真
    • 逻辑表达式之间
    运算符 理解 作用
    #not# 非门 取反
    #and# 与门 左右两边均真才真
    #or# 或门 左右两边均假才假
2. 运算符的使用
2.1 for循环或sum求和
model:

sets:
plant/1..6/:a;
endsets

data:
a=6,5,4,3,2,1;
enddata

y=@sum(plant(i)|i#ge#5 : a(i));

end
@for(plant(i)|
	i#le#2 #or# i#ge#5 : d(i)>5);

使用方法:@sum(矩阵工厂 | 判断条件 : 矩阵);

2.2 if判断
  1. 函数: 0 ≤ x ≤ 500 0\leq x \leq500 0x500,代码如下:
x#ge#0 #and# x#le#500
x#le#500
  1. if函数的嵌套功能
@if(x#le#500,4*x,@if(x#gt#1000,1500+2*x,500+3*x));

使用方法:@if(判断,成功执行片段,相当于else(f否时执行片段));
特别提醒:else的部分不可省略

3. 变量定界函数
函数 作用
@bin(x) 限制x只能取0或1,0-1规划中有用
@gin(x) 限制x为整数,整数规划中有用
@bnd(a,x,b) 限制a ≤ \leq x ≤ \leq b
@free(x) 取消对x非负的默认限制,使其定义域自由
4. 数学函数
类别 函数名 返回值
三角函数 @sin(x) 返回x的正弦值
@cos(x) 返回x的余弦值
@tan(x) 返回x的正切值
指数函数 @log(x) 返回x的自然对数值,其他底数使用换底公式
@exp(x) 返回 e x e^{x} ex的值,因为无法敲出e的值而诞生
其他 @abs(x) 返回x的绝对值
@sigh(x) 返回x的符号值,整数为1,负数为-1
@floor(x) 返回x的整数部分,向下取整
比较大小 @smax(x1,…,xn) 返回其中最大值
@smin(1,…,xn) 返回其中最小值
5.集合(矩阵)操作函数
类别 函数名 作用
常用 @for(factory:a>0) 循环
@sum(factory:a) 求和
有用 @prod(factory:a) 求积
@max(factory:a) 求最大值
@min(factory:a) 求最小值
很少用 @in(factory,c) 判断常数c是否在集合中
@size(factory) 返回可生产矩阵长度

你可能感兴趣的:(笔记)