lingo大规模规划求解首先,让我们先看看一个非常简单的规划例子在LINGO软件中实现过程:目标函数:𝑦(𝑚𝑖𝑛)=2∗𝑥1+𝑥2−3∗𝑥3+5约束条件:{𝑥1+𝑥2−3∗𝑥3≤10𝑥1−2∗𝑥2≥5𝑥1,𝑥2,𝑥3∈𝑁求解上面目标函数的最小值,我们在lingo中可编写如下代码:model:MIN=2*X1+X2-3*X3+5;X1+X2-3*X3=10;X1-2*X2=5@GIN(X1);!整数约束;@GIN(X2);@GIN(X3);END可以看出,LINGO语言和数学专业语言很接近,很容易表示约束条件和目标函数。可是对于规模很大的约束条件,难道我们也必须这样一条一条的输入吗,显然这样做是一件非常困难和繁琐的事,lingo语言又是如何表示约束条件规模巨大的规划问题呢,带着这样的疑问,让我们一步一步得看下面的内容:一、集合域在数学中集合的定义如下:集合:具有某种相同属性的对象放在一起,就形成了一个集合,集合中的每一个对象称作该集合的元素。在大规模的优化问题中,集合是必然存在的,比如在平板车建模中,各种规格集装箱就可以看成一个集合,在货物配送问题中154个城市可以看成一个集合。在lingo语言中,将某些对象看成一个集合便可以很方便地对集合中的每一个元素进行统一处理。集合域必须在模型的约束引用集合之前定义。集合域用关键字“sets”开始,“endsets”结束。集合分类:基本集合定义统一语法格式:setname[/member-list/][:attribute-list];集合名/对象名1对象名2…对象名n/:对象属性;集合定义的几种方法:setsrow/1..20/:d1,d2,…dn;!集合名/对象名/:对象属性;endsets派生集合定义方法:setsrow/1..20/;col/1..100/;page/1..50/;link(row.col):k1,k2…kn;trd/(row.col.page):t1,t2,…tn;endsetsK1可以表示某个省的某个城市的人口。t1可以表示某个省的某个城市某个人的收入。二、数据域:数据域是优化问题中已知得对象的属性值,例如:人的身高,体重;车辆的载重,行驶速度。数据域以关键字“data”开头,“enddata”结束。数据域可以出现在模型中的任何地方。data:d1=…;k1=…;t1=…;enddata数据域的未知数值有时只想为一个集的部分成员的某个属性指定值,而让其余成员的该属性保持未知,以便让LINGO去求出它们的最优值。在数据声明中输入两个相连的逗号表示该位置对应的集成员的属性值未知。两个逗号间可以有空格。例3.8sets:years/1..5/:capacity;endsetsdata:capacity=,34,20,,;enddata属性capacity的第2个和第3个值分别为34和20,其余的未知。实时数据处理在某些情况,对于模型中的某些数据并不是定值。譬如模型中有一个通货膨胀率的参数,我们想在2%至6%范围内,对不同的值求解模型,来观察模型的结果对通货膨胀的依赖有多么敏感。我们把这种情况称为实时数据处理(whatifanalysis)。LINGO有一个特征可方便地做到这件事。在本该放数的地方输入一个问号(?)。data:interest_rate,inflation_rate=.085?;enddata每一次求解模型时,LINGO都会提示为参数inflation_rate输入一个值。在WINDOWS操作系统下,将会接收到一个类似下面的对话框:直接输入一个值再点击OK按钮,LINGO就会把输入的值指定给inflation_rate,然后继续求解模型。除了参数之外,也可以实时输入集的属性值,但不允许实时输入集成员名。三、初始域初始域是专门为初始化决策变量而定义的一块区域。初始部分是LINGO提供的另一个可选部分。在初始部分中,可以输入初始声明(initializationstatement),和数据部分中的数据声明相同。对实际问题的建模时,初始部分并不起到描述模型的作用,在初始部分输入的值仅被LINGO求解器当作初始点来用,并且仅仅对非线性模型有用。和数据部分指定变量的值不同,LINGO求解器可以自由改变初始部分初始化的变量的值。一个初始部分以“init:”开始,以“endinit”结束。初始部分的初始声明规则和数据部分的数据声明规则相同。也就是说,我们可以在声明的左边同时初始化多个集属性,可以把集属性初始化为一个值,可以用问号实现实时数据处理,还可以用逗号指定未知数值。init:X,Y=0,.1;endinitY=@log(X);X^2+Y^2=1;好的初始点会减少模型的求解时间。四、集合循环函数统一语法格式:@function(setname[(set_index_list)[|condition]]:expression_list);其中:function是集合函数名,是FOR,MAX,MIN,PROD,SUM五种之一;setname是集合名;set_index_list是集合索引列表(不需使用索引时可以省略);condition是逻辑表达式描述的过虑条件(通常含有索引,无条件时可省略);expression_list是一个表达式(对@FOR函数,可以是一组表达式)。五个集合函数名的含义如下:@FOR(集合元素循环函数):对集合setname的每个元素独立地生成表达式,表达式由expression_list描述(通常是优化问题的约束)。@MAX(集合属性的最大值函数):返回集合setname上的表达式的最大值。@MIN(集合属性的最小值函数):返回集合setname上的表达式的最小值。@PROD(集合属性的乘积函数):返回集合setname上的表达式的积。@SUM(集合属性的求和函数):返回集合setname上的表达式的和。对应数学表达式与LINGO命令:数学表达式lingo命令∑𝐱𝐢𝐧𝐢=𝟏(一维数组和)@sum(row(i):x(i));∑∑𝐱𝐢𝐣𝐧𝐣=𝟏𝐦𝐢=𝟏(二维维数组和)@sum(links(i,j):x(i,j));∑∑𝐱𝐢𝐣𝐧𝐣=𝟏𝐦𝐢=𝟏𝐘𝐢𝐣(矩阵点乘和)@sum(links(i,j):x(i,j)*Y(i,j));∏𝐱𝐢𝐧𝐢=𝟏(求数组的积)@prod(row(i):x(i));∑𝐱𝐢𝐣𝐧𝐢=𝟏≤∑𝐲𝐢𝐣𝐧𝐢=𝟏(𝐣=𝟏,𝟐,…,𝐦)(比较m个一维数组的和)@for(col(j):@sum(row(i):x(i))=@sum(row(i):y(i)));五、变量定界函数变量定界函数对变量的取值范围附加限制,共有以下四种函数:@BND(L,X,U):限制L〈=X〈=U。注意LINGO中命令SLB,SUB类似函数@SLB和@SUM.@BIN(X):即限制X为0或1。注意LINGO中这个函数的名字却不是@INT(X).@FREE(X):取消对X的符号限制(即可取负数、0后正数)。@GIN(X):限制X为整数。数学表达式LINGO命令𝐱𝐢(𝐱𝐢∈[𝟎,𝟐𝟎];𝐢=𝟏,𝟐,…,𝐧)@for(row(i):@bnd(0,x(i),20));𝐱𝐢(𝐱𝐢∈{𝟎,𝟏};𝐢=𝟏,𝟐,…,𝐧)@for(row(i):@BIN(x(i)));𝐱𝐢(𝐱𝐢∈𝐑;𝐢=𝟏,𝟐,…,𝐧)@for(row(i):@FREE(x(i)));𝐱𝐢(𝐱𝐢∈𝐍;𝐢=𝟏,𝟐,…,𝐧)@for(row(i):@gin(x(i)));六、条件控制器用于集合循环函数中,循环变量的范围控制。有两类控制方法:1是直接控制集合中对象的范围,2是通过控制对象属性值的范围来间接控制对象的范围。数学表达式lingo命令∑𝐱𝐢𝐧𝐢=𝟏(i=1,2,…,n-3)@sum(row(i)|i#LE#n-3:x(i));∑∑𝐱𝐢𝐣𝐧𝐣=𝟏𝐦𝐢=𝟏(j=5)@sum(links(i,j)|j#GE#5:x(i,j));∑∑𝐱𝐢𝐣𝐧𝐣=𝟏𝐦𝐢=𝟏𝐘𝐢𝐣(𝐱𝐢𝐣0)@sum(links(i,j)|x(i,j)#NE#0:x(i,j)*Y(i,j));∏𝐱𝐢𝐧𝐢=𝟏(𝐱𝐢0)@prod(row(i)|x(i)#NE#0:x(i));七、基本的数学函数在LINGO中建立优化模型时引用大量的内部函数这些函数以@、。号打头.LINGO中包括相当丰富的数学函数,这些函数的用法非常简单,我们直接在下一一列出@ABS(X);绝对值函数,返回X的绝对值@COS(X);余弦函数,返回X的余弦值(X的单位是弧度)@EXP(X)指数函数,返回xe的值(其中e为自然对数值的底,即2.718281„)@FLOOR(X);取整函数,返回X的整数部分(向最靠近0的方向取整).@LGM(X):返回X的伽马(Gamma)函数的自然对数值(当X为整数时LGM(X)=LOG(X-1)!;当X不为整数时,采用线性插值得到结果)@LOG(X):自然对数函数,返回自然对数值@MOD(X,Y):模函数,返回X对Y的取模的结果,即X除以Y的余数,这里X余Y应是整数@POW(X,Y):指数函数,返回yX的值.@SIGN(X):符号函数,返回X的符号值(X0是返回-1,X=0时返回+1)@SIN(X):正弦函数,返回X的正弦值(X的单位是弧度)95@SMAX(list)::最大值函数,返回一列数(list)的:最大值@SMIN.(list)::最小值函数,返回一列数(list)的:最小值@SQR(X):平方函数,返回X的平方即(X*X)的值@SQRT(X):平方根函数,返回X的平方根的值@TAN(X);正切函数,返回X的正切值(X的单位是弧度)。八、lingo中其他常用命令@WRAP(I,N)当I为于区间[I,N]内时直接返回I;一般地,返回J=I-K*N,其中J位于区间[1,N],K为函数。可见这个函数相当于数学上用I对N取模函数的值+1,即@WRAP(I,N)=@MOD(I,N)+1.此函数对N〈1无定义。@SIZE(set_name)返回数据集set_name中包含元素的个数。@IF(logical_condition,true_result,false_result)当逻辑表达式logical_condition的结果为真时,返回true_result,否则返回false_result。例如@if(x#LT#100,20,15)语句,当X〈100时,返回20,否则返回15。@WARN(„text‟,logical_condition)如果逻辑表达式“logical_condition”的结果为真,显示'text'信息.@USER(user_determined_arguments)该函数是允许用户自己编写的函数(dl或0bj文件),该用户函数可能当用C或FORTRAN等其他语言编写并编译,返回值为用户函数计算的结果.从编程角度来看,@USER函数包含两个参数:第一个用于指定参数个数,第二个用于指定参数向量:而在LINGO中调用·USER时则直接指定对应的参数“user_determined_”(类似于C语言中的main(argc,argv)的编程和运行方式).更多细节请参考LINGO使用手册.九、文件读写1.复制和粘贴功能对于数据量不是很大的集合而言,复制粘贴是最快捷最简单的方法,和其他软件操作一样,LINGO软件,支持从网页,文本文档,电子表格中复制数据。同样对其LINGO运行的结果,我们可以将求解报告窗口中的结果复制到其他地方。2.@OLE函数,它可以从Excel中读取数据或将结果写入到Excel中。输入数据:统一语法格式:variable_list=@OLE('spreadsheet-file',range_name_list);其中spread