lingo中双目标规划min=x+ymax=y这个怎么编程
发布时间:2025-05-24 11:03:07 发布人:远客网络
一、lingo中双目标规划min=x+ymax=y这个怎么编程
1、在lingo软件中处理双目标规划问题时,可以通过两种主要策略来解决。首先,可以为每个目标设定一个优先级,然后运用贯序求解法得出最终结果。这种方法有助于明确区分各个目标的重要程度,确保优先级较高的目标得到充分考虑。其次,也可以将两个目标赋予不同的权重,然后进行加权处理,将它们合并为单一目标进行优化。这样做的好处是简化了模型,使得求解过程更加直接。
2、采用贯序求解法时,需要明确每个目标的优先级。例如,假设目标一比目标二更重要,则可以先求解目标一,然后在满足目标一的基础上,求解目标二。这种方法要求目标之间的关系比较明确,且可以相互比较。通过这种方法,可以确保高优先级目标的约束条件被优先满足。
3、使用加权法时,需要根据实际问题的重要性分配权重。比如,如果目标一的重要性是目标二的两倍,那么可以将目标一的权重设为2,目标二的权重设为1。然后将两个目标的值按照各自的权重进行加权求和,形成一个新的目标函数。这种方法适用于目标之间关系较为复杂的场景,通过调整权重可以灵活地平衡不同目标之间的关系。
4、无论采用哪种方法,都需要确保模型的设定符合实际需求。在设定优先级或权重时,需要充分考虑各目标之间的相互作用以及它们对决策的影响。此外,在lingo中实现这些方法时,需要正确设置目标函数、约束条件以及变量范围,确保模型能够准确反映实际情况。通过合理设定和求解,可以有效地解决双目标规划问题。
二、求lingo新功能大全、高人来。
2006年初,LINDO系统公司正式发布了 LINGO 10.0版本。与 LINGO 9.0及更早的版
本相比,该版本的主要改进包括三个方面:
1.LINGO 10.0最显著的新特征在于增强了用 LINGO编程的能力。这主要包括:
在 LINGO 9.0及更早的版本的计算段( CALC)中,控制程序流程的只有一种语句,即
集合循环函数@FOR引导的语句,此外所有计算段中的语句是顺序执行的。 LINGO10.0在
计算段中增加了控制程序流程的语句,主要包括条件分支控制(@IFC或@IFC/@ELSE语
句)、条件循环控制(@WHILE语句)、循环跳出控制(@BREAK语句)、程序暂停控制
(@PAUSE语句)以及程序终止控制(@STOP语句)。
在 LINGO 9.0及更早的版本中,在每个 LINGO模型窗口中只允许有一个优化模型,可
以称为主模型( MAIN MODEL)。在 LINGO 10.0中,每个 LINGO模型窗口中除了主模型
外,用户还可以定义子模型(SUBMODEL)。子模型可以在主模型的计算段中被调用,这就
进一步增强了 LINGO的编程能力。相应的新增函数还包括@SOLVE、@GEN、@PIC、
LINGO10.0增加了输出函数@TABLE,可以更方便地以格式化的表格形式输出数据;
新增了数学函数@NORMSINV,即标准正态分布的分布函数的逆函数;新增了缺省输出设
备(文件)的重定义函数@DIVERT;新增了参数设置函数@SET和@APISET等。
2.对 LINGO内部采用的一些求解程序(如混合整数规划、非线性优化和全局优化求
解程序,包括一些相应的选项)的功能进行了完善和改进,使求解过程更快速、更可靠,对
模型进行调试的能力和对模型错误进行更准确定位的能力也得到了进一步增强。
3.增加了对一些新的软硬件的支持,如支持 64位运算和更大的内存等,以及支持 Java
JNI接口技术,新的@ODBC函数支持 Microsoft SQL Server等。
我们下面只对第1类新增功能(增强 LINGO编程能力的功能)进行简要介绍,关心第
2、3类新增功能的读者请直接阅读 LINGO在线帮助文件或相关介绍文档。
在计算段( CALC)中,如果只有当某个条件满足时才执行某个或某些语句,则可以使
用@IFC或@IFC/@ELSE语句,其中@ELSE部分是可选的(在下面的语法中用方括号表示)。
executable statements(可执行语句 1);
executable statements(可执行语句 2);]
其中 condition是一个逻辑表达式(表示相应的条件),当 condition的逻辑值为“真”
(条件成立)时,程序执行语句 1;否则程序执行语句 2。
我们以本书第五章 5.2节(有瓶颈设备的多级生产计划问题)中的数据来说明这个语句
的用法。在该问题中,项目间的消耗系数 Req是一个非常稀疏的矩阵,仅有 6个非零元。如果
我们想输出这个矩阵,但不显示其中的零元素(即显示为空),可以在原来的程序(本书 177-178
页的程序 exam0502.lg4)中增加以下的计算段:
@WRITE('项目间的消耗系数如下:');
@WRITEFOR(PART(J): 5*'', PART(J));
@write(@FORMAT( Req(i,j),'#5.0f'));
运行修改后的程序,相应的输出如下(只列出与计算段的输出相关的部分):
1.请注意上面程序中的函数@WRITE和@WRITEFOR,他们在 LINGO9.0中也出现过
(参见本书 112页),但当时主要是用在程序的数据段(DATA)方便用户控制输出格式,所
输出的变量的取值是程序运行结束后最后结果的相关数据,并且输出必须定向到@TEXT函
数,即通过@TEXT函数输出到缺省的输出设备(通常就是报告窗口)或文本文件。 LINGO10.0
中,这两个函数也是为了方便用户控制输出格式,但它们还可以出现在计算段(CALC)随时
输出中间结果,并且不需要使用@TEXT函数,输出的结果也是被定向到缺省的输出设备(通
常就是标准的报告窗口)。如果希望改变缺省的输出设备,可以采用@DIVERT函数(参见
作为一个简单例子,我们可以编写以下程序,说明在计算段中可以随时输出中间结果。
@write('a=',a,@newline(1));
@write('a=',a,@newline(1));
以上程序中第 3行和第 6行的语句是一样的,但输出结果却会不一样:
2.请读者特别注意,条件分支控制语句的用法只能出现在计算段( CALC)中。这也意
味着,我们不应该对程序运行结束后才能得到最后结果、计算段中尚未确定具体取值的变量
进行上述判断和输出。否则,输出的取值可能只是变量的初始值或中间计算结果。读者可能
会觉得既然如此,那么这种控制语句的用处就不大了,因为计算段处理的似乎都是已知参数
(或从已知参数很容易直接计算得到的变量值)。实际上并非如此,这是由于 LINGO10.0
增加了子模型功能,而子模型又是可以在计算段进行求解的,这时计算段中的变量所取的值
可能既不是初始参数,又不是整个模型最后的结果,但仍然可以输出中间结果。
而且,LINGO10.0中还增加了条件循环(@WHILE语句)等其他复杂的控制语句,它
们通常也要用到@IFC语句。我们将在后面介绍子模型和条件循环控制时再通过例子进行说
3.请读者注意,@IFC函数和以前用过的@IF函数的功能是不同的:@IFC是引导流程
控制语句的函数(按照不同条件选择不同的程序分支进行执行),而@IF是一个算术函数,
按照不同条件返回不同的计算结果或表达式(参见本书 114页的介绍)。
在 LINGO 9.0及更早的版本中,只有一种控制程序流程的语句,即集合循环函数@FOR
引导的语句,该函数对集合的元素逐个进行循环。在 LINGO 10.0中,如果只要当某个条
件满足时就反复执行某个或某些语句,直到条件不成立为止,则可以使用@WHILE语句。
executable statements(可执行语句);
其中 condition是一个逻辑表达式(表示相应的条件),当 condition的逻辑值为“真”
(条件成立)时,程序就执行相应的语句,直到条件不成立为止。请注意,条件循坏控制也
在条件循环控制中,还经常会使用到循坏跳出控制(@BREAK语句)、程序暂停控制
(@PAUSE语句)以及程序终止控制(@STOP语句):
@BREAK函数不需要任何参数,其功能是立即终止当前循环,继续执行当前循环
外的下一条语句。这个函数可以用在条件循环语句(@WHILE语句)中,也可以
用在集合循环语句(@FOR语句)中。此外,由于一般是在满足一定的特定条件
时才终止当前循环的执行,所以函数@BREAK一般也要结合@IFC/@ELSE使用。
@PAUSE函数暂停程序执行,并弹出一个窗口,等待用户选择继续执行(RESUME)
INTERRUPT)。如果希望在弹出的窗口中显示某些文本信息或某
个变量的当前取值,只需要将这些文本信息或变量作为
@STOP函数终止程序的运行,并弹出一个窗口,说明程序已经停止运行。如果希
望在弹出的窗口中显示某些文本信息或某个变量的当前取值,只需要将这些文本或
例如,如果希望从一个递增排列的正整数数列
所在的位置,可以采用二分搜索算法。具体的程序是(原程序位于
LOOPBINS.LG4,这里加上了中文注释):
X= 2 7 8 11 16 20 22 32;!递增排列的正整数数列;
IE=@SIZE( S1);!搜索位置的最大值(数列中元素的个数)
LOC=@FLOOR((IB+ IE)/2);!二分法;
@PAUSE('找到位置:', LOC);!显示结果;
@STOP('数列中找不到相应的数!!!');!程序停止运行;
注:这里集合 S1没有显式地定义元素,但由于其属性 X有 8个元素,因此 LINGO自
动认为集合 S1={1,2,3,4,5,6,7,8}。
本程序运行时,将找到 KEY= 16位于数列 X中的第 5个位置,于是通过@PAUSE语句
将这一信息报告给用户;如果取 KEY= 15,由于数列 X中没有 15,程序运行时通过@STOP
请读者注意,由于@BREAK函数不需要参数,因此程序中的语句直接写成“@BREAK;”。
而函数@PAUSE和@STOP是可以有参数的,所以程序中即使不给出参数,语句也应该写成
“@PAUSE();”和“@STOP();”,即标示参数表的小括号不能省略,否则就会出现语法错误。
这和以前用过的函数@TEXT的用法非常类似。
在 LINGO 9.0及更早的版本中,在每个 LINGO模型窗口中只允许有一个优化模型,可
以称为主模型( MAIN MODEL)。在 LINGO 10.0中,每个 LINGO模型窗口中除了主模型
外,用户还可以定义子模型(SUBMODEL)。子模型可以在主模型的计算段中被调用,这就
进一步增强了 LINGO的编程能力。
子模型必须包含在主模型之内,即必须位于以“ MODEL:”开头、以“ END”结束的模
块内。同一个主模型中,允许定义多个子模型,所以每个子模型本身必须命名,其基本语法
其中 mymodel是该子模型的名字,可执行语句一般是一些约束语句,也可能包含目标
函数,但不可以有自身单独的集合段、数据段、初始段和计算段。也就是说,同一个主模型
内的变量都是全局变量,这些变量对主模型和所有子模型同样有效。
如果已经定义了子模型 mymodel,则在计算段中可以用语句“@SOLVE( submodel);”求
我们来看一个背包问题( Knapsack Problem)的例子:王先生想要出门旅行,需要将一
些旅行用品装入一个旅行背包。旅行背包有一个重量限制,装入的旅行用品总重量不得超过
30千克。候选的旅行用品有 8件,其重量依次为 3、4、6、7、9、10、11、12(千克);
王先生认为这8件旅行用品的价值(或重要性)依次为 4、6、7、9、11、12、13、15。那
么,为了使背包装入的旅行用品的总价值最大,王先生应该选择哪几件旅行用品?
我们用 VAL(I)、WGT(I)分别表示第 I件物品的价值和重量, CAP表示背包的重量
限制,用 Y(I)表示是否装入第 I件物品( 0-1决策变量,1表示装, 0表示不装)。容易建
立如下优化模型(直接按 LINGO的程序格式写出,命名为文件 knapsack01.lg4):
[Objective] OBJ=@SUM( ITEM(j): VAL(j)*Y(j));!目标;
[Capacity]@SUM( ITEM(j): WGT(j)*Y(j))<= CAP;!重量约束;
@FOR( ITEM(j):@BIN( Y(j)));!0/1变量;
对于这样一个简单的模型,上面的程序中只有主模型。作为一种练习,我们也可以将这
CALC中进行求解,相应的程序为(命名为文件
SUBMODEL KNAPSACK:!开始定义子模型
[objective] OBJ=@SUM( ITEM(j): VAL(j)*Y(j));!目标;
[capacity]@SUM( ITEM(j): WGT(j)*Y(j))<= CAP;!重量约束;
@FOR( ITEM(j):@BIN( Y(j)));!0/1变量;
ENDSUBMODEL!完成子模型KNAPSACK的定义;
求解本模型,得到的结果与不用子模型时相同。
A.3.2求背包问题的多个最好解的例子
对于上面的背包问题,最优解并不是唯一的。如果我们希望找到所有的最优解(最优值
OBJ=38的所有解),有没有办法呢?更一般地,能否找出前 K个最好的解?这样我们可以
把这 K个最好的解全部列出来,供王先生(决策者)选择。
为了得到第 2个最好的解,我们需要再次求解子模型 KNAPSACK,但必须排除再次找到
刚刚得到的解 Y(2)=Y(4)=Y(5)=Y(6)=1(其他 Y(I)为 0)。因此,我们需要在第 2次求解子模型
KNAPSACK时,增加一些约束条件(一般称为“割”)。生成“割”的方法可能有很多种,
这里我们介绍一种针对 0-1变量的特殊处理方法。
对于我们刚刚得到的解 Y(2)=Y(4)=Y(5)=Y(6)=1(其他 Y(I)为 0),显然满足
Y(1)-Y(2)+ Y(3)-Y(4)- Y(5)-Y(6)+ Y(7)+ Y(8)=-4;
这个等式左边就是将刚刚得到的解中取 1的 Y(I)的系数定义为-1,取 0的 Y(I)的系数定义
为 1,然后求代数和;等式右边就是解中取 1的 Y(I)的个数的相反数。
为了防止再次求解子模型 KNAPSACK时这个解再次出现,就是要防止 Y(2),Y(4),Y(5),
Y(6)同时取 1的情况出现。下面的约束就可以保证做到这一点:
Y(1)-Y(2)+ Y(3)-Y(4)- Y(5)-Y(6)+ Y(7)+ Y(8)>=-3;
这个约束就是将上面等式中的右端项增加了 1,将等号“=”改成了“>=”。显然,这
个约束排除了 Y(2),Y(4),Y(5),Y(6)同时取 1的情况,因为 Y(2),Y(4),Y(5),Y(6)同时
取 1(其他 Y(I)=0)不能满足这个约束。其次,由于 Y(I)只能取 0或 1,这个约束除了排除
Y(2),Y(4),Y(5),Y(6)同时取 1的情况外,没有对原可行解空间增加任何新的限制。
可以想象,增加这个约束后,新的最优解一定与 Y(2)=Y(4)=Y(5)=Y(6)=1(其他 Y(I)为
0)不同。这种处理方法具有一般性,可以用于找出背包问题的前 K个最好解。
具体的程序如下(以下程序中取 K=7,命名为文件 knapsack03.lg4)):
SOLN: RHS;! RHS表示根据每个最优解生成“割”时的右端项;
SXI(SOLN,ITEM): COF;!“割”的系数,即 1或-1;
OBJ=@SUM( ITEM(j): VAL(j)*Y(j));!目标;
@SUM( ITEM(j): WGT(j)*Y(j))<= CAP;!重量约束;
@FOR( ITEM(j):@BIN( Y(j)));!0/1变量;
@FOR( SOLN(k)| k#LT# ksofar:!"割去"(排除)已经得到的解;
@SUM( ITEM(j): COF(k,j)*Y(j))>= RHS(k);
@divert('knapsack.txt');!结果保存到文件knapsack.txt;
@FOR( SOLN(ks):!对ks=1,2,…,K进行循环;
KSOFAR= ks;! KSOFAR表示当前正在计算的是第几个最优解;
!以下打印当前(第ks个)最优解Y及对应的最优值OBJ;
@WRITE('',ks,'',@FORMAT( OBJ,'3.0f'),':');
@writefor(ITEM(j):'',Y(j));
!以下计算这个解生成的“割”的系数;
@divert();!关闭文件knapsack.txt,恢复正常输出模式;
注:计算段中的语句@divert('knapsack.txt')的含义是,将此后的输出定向到文
本文件knapsack.txt(参见本附录A.4.3节)。
运行这个程序以后,文件 knapsack.txt中将包括以下输出(其他输出略去):
可见,前 7个最好的解中,最优值为 OBJ=38的解一共有 3个,而 OBJ=37的解至少有
4个(因为我们只计算了前 7个最好的解,我们暂时还无法判断 OBJ=37的解是否只有 4个),
每个解(Y的取值)也显示在结果报告中了。
同一个 LINGO主模型中,允许定义多个子模型。例如,如果我们希望分别求解以下 4
1且 x,y非负的条件下,求 x-y的最大值;
1且 x,y非负的条件下,求 x+y的最小值;
@write('问题1的解:',@newline(1));
@write('问题2的解:',@newline(1));
@write('问题3的解:',@newline(1));
@write('问题4的解:',@newline(1));
OBJ1和OBJ2只有目标(没有约束),而
只有约束(没有目标)。在计算段,我们将它们进行不同的组合,分别得到针对问题(
的优化模型进行求解。但需要注意,每个
@solve命令所带的参数表中的子模型是先合并后求解
@solve命令所带的参数表中的子模型合并后是合理的优化模型,例
运行这个后,得到的正是我们预想的结果(只列出部分相关的输出结果):
Objective value: 0.2403504E-09
这4个问题都是非常简单的问题,最优解和最优值很容易用解析方法计算得到,读者不
妨用解析方法计算和验证一下以上得到的解的正确性。
这个函数只能在计算段使用,功能与菜单命令
132页),即生成完整的模型并以代数形式显示(主要作用是可供
用户检查模型是否有误)。当不使用任何调用参数时,
“@GEN();”语句只对主模型中出现
在当前“@GEN();”语句之前的模型语句进行处理。
knapsack01.lg4中增加以下的计算段:
则程序运行时报告窗口的显示为:
[OBJECTIVE] OBJ- 4* Y_1- 6* Y_2- 7* Y_3- 9* Y_4- 11*Y_5– 12*
[CAPACITY] 3* Y_1+ 4* Y_2+ 6* Y_3+ 7* Y_4+ 9* Y_5+ 10* Y_6+ 11
@BIN( Y_1);@BIN( Y_2);@BIN( Y_3);@BIN( Y_4);@BIN( Y_5);
@BIN( Y_6);@BIN( Y_7);@BIN( Y_8);
三、数学规划求解软件Lingo使用简介
1、Lingo,由美国Chicago大学的Linus Schrage教授在1980年左右开发,现由LINDO Systems Inc.提供服务,可通过其官网www.lindo.com了解详情。这款软件主要用于构建和求解优化问题,其核心是数学规划模型,包括决策变量(x1, x2,..., xn)、目标函数(min Z=f(x))和约束条件(x属于A),并通过单纯形法求解。
2、Lingo的界面设计简洁明了,工具栏和菜单栏提供了清晰的操作路径。运行状态窗口则实时展示模型的运行情况。在使用Lingo时,基本语法要点包括目标函数的定义(MIN=, MAX=)、运算符的使用(如<=、>=)、以及注释的添加。在建模过程中,应尽量避免过多的整数约束和非线性元素,通过实数优化和线性模型简化问题。
3、Lingo还提供了丰富的运算符和函数,如数学函数、变量定界和条件判断,以及支持集合循环操作的函数。模型的构建通常分为四个段:目标与约束段、集合段、数据段和初始段,每个段都具有明确的作用和格式。对于集合,Lingo支持显式和隐式列举法,以及派生集合的构造,对于循环操作,使用集合索引和过滤条件进行。
4、尽管Lingo功能强大,但理解和掌握其集合循环函数可能会有些挑战,这是需要重点学习和实践的部分。总的来说,Lingo是一款强大的数学规划求解软件,通过合理利用其语法和功能,可以有效地解决复杂的优化问题。