1、lingo 大规模规划求解首先,让我们先看看一个非常简单的规划例子在 LINGO 软件中实现过程:目标函数: ()=21+233+5约束条件:1+2331012251,2,3 求解上面目标函数的最小值,我们在 lingo 中可编写如下代码:model:MIN=2*X1+X2-3*X3+5;X1+X2-3*X3=5GIN(X1);!整数约束;GIN(X2);GIN(X3);END可以看出,LINGO 语言和数学专业语言很接近,很容易表示约束条件和目标函数。可是对于规模很大的约束条件,难道我们也必须这样一条一条的输入吗,显然这样做是一件非常困难和繁琐的事,lingo 语言又是如何表示约束条件规模巨
2、大的规划问题呢,带着这样的疑问,让我们一步一步得看下面的内容:一、集合域在数学中集合的定义如下:集合:具有某种相同属性的对象放在一起,就形成了一个集合,集合中的每一个对象称作该集合的元素。在大规模的优化问题中,集合是必然存在的,比如在平板车建模中,各种规格集装箱就可以看成一个集合,在货物配送问题中 154 个城市可以看成一个集合。在 lingo 语言中,将某些对象看成一个集合便可以很方便地对集合中的每一个元素进行统一处理。集合域必须在模型的约束引用集合之前定义。集合域用关键字“sets”开始, “endsets”结束。集合分类:基本集合定义统一语法格式:setname/member-list/
3、:attribute-list; 集合名/对象名 1 对象名 2 对象名 n/:对象属性;集合定义的几种方法:setsrow/120/:d1,d2,dn; !集合名/对象名/:对象属性;end sets派生集合定义方法:setsrow/120/;col/1100/;page/150/;link(row.col):k1,k2kn;trd/(row.col.page):t1,t2,tn;end setsK1可以表示某个省的某个城市的人口。t1可以表示某个省的某个城市某个人的收入。二、数据域:数据域是优化问题中已知得对象的属性值,例如:人的身高,体重;车辆的载重,行驶速度。数据域以关键字“data”
4、开头,“enddata”结束。数据域可以出现在模型中的任何地方。data:d1=;k1=;t1=;enddata数据域的未知数值有时只想为一个集的部分成员的某个属性指定值,而让其余成员的该属性保持未知,以便让 LINGO 去求出它们的最优值。在数据声明中输入两个相连的逗号表示该位置对应的集成员的属性值未知。两个逗号间可以有空格。例 3.8sets:years/15/: capacity;endsetsdata:capacity = ,34,20,;enddata属性 capacity 的第 2 个和第 3 个值分别为 34 和 20,其余的未知。实时数据处理在某些情况,对于模型中的某些数据并不
5、是定值。譬如模型中有一个通货膨胀率的参数,我们想在 2%至 6%范围内,对不同的值求解模型,来观察模型的结果对通货膨胀的依赖有多么敏感。我们把这种情况称为实时数据处理(what if analysis) 。LINGO 有一个特征可方便地做到这件事。 在本该放数的地方输入一个问号(?) 。data:interest_rate,inflation_rate = .085 ?;enddata每一次求解模型时,LINGO 都会提示为参数 inflation_rate 输入一个值。在WINDOWS 操作系统下,将会接收到一个类似下面的对话框:直接输入一个值再点击 OK 按钮,LINGO 就会把输入的值指
6、定给 inflation_rate,然后继续求解模型。除了参数之外,也可以实时输入集的属性值,但不允许实时输入集成员名。三、初始域初始域是专门为初始化决策变量而定义的一块区域。初始部分是 LINGO 提供的另一个可选部分。在初始部分中,可以输入初始声明(initialization statement) ,和数据部分中的数据声明相同。对实际问题的建模时,初始部分并不起到描述模型的作用,在初始部分输入的值仅被 LINGO求解器当作初始点来用,并且仅仅对非线性模型有用。和数据部分指定变量的值不同,LINGO 求解器可以自由改变初始部分初始化的变量的值。一个初始部分以“init:”开始,以“endi
7、nit”结束。初始部分的初始声明规则和数据部分的数据声明规则相同。也就是说,我们可以在声明的左边同时初始化多个集属性,可以把集属性初始化为一个值,可以用问号实现实时数据处理,还可以用逗号指定未知数值。init:X, Y = 0, .1;endinitY=log(X);X2+Y2=5)=1=1 sum(links(i,j)|j#GE#5:x(i,j);(=1=10) prod(row(i)|x(i)#NE#0:x(i);七、基本的数学函数 在 LINGO 中建立优化模型时引用大量的内部函数这些函数以“、 。号打头. LINGO 中包括相当丰富的数学函数, 这些函数的用法非常简单 ,我们直接在下一
8、一列出 ABS(X);绝对值函数,返回 X 的绝对值 COS(X);余弦函数,返回 X 的余弦值(X 的单位是弧度) EXP(X)指数函数 ,返回 x e 的值(其中 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 的余数,这里
9、X 余 Y 应是整数 POW(X,Y):指数函数 ,返回 yX 的值. SIGN(X):符号函数,返回 X 的符号值(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) 当
10、I 为于区间I,N内时直接返回 I;一般地,返回 J=I-K*N,其中 J 位于区间1,N,K 为函数。可见这个函数相当于数学上用 I 对 N 取模函数的值 +1,即WRAP(I,N)=MOD(I,N)+1.此函数对 N1 无定义。 SIZE(set_name) 返回数据集 set_name 中包含元素的个数。IF (logical _condition, true _result, false _result) 当逻辑表达式 logical _condition 的结果为真时,返回 true _result,否则返回 false _result。例如if(x # LT # 100,20,15
11、)语句,当 X100 时,返回 20,否则返回 15。 WARN (text, logical _condition) 如果逻辑表达式“logical _condition”的结果为真,显示 text信息. USER (user _determined _arguments) 该函数是允许用户自己编写的函数( dl 或 0bj 文件),该用户函数可能当用 C 或FORTRAN 等其他语言编写并编译,返回值为用户函数计算的结果.从编程角度来看,USER 函数包含两个参数:第一个用于指定参数个数,第二个用于指定参数向量:而在 LINGO 中调用USER 时则直接指定对应的参数 “user _det
12、ermined_”(类似于 C 语言中的 main ( argc , argv ) 的编程和运行方式).更多细节请参考 LINGO 使用手册. 九、文件读写1. 复制和粘贴功能对于数据量不是很大的集合而言,复制粘贴是最快捷最简单的方法,和其他软件操作一样,LINGO 软件,支持从网页,文本文档,电子表格中复制数据。同样对其 LINGO 运行的结果,我们可以将求解报告窗口中的结果复制到其他地方。2. OLE 函数,它可以从 Excel 中读取数据或将结果写入到 Excel 中。输入数据:统一语法格式:variable_list=OLE(spreadsheet-file,range_name_list);其中 spreadsheet_file 是电子表格文件名称, 应当包括扩展名(如*.xls 等),还可以包含完整的路径名,只要字符书不超过 64 均可; rang_name_list 是指文件中包含数据的单元范围(单元范围的格式与 Excel 中工作表的单元范围的格式一样) 。variable_list 是一些要初始化的属性或属性列表。例如:PRICE=OLE(C:XLSMYDATA.XLS,MYPRICES);输出数据:统一语法格式:OLE(spreadsheet-file,range_name_list)=variable_list;