lingo是专门求解优化的软件,有目标函数,有约束条件 ,可以解决线性优化问题,非线性优化问题,线性方程组,非线性方程组
对于换行可以直接敲回车;?
开头用!,结尾用分号 用于注释,可用于多行注释
lingo不区分大小写
lingo crtl+滚轮 调整代码的字体
lingo中的乘号不能省略
在lingo中加空格不影响
lingo中每一句要用分号结尾
小规模问题:不使用集合语言(变量小于20个等)
大规模问题:使用集合语言
max,min用于定义目标函数
@bin(x) 表示x为0或1
@gin(x)表示x为整数
@free(x)表示x为任意实数
@bnd(L,x,U)表示x为[L,U]之间的实数
lingo中默认变量都是非负数
min=2*x1+3*x2;
x1+x2>=350;
x1>=100;
2*x1+x2<=600;
!x1 -100,100;
@free(x1); !去掉变量的限制
@bnd(-100,x1,100);
对于大规模问题要用集合
!写一个集合可以运行的看一下报不报错;
!定义集合;
sets:
L/1..6/:a,b,d;!单下标a,b,d的下标都是1..6;
YY/1,2/: e,x ,y;!单下标e,x的下标都是1..2;
H(L,YY):C;!双下标,C是由L,Y组成的双下标;
endsets
!数据集合;
data:
a=6, 2, 6 , 4 ,2 ,9 ;
b=4 ,9 ,5 ,3 ,5 ,8 ;
d=1 ,2, 1, 9, 4, 3 ;
e=10 20;
x=1 2;
y=1 10;
enddata
!目标函数;
min =@sum(YY(j):@sum(L(i):
C(i,j) * @sqrt( (x(j)-a(i))^2 + (y(j)-b(i))^2 ) ) ) ;
!j从1..2,在YY集合里就写YY(j);
!@sum(YY(j):表达式a(j)):表示求和符号
!约束;
!for 循环;
!对于所有的i来说;
@for(L(i):
@sum(YY(j):c(i,j))
=d(i) );
@for(YY(j):
@sum(L(i):c(i,j))
<=e(j) );
?求解非线性问题就要设置
!求解非线性问题;
max=@sin(r)/r+1;
r=@sqrt((x-50)^2+(y-50)^2)+2.71828;
@bnd(0,x,100);
@bnd(0,y,100);
!在solver中选择全局求解器,点击全局求解;
求解方程组
!求解方程组;
10*(x+y)=750;
20*(x-y)=350;
目标函数是0就是没有的意思
*.lng可以用记事本打开,*.lg4只能用lingo打开
求解:
点击靶子求解,或者ctrl+U求解,点solver
!求解非线性方程;
x^2+y^2=2;
2*x^2+x+y^2+y=4;
?只能找到一个解,可以加条件进行变换解的范围;
x^2+y^2=5^2;
y>=2;
x>=2;
@gin(x);
@gin(y);
目标函数的Z不要输入;
lingo中没有严格大于或严格小于,只有>=,=,=<三种,输入>相当于输入>=,它会自己改;
要属于严格小于,可以减去一个非常非常小的数
不使用集合语言
容易检查
max=4*x1+3*x2;
2*x1+x2<10;
x1+x2<=8;
x<=7;
@gin(x1);
@gin(x2);
?条件的顺序没有任何的关系(顺序随便)
!x属于(-5,5)的整数;
@free(x);
@bnd(-5,x,5);
@gin(x);
?x只能取-1和1
!x属于{-1,1},x只能取-1和1;
@bin((x+1)/2);
大规模问题
多个约束条件用for,多个求和使用sum
s/1..2/:c,x;? 定义一个S集合,c,x变量依赖于s这个集合
? ?
?@sum()---------表示求和符号
? ? ? ? ? ? ? ? ? ? ? ?S(j)-----------表示j在S里面取值,? ? S={1,2}
?? :-------表示对于什么求和
@????????sum(????????s(j):????????c(j)*x(j)????????)
x1,x2...x200均为整数<------------> xi均为整数,for i属于S
@for(????????s(i)????????:????????@????????gin(???????? x(i)???????? ) ????????)
model:开始? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? end结束? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?可有可无?
c=1 2 3;中间用,? 空格? 或回车都可以
段 -------------------? 冒号开始? ?结束不用符号
lingo程序主要分为:1.集合段? ?2.数据段? ?3.模型段? ?4.其他:初始化段,计算段,子模型段
注:
各段之间没有顺序关系
数据段不能使用分式;
数据段可使用问号“?”来实现实时输入;
数据段可从硬盘文件中读取? A=@file(data.txt);
计算段不能含有变量,必须是已知数据的运算;
title:标题;?
@text(data.txt)=@table(x); ? !把x作为表格输出出来,输出到文本文件里,空的就输出到屏幕上;
model:
title:指派问题;
sets:
s/1..5/:;
link(S,S):c,x;
endsets
data:
c=3 8 2 10 3
8 7 2 9 7
6 4 2 7 5
8 4 2 3 5
9 10 6 9 10;
@text(data.txt)=@table(x); !把x作为表格输出出来,输出到文本文件里,空的就输出到屏幕上;
enddata
min=@sum(link(i,j):c(i,j)*x(i,j));!两个求和符号;
@for(S(i):@sum(S(j):x(i,j))=1);
@for(S(j):@sum(S(i):x(i,j))=1);
@for(link(i,j):@bin( x(i,j) ) );
link(i,j)表示对集合里的所有下标求和可以省略掉 变成?link?
逻辑运算
#gt#: great than ????????????????????????(严格大于)
#ge#:great than or equal??????????(大于或等于)
#lt# less than? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(严格小于)
#eq#:equal? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (等于)
#ne#:not equal? ? ? ? ? ? ? ? ? ? ? ? ? ? (不等于)
#not#
#and#
#or#
?对指标进行限制
@sum(? s(i)???????? | ????????i #ge#5 :????????x(i)? )? ? !不能使用>这些符号
一些函数
@abs(x)? ? ?@sin(x)? ? @exp(x)? ?@log(x)? ? @lgm(x)? @floor(x)
? @cos(x)? ? @tan(x)? ? @sing(x)? ?@mod(x,y)? ?@smax(x1,x2,x3...xn)
@smin(x1,x2,x3...xn)
注意:max 对于目标函数的? ? ?@smax----对于一个系列? ? ? ? ? @max-----对于集合
集合函数
@size? 这个集合有几个下标,几个元素
@wrap?
@rand? 随机数
@qrand?
?x^2+y^2=1; @atan(X)-y=0;
利用最小二乘法,将上述的非线性方程转换为非线性规划问题:
min? ? ? (x^2+y^2-1)^2+(arctan-y)^2 ;
lingo放到TXT中
~? ?txt文本中表示结束
3 ?8 ?2 10 ?3 8 ?7 ?2 ?9 ?7 6 ?4 ?2 ?7 ?5 8 ?4 ?2 ?3 ?5 9 ?10 6 ?9 ?10~
1 2? 3~
??c=@file('新建文本文档.txt');
? d=@file('新建文本文档.txt');!读完c的数据接着读下面的数据给d
? d=1 2 3;
将解的结果放到记事本里
@text('result.txt')=@write('the result is :',@newline(1))? !结果是:换一行开始;
@text('result.txt')=@write(? link(i,j) |? x(i,j)#gt#0:? ? ?' x('???,?i,???','? ,j,??')=1'??,@newline(1)????);
@text('result.txt')=@table(x);
随机数
!@qrand(seed)可生成一系列的随机数,但只能用在数据段;
!seed随机种子;
model:
data:
M=4;N=2;seed=1234567;
enddata
sets:
rows/1..M/;
cols/1..N/;
table(rows,cols):x,y;
endsets
data:
x=@qrand(seed);
@text()=@table(x);
@text()=@table(y);!放最后面一行会报错;
enddata
@for(table(i,j):y=20*x);
!@rand(seed)可生成一个随机数,但可以用在数据段和计算段;
!seed随机种子;
model:
data:
M=4;N=2;seed=1234567;
enddata
sets:
rows/1..M/;
cols/1..N/;
table(rows,cols):x,y;
endsets
Calc:
@for(table(i,j):x(i,j)=@rand(seed);
seed=x(i,j));
endCalc
data:
@text()=@table(x);
@text()=@table(y);!放最后面一行会报错;
enddata
!模型段;
@for(table(i,j):y=20*x);
对于这个随机种子哔哩哔哩有个up主讲的很好
https://www.bilibili.com/video/BV177411w7RJfrom=search&seid=8077816425857132924&spm_id_from=333.337.0.0 https://www.bilibili.com/video/BV177411w7RJ?from=search&seid=8077816425857132924&spm_id_from=333.337.0.0
|