Lingo 的基本使用入门

Lingo 的基本使用

哎,什么都得自学……学校课程欠缺好大……

lingo 的语法

注意除号为 /

表示次方,使用 ^ eg:x^2

lingo 不区分大小写,eg:mmm、Mmm、mMm 都视为同一个变量。(Spss 也不区分哦)

lingo、Matlab 中变量的命名不要使用驼峰式,使用下划线,且字母在首位。

lingo 不读取空格

model end 关键词可以不添加。但是 使用矩阵工厂创建矩阵后,整个程序需用 model:end 包起来。

Lingo 17 有时候会报一些语法错误,但是明明没有错误……

注意:Lingo 中的代码表示的是方程组,这点很重要。不能将计算机语言中的一些默认特性带入 Lingo。比如:Lingo 中不可以 “给同一个变量赋不同的值”。(之所以打双引号是因为 Lingo 中的都是方程,用变量赋值来说,在数学上不准确)

错误实例:

c = 1;
c = 2;

Lingo 会提示异常,c 的结果也不对:image-20200716162419117

image-20200717165642076

没有被赋初始值的变量,可能默认不是 0,亦有可能是 1.234568。你可以手动覆盖,问题不大。出现这种情况可能是因为内部实现使用了不同的算法。

image-20200716162640578

lingo也可以用来解普通方程

image-20200716150043115

lingo 用于解线性规划

如果是求线性规划问题,目标值会在 Objective value 属性中给出image-20200716145710628

  1. 一个线性规划中只含有一个目标函数。(两个以上的多目标线性规划,Lingo无法直接解) 如果建模同学给了我们多个目标函数,直接告诉他,没办法用 Lingo 求解,需要将多目标线性规划转换成 一个目标,这其实是有方法的。

    Lingo不能直接求解目标规划问题,但可以通过逐级求解线性规划的方法,求得目标规划问题的解

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

  3. !我是注释; 但是 Lingo17 注释遇到分号就会终止注释语句,这一点一定要留意 : 不要在 Lingo 的注释语句中 写 matlab 矩阵格式 的矩阵!

    以下代码直接报错

    x^2 + y^2 + 2*x = 103;
    !sdfdsfds;
    2*x + y = 12; 
    y > 5;![2, 2; 2 3];
    

    image-20200716153006216

    不写 matlab 语法中的矩阵即可image-20200716153049489

  4. 线性规划和非线性规划的本质区别是目标函数是否线性,其余一致,故不需要区分。但值得注意的是,非线性规划的求解十分困难,基本得不到全局最优解(可以得到 “满意解” )建议将非线性问题转化为线性问题来求解。

  5. 如果一个线性代数问题有多个解,则 Lingo 只会给其中的一种。

矩阵工厂

矩阵工厂就是集合的意思, 用来生产一维矩阵

使用 A(i) 拿到一维矩阵 A 的 第 i 个元素。

sets:
	factory/1..6/:a,b;
	plant/1..3/:x,y;
endsets
  1. factory 与 plant 都是矩阵工厂,但是是两家不同的工厂。

  2. factory 工厂后面的 /1…6/ 说明它专门生产 1*6 矩阵

    factory 工厂最后面出现的 a 和 b,都是 1*6 的矩阵

  3. plant 工厂后面的 /1…3/ 表示 它专门生产 1*3 矩阵

  4. plang、factory 工厂的名称随便起,无所谓。矩阵变量名也是如此

  5. 本质上只定义了四个行矩阵的大小,矩阵工厂只是中介。

  6. 生产完矩阵后,工厂和矩阵之间将脱开联系。

  7. Lingo 不是一行行地读代码的。所以我们使用 sets:endsets 表示矩阵工厂生产流程的起止。

矩阵的赋值

data:enddata 代码块一定要写在 sets:endsets 之后

  1. 不是所有矩阵都要被赋值,有些矩阵正是我们要求解的变量(如 解向量 x)。

  2. Lingo 矩阵赋值时,你就老实写数字,不要写 一个算式,不要打算让 Lingo 帮你先求解再给矩阵赋值:

  3. image-20200716164320613

    image-20200716164345283

for 循环

当一个数学式子需要手写好几个代码行的时候就可以使用for循环代替

image-20200716165213984

image-20200716165031272

这个式子,手写需要 5 行。

使用 for 循环表示如下:

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

data:
	a = 1 2 3 4 5;
enddata

max S;

@for( col_1(i): a(i)*x(i) = s);
!for( col_1 : a*x = s) 这样也行;
  1. for 循环,执行整行语句,因为 S = ai * xi , i = 1, 2, …, 5 相当于 5 个约束条件
  2. for 循环内部,先写工厂,以告诉 for 循环几次,之后再上接约束条件。
  3. for 循环中的 i 可以替换成其他变量,随意。
  4. 这个 for 循环中 i 甚至可以省略,这是因为不会造成歧义。这是特殊情况。二维工厂出现后必须要带 i。

sum

image-20200716170318014

暴力Lingo:image-20200716170346167

sum Lingo:image-20200716170403900

for 与 sum 出现的标志

  1. 约束条件后面有 i = 1 , 2 , . . . , n i = 1, 2, ...,n i=1,2,...,n ,一定在最外层 套上 for。
  2. 约束条件前面是 ∑ i = 1 n X   i   \sum_{i=1}^{n}X~i~ i=1nX i  一定要在外层 加上 sum。

工厂合并

工厂合并 : 生产二维矩阵

既然是合并,那显然,首先必须要有两个生产一维矩阵的工厂

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

Matrix 是生产 6*8 二维矩阵的工厂。

二维工厂也可以用于表示 for 循环。例题中会体现

二维工厂的赋值

data:
	Matrix = 1 2 3 4 ...balabala... 48; !一共需要64个元素;
enddata

例题

image-20200716174309569

model:

	sets:
		row/1..6/:ro, a;
		col/1..8/:co, d;
		Matrix(row, col):x, c;
	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( row(i): @sum( col(j):c(i,j)*x(i,j) ) )完全等价于下式;          
	min = @sum( Matrix(i,j) : c(i,j)*x(i,j) );
	
	!约束条件;       
	@for( row(i) : @sum( col(j) : x(i,j) ) <= a(i) );
	@for( col(j) : @sum( row(i) : x(i,j) ) = d(j) );

end

结果:image-20200716180822828

参考视频

  • 31
    点赞
  • 163
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值