运筹学lindo教程特别版
发布时间:2024-11-06
发布时间:2024-11-06
目录
第1章 引言
第2章 LINDO软件的基本使用方法
2.1 LINDO入门
2.1.1 LINDO软件简介
LINDO是英文Linear Interactive and Discrete Optimizer字母的缩写形式,即”交互式的线性和离散优化求解器”。LINDO软件和第3章即将介绍的LINGO软件包是美国LINDO系统公司开发的一套专门用于求解最优化问题的软件(如图2-1所示)。LINDO用于求解线性规划问题,其功能比较强,计算效果比较好。此外,LINDO软件使用起来非常方便,很容易学会。即使对优化方面的专业知识了解不多的人,也能够方便地建模和输入,有效地求解和分析实际中遇到的大规模化的问题,并通常能够快速得到复杂优化问题的高质量的解。
图2-1 美国LINDO系统公司开发的一套专门用于求解最优化问题的软件
第一次运行刚安装的LINDO软件时,系统会弹出一个对话框,要求你输入Password(密码)。如果是正版软件,则在密码框中输入LINDO公司提供的密码,然后按“OK”按钮即可。否则,只能选择演示版(Demo Version),按下”Demo Version”按钮即可。
2.1.2 编写一个简单的LINDO程序
在Windows操作系统下安装好LINDO软件后,双击桌面上LINDO图标 (或在Windows”开始”菜单的“程序”中选择运行LINDO软件(如图2-2所示),可以启动LINDO软件,屏幕上首先显示(如图2-3所示)所示的LINDO的初始界面。从界面上可以看到LINDO的最大的Constraints(约束)个数为50,最大的Variables(变量)个数为100,最大的Nonzeros个数为16000。
图2-2 启动LINDO程序
图2-3 启动LINDO的初始界面
下面通过一个非常简单的例子,说明如何编写、运行一个LINDO程序的完整过程。点击图2-3中的“OK”,出现如图2-4所示的工作界面。
图2-4 启动LINDO的工作界面
这就是LINDO的初始用户界面。目前光标所在子窗口称为模型窗口,是用来供用户输入LINDO程序的。目前这个模型窗口标有“<untitled>”字样,表示用户还没有为这个程序命名,因此,LINDO采用了自动生成的名字“<untitled>”,将来用户在保存程序时可以对它重新命名。
【例2.1】 生产规划的优化问题
maxZ 200x1 500x2
1.5x1 5x2 40 s.t. 2x1 4x2 40 x1 0,x2 0
我们可以直接在<untitled>这个新的、空白的模型窗口中输入这个问题(如图2-4所示)。
图2-4 例2.1的模型输入
我们看到这段程序有以下特点:
1、这个LINDO程序以“max”开始,表示目标是最大化问题(容易想到,对最小化问题自然该用”min”开始),后面直接写出目标函数的表达式。注意:LINDO不区分大小写字符(实际上任何小写字符将被转换成大写字符);变量和系数间不用乘号“*”。
2、约束的表达式前用st(说明也可写成s.t.或subject to)。程序以“end”结束。(请注意:“end”在这里也可省略)
3、输入的LINDO模型中用右括号“) ”结尾的“ first)”和“ second)”是行名(对应约束,就是约束名);我们也可以分别输入“2)”和“3)”等其它行名;请注意:“ first)”和“ second)”也可以省略,省略时LINDO将会按照输入行的顺序自动生成用数字表示的行名(即行号)。如本例中若输入时省略行名时,系统对约束默认的行名分别是“2)”和“3)”,并对目标函数所在的行自动生成行名“1)”。
4、我们输入上面的模型时,故意写的歪七扭八,是为了说明在LINDO中,模型书写起来是相当灵活的,由于LINDO中已假设所有的变量都是非负的,所以非负约束(4)即(x1≥0,x2≥0)不必再输入到计算机中;约束条件中的“ ”及“ ”可分别用“〈”和“〉”代替;输入的多余的空格和回车也会被忽略;一个约束还可以分成两行甚至多行写,等等。
5、模型中的感叹号“!”后面的文字将被认为是说明语句(注释语句),不参与模型的建立,主要是为了增强程序的可读性。注意此处书写时不能换行。
现在我们就可以用LINDO软件来求解这个模型。用鼠标单击LINDO软件工具栏中的图标,或从菜单中选择“Slove(Ctrl+S)”命令(即LINDO的主菜单“Solve”求解中的“Slove(求解)”命令,快捷键是Ctrl+S(以后我们约定都这样表示),见图2-5。则LINDO开始编译这个模型,编译没有错误马上开始求解,求解时会显示如图2-6所示的LINDO求解器运行状态窗口(LINDO SOLVE STATUS),其中显示的相应信息的含义见表2-1。注意,LINDO求解线性规划的过程默认采用单纯形法,一般是首先寻求一个可行解,在有可行解的情况下再寻求最优解。用LINDO求解一个LP问题会得到如下的几种结果:可行或不可行;可行又可分为:有最优解和解无界两种情况。因此,图2-5中当前状态可显示为:Optimal (最优解),Feasible(可行解),Infeasible(不可行解),Unbourded(解无界)四种状态之一。
图2-5 例2.1的模型求解
图2-6 LINDO求解器运行状态窗口(LINDO solver Status)
由于这个例子中LP模型的规模太小,我们可能还没有来得及看清图2-6的界面,LINDO就解出了最优解,并马上弹出如图2-7的对话框。这个对话框询问你是否需要作灵敏性分析“DO RANGE(SENSITIVITY )ANALYSIS?”。我们现在先选择“否(NO)”按钮,这个窗口就关闭。然后,我们再把图2-4状态窗口也关闭(按下图2-6的“Close”按钮即可)。
图2-7 灵敏性分析对话框
现在这个模型就解完了。那么最优解在哪里呢?如果你在屏幕上没有看到求解的结果,那么请你用鼠标选择LINDO的主菜单“Window(窗口)”,就可以查看该窗口的内容(如图2-8所示)。
图2-8 LINDO的求解结果报告窗口
这些输出结果表示的意思如下:
1、“LP OPTINUM FOUND AT STAP 0”表示单纯形法在0次迭代后得到的最优解。
2、“OBJECTIVE FUNCTION VALUE 1)4500.000”表示最优目标值。(注意:在LINDO中目标函数所在行总是被认为是第1行,这里的“1)”就是这个含义。
3、“VALUE”给出最优解中各变量(VARIABLE)的值:x1=10,x2=5。
4、“REDUCE COST”给出了最优的单纯形表目标函数行第1行中变量对应的系数(即各个变量的检验数(也称判别式))。其中基变量的REDUCE COST 值一定为0;对于非基变量(注意非基变量本身取值一定为0),相应的REDUCE COST 值表示该当非基变量增加1个单位(其他非基变量保持不变)时目标函数减少的量(对MAX型问题)。本例最优解中两个变量都是基变量,所以对应的REDUCE COST 的值均为0。
5、“SLACK OR SURPLUS(松弛或剩余)”给出约束对应的松弛变量的值:第2,3行松弛变量均为0,说明对于最优解来讲,两个约束(第2,3行)均取等号,即都是紧约束。
6、“DUAL PRICES ”给出了对偶价格的值:第2,3行对偶价格分别为50.0,62.5(含义参看《运筹学》)。
7、“NO ITERATIONS =0”表示用单纯形法进行0次迭代(旋转)。
现在,我们归纳一下上面介绍的输入,求解LP问题的一般步骤如下:(1)在模型窗口中输入一个LP模型。模型以“max”或“min”开始,按线性规划问题的自然形式输入(如前面的例子所示)。如要结束一个模型的输入,只需输入“END”(也可以省略)。(2)求解模型。如果LINDO报告有编译错误,则回到上一步修改模型。(3)查看结果。
2.2LINDO的主要菜单命令
从前面的各个图形窗口中我们已经看到,LINDO软件菜单条上有六个主菜单:File(文件) Edit(编辑)
Solve(求解) Report(报告 ) Windows(窗口) Help(帮助)
File(文件)菜单包括了LINDO通过文件与外部设备交换信息的命令;Edit(编辑)菜单包括了在当前窗口下编辑文本的命令;Solve(求解)菜单包括了求解摸新年感的命令;REPORTS(报告)彩旦包括了生成解答结果报告的命令;Windows(窗口)菜单包括了窗口切换的命令;HELP(帮助)菜单包括了访问在线帮助文档的命令。
对于几乎所有的菜单命令,LINDO都提供了快捷键;对于常用的菜单命令,LINDO在工具栏提供了相应的图形按钮(参见图2-6)。工具栏是浮动式的,可以用鼠标拖到屏幕的任何地方。这些用法都是和WINDOWS下其他应用程序的标准用法类似的,所以我们不准备对所有的菜单命令进行完整和详细的介绍,而是只对前4个菜但中有一定LINDO特色的主要命令进行简单介绍。
2.2.1文件主菜单
File/New、File/open和File/view的区别
File/view 用于新建一个模型文件,File/open用于打开一个已有文件,此后可以对这个文件进行编辑、求解、保存等;而File/View只用于打开已有文件供浏览(也可以求解)使用,不能编辑。由于LINDO编辑器对文件的大小是有限制的,因此用Flie/New和File/Open打开的文件不能太大(通常不超过64000字符);而File/view不受文件大小限制,这对浏览特别大规模的文件(通常不一定是由LINDO本身的编辑器产生的)是有用的。
File/Title显示当前模型的名称(如果该模型被命名过,即模型的程序中出现过Title语句)。 File/Date显示当前日期和时间。File/Elapse Time显示本次启动LINDO以来已经运行了多长时间。
File/License输入验证LINDO的许可证密码、功能和界面如下图2-7。
说明:File/Long Output,File/Take Commands等其他子菜单的作用可参阅相应的书籍。
2.2.2编辑主菜单
该菜单下的多数命令基本上是不言自明的,与WINDOWS下的其他编辑器类似,这些命令就不具体介绍了。这里只介绍几个LINDO软件中特色命令。
Eidt/Options该命令打开一个对话框(见图2-8),用于设置LINDO系统运行的内部参数。从图中可以看出,可修改的参数分成两大类:左边一类是关于优化程序的,右边一类是关于输出格式的(Output)。先看输出格式中所包含的四个选项:Status Window(状态窗口)选项:用于控制是否简明的形式报告结果(默认设置为详细(Verbose)的形式报告结果)。 Page Length Limit(页长限制):用于控制输出时每页最多显示多少行(可以设置为任意正整数;默认设置是“None”,表示无限制。Terminal Width(终端宽度):每行的最大宽度(每行多少字符),可以设置为40-132之间的整数(默认设置为80)。关于优化程序(Optimizer)的参数又分成两类:左边一类是关于整数规划的;右边一类是一般参数。对于IP的参数设置可参阅相关书籍;对于LINDO的一般参数(General),可以如下设置:Nonzero Limit(模型中允许出现的非零系数的个数上限):这个参数对于不同版本的LINDO软件默认值不同,试用版中是2000000。Iteration Limit(求解时允许的最大迭代步数):默认值是“None”,即没有限制;有时为了防止计算时间太长,用户可以自行设置为任意一个整数。Initial Contraint Tol(初始阶段求解时约束条件允许的误差上限):即只要约束两边相差小于这个数时,就认为约束成立。计算的初始阶段这个误差可能没有必要设置过小,以免找不到可行解,所以默认值是0.00008。Final Contraint Tol(最后阶段求解时约束允许的误差上限):即只要约束两边相差小于这个数时,就认为约束成立。计算的最后阶段这个误差有必要设置的比较小,以便提高计算精度,所以默认值是0.00001。Entering Var Tol(进基变量的误差上限):即只有当变量的判别数大于这个上限时,这个变量才可能进基(相当于认为绝对值小于这个数时,判别数就是零)。默认值是0.0000005.(具体含义见相关参考书)。Pivot Size Tol(旋转时采用的误差下限:即旋转变量的绝对值不能小于该上限(相当于认为绝对值小于这个数时,旋转元就是0)。默认值是0.0000000001。(旋转元和进基变量的含义见相关参考书)。一旦参数被修改并按下“OK”按钮后,将对所有此后的运行均有效,直到退出LINDO系统或重新设置这个参数为止,而与具体的模型无关。如果将这些参数用对话框中的“Save(保存)”按钮保存下来,退出LINDO后下次启动LINDO时这些参数仍然有效。对话框中右下方的
“Default(默认)”按钮恢复LINDO系统的默认参数值。“Cancel(取消)”按钮用于废除本次参数修改,关闭这个选项窗口。“Help(帮助)”按钮用于提供本窗口的在线帮助。
Edit/paste Symbol该命令打开一个对话框,用于在模型中当前光标后面插入符号。例如:对于前面介绍的LP模型(参见例2.1),Paste Symbol打开的对话框如图2-9,可以看到可选的符号主要是三类:Reserved(保留字):LINDO系统的保留字(如一些常用的语句关键词和运算符号;Variable(变量):当前模型的决策变量;Rows(行名):约束的行号或行名。可以用鼠标双击其中某个符号,则该符号显示在图中的缓冲区(“Paste Buffer”);也可直接编辑缓冲区的内容。当单击“Paste(粘贴)”按钮时,缓冲区的内容将被插入当前模型的当前光标后。单击“Clear(清除)”按钮将清除缓冲区的内容,单击“Close(关闭)”,按钮将关闭该对话框。Edit/Choose New Fond该命令用于指定显示的字体,字型和文字的大小。对话框如图2-10所示。
2.2.3求解主菜单
Solve /Compile Modl
Solve /Compile Modl(编辑模型)命令对当前模型进行编译。如果当前模型输入有语法错误,编译时将报告错误。Solve/Pivot
Solve/Pivot(旋转)命令从当前解出发进行一次单纯形旋转(即一次迭代)。用这个命令可以跟踪整个单纯形算法的运行。Solve/Debug
Solve/Debug(调试)命令分析LP无解或无界的原因,建议如何修改。
Solve/Preemptive Goal
Solve/Preemptive Goal(多目标)命令依次按照多个目标求解模型。
2.2.4报告主菜单
Report/Solution
Report/Solution(解答)命令显示当前的解(你必须在此之前求解过当前模型)。对话框参见2-11,你可以选择“All Values”(把所有变量的值全部显示)。“Nonzero Only”(显示非零取值的变量),然后单击“OK”按钮即可。
Report/Range
Report/Range(敏感性分析)命令显示当前解的敏感性分析结果(你必须在此之前求解当前模型)。敏感性分析可参见相关参考书。
Report/Parametrics
Report/Parametrics(参数分析)命令对约束的右端项进行分析,也就是研究某个约束的右端项发生变化时,最优值如何变化。例如,对于前面介绍过的生产规划的优化问题,对话框如图2-12,你可以选择参数分析结果的报告方式。单击“OK”按钮得到参数分析结果(如图2-13所示),非常方便!从图中和报告窗口中显示结果都可以看出,这时最优解和最优值没有变化。请你用其他数试试,看看效果如何。
Report/Statistics
Report/Statistics(统计)命令显示当前模型的统计信息。例如,对于当前介绍的生产规划的优化问题(例2-1),该命令将在报告窗口显示如下统计信息:
第1行的意思:该模型有行,2个变量,
第2行的意思:非零系数共有个,约束中非零系数共有个
第3行的意思:模型中系数的最小值和最大值(按绝对值看)分别为
第4行的意思:模型目标为极大化,
第5行的意思:
2.3使用技巧及注意事项
我们前面已经看到,LINDO软件对模型的输入格式的要求与线性规划问题的自然形式(数
字形式)非常类似,几乎没有什么差别,因此几乎不要专门学习就可以掌握。LINDO软件对模型的输入格式还是有一些特殊规定的。我们下面就简单解释一下使用LINDO软件建立线性规划问题的一些特殊注意事项。
(1) LINDO中变量名由字母和数字组成,但必须以字母开头,且长度不能超过8个字符
(只能是英文字符,不能含有中文字符)。LINDO中不区分大小写字母,包括LINDO中本身的关键字(如MAX,MIN等)也不区分大小写字母。
(2) LINDO中对优化模型的目标和约束用行号进行标识,这些标识会在将来的求解报告
中用到。用户没有指定行号时,系统将自动产生行号,将目标函数所在行作为第一行,从第二行开始为约束条件。我们也可以人为定义行号或行名,行号或行名总是以“,”结束,放在相应的约束之前;行号或行名可以和变量名一样命名,也可以只用数字命名,但长度同样不能超过8个字符。为了方便将来阅读求解结果报告,建议用户总是自觉地对每个约束进行命名。行名中甚至可以含有中文字符,但行名结束标志符号必须是英文字符,否则会出现错误。
(3) 在LINDO模型的任何地方都可以用“TITLE”语句对输入的模型命名,用法是在
TITLE后面写出其名字(最多72个字符,也可以有汉字),在程序中单独占一行。请看下面两个例子:TITLE Example Modle for Chapter 2。TITLE第2章的第一个例子前者将模型命名为“TITLE Example Modle for Chapter 2”,后者将模型命名为“第2章的第一个例子”。实际上这类似于对模型的注释和说明,这是模型命名的第一个作用。对模型命名的另一个目的,是为了方便将来阅读求解结果报告。因为我们有可能同时处理多个模型,很容易混淆模型与求解结果的对应关系。这时如果对不同模型分别进行命名,就可以随时(例如在求解当前模型前)使用菜单命令
“FILE/TITLE”将当前模型的名字显示在求解结果报告窗口中,这样就容易判别每个求解结果与每个模型的对应关系。此外,LINDO模型中以感叹号“!” 开头的是注释行(注释语句或称为说明语句),可以帮助他人或以后自己理解这个模型。实际上,每行中“!”符号后面都是注释或说明。例如:!This is a comment。第1行完全是注释语句;第2行则后半部分为注释语句。可以看出,注释语句中以有汉字,但领头的有感叹号“!”必须是字符,否则会出现错误。再次总结,提醒一下:行号。“TITLE”语句和注释语句,是LINDO中惟一可以使用汉字字符的地方。
(4) LINDO中变量不能出现在一个约束条件的右端(即约束条件的右端只能的常数);
变量与其系数间可以有空格(甚至回车),但不能有任何运算符号(包括乘号“*”等)。
(5) LINDO中不能接受括号“()”和逗号“,”等任何符号(除非在注释的语句中),例
如:400(X1+X2)需写成400X1+400X2;“10,000”需写成“10000”。
(6) LINDO中表达式应当已经经过化简,如不能出现2X1+3X2-4X1而应写成-2X1+3X2
等。
(7) LINDO中已假定所有变量非负。可在模型的“END”语句后面用命令“FREE”(设
定自由变量)取消变量的非负假定。其用法是“FREE”后面跟变量名,例如,在“END”语句后输入下面命令,可将变量X的非负假定取消:FREE X
(8) 可以在模型的“END”语句后面用命令“SUB”(即设置上界(set upper bound)的
英文缩写)设定变量的上界,用命令“SLB”(即设置下界(set lower bound)的英文缩写)设定变量的上下界。其用法是:“UB vnme value”将变量Vname的上限设定为value;“SUB”的用法类似。例如:SUB X1 10 !作用等价于“X1〈=10”SLB X2 20 !作用等价于“X2〉=20”。但用“SUB”和“SLB”表示的上下界约束不计入模型的约束,因此LINDO也不能给出其松紧判断和敏感性分析。
(9) 数值均衡化及其他考虑:如果约束系数矩阵中各非零元的绝对值的数量级差别很大
(相差1000倍以上),则称其数值不均衡的。为了避免数值不均衡引起的计算问题,使用者应尽可能自己对矩阵的行列进行均衡化。此时还有一个原则,即系数中非零元的绝对值不能大于100000或小于0.0001。LINDO不能LP中系数自动进行数值均衡化,但如果LINDO觉得矩阵元素之间很不均衡,将会给出警告。
(10) 简单错误的检查和避免
当我们将一个线性规划问题的数学表达式输入LINDO系统时,有可能会带有某些输入错误。这类错误虽可能只是抄写和输入错误而造成的,但当问题规模较大时,要搜寻它们也是比较困难的。在LINDO中有一些可帮助寻找错误的功能,其中之一就是菜单命令“Report/Picture(Alt+5)”它的功能是可以将目标函数和约束表达式中的非零系数通过列表(或图形)显示出来。例2.2将图2-18中输入,Report/Picture命令,将弹出一个对话框(图2-19);在弹出的对话框中采用默认选项(即不采用下三角矩阵形式,而以图形方式显示),直接按“OK”按钮可得到图2-20的输出。可以从图2-9很直观地的发现,其实错误原因只不过是在图2-18中的输入中,行的表达式中弄混了。在图2-20中,还可以用鼠标控制显示图形的缩放,这对于规模较大的模型是有用的。
下面一个例子,说明三个变量范围限定命令(FREE,SUB,SLB)的作用。
这个模型中变量X没有非负限制,对Y有上限限制,对Z有下限限制。用FREE,SUB,SLB三个命令可以实现这些功能,具体输入如图2-21所示。
求解得到的结果如图2-22所示,即最大值为122,最优解为X=-7,Y=0,Z=39。可以看出Y的上界(20)在最优解中并没有达到,下界(30)也没有达到,因此模型中去掉“sub y 20”“slb z 30”两个语句,得到结果应该是不变的。但由于最优解中X的取值为负值,所以“free x”这个语句确实是不能少的。我们不妨试下,去掉了这个语句后效果会怎样?这时我们会发现模型没有可行解。
(11) 使输出的结果更简洁
对于例2.3,选择菜单命令“Reports/Solution(Alt+0)”(这个命令的功能是把最优解显示出来),这时会弹出一个选择对话框(图2-23),默认的选项是“Nonzreo Only(只显示非零值)”。按下图2-24所示,可以看到这时只显示了2个取非零值的变量X,Z。特别对于大的模型,这样阅读起来非常方便。
(12) 合理设定变量的上下界,尽可能给出变量的初始值
如果在实际问题中知道变量的取值范围,那就是尽量告诉LINDO,不要让软件帮你到大海捞针。例如,如果X的取值范围在实际中是大于30小于50,就不要让软件在这个整数范围内寻求最优解。有时实际问题中还能感觉到最优解大致在哪个解附近,那就可以以初始值的形式告诉LINDO,这对于问题的求解是很有帮助的。毕竟,软件是死的,而人要比计算机聪明的多。