
一、主体不同
1、lingo:是交互式的线性和通用优化求解器。
2、lindo:是一个解决二次线性整数规划问题的方便而强大的工具。
二、特点不同
1、lingo:特色在于内置建模语言,提供十几个内部函数,可以允许决策变量是整数(即整数规划,包括 0-1 整数规划),方便灵活,而且执行速度非常快。
2、lindo:主要设计原则是,如果一个用户只是想解决一个简单的问题,就不应该在学习LINDO的基本特性上花费太多的准备成本。
三、用处不同
1、lingo:可以用于求解非线性规划,也可以用于一些线性和非线性方程组的求解等,功能十分强大,是求解优化模型的最佳选择。
2、lindo:LINDO能在商业、工业、研究和政府等领域发挥巨大作用。
参考资料来源:百度百科-LINGO
参考资料来源:百度百科-LINDO
1首先说一下:ch9505有病吗,记得我上次问了个问题,他丫的也是直接复制下来。
2然后我开始帮你解答这个题目:
所有代码都是原创的,大概花了我一个上午才帮你解出来的。这个题目虽然不是太难,但是数据有些繁琐。集合声明比较多,维度不一。希望能够帮上你的忙。
程序部分:
MODEL:
SETS:
program/14/;!定义四个项目;
factory/1,2/:totaltime;!定义两个车间,注意:本程序中,我们约定q开头代表数量,c开头代表成本;
warehouse/1,2,3/;!定义三个仓库;
steel/A,B,C,D/;!定义四种钢材(集合中第四种钢材为塑钢门窗);
component/1,2/;!定义两种构件;
linka(steel,warehouse):qlinka;!表21==仓库存钢量;
linkb(component,steel):qlinkb;!表22==单位构件需钢材量;
linkc(factory,component):time,cost,qlinkc;!表23 24==车间生产成本(&耗时);
linkd(program,component):cpdemand;!表25,cpdemand stands for "component demand"构件需求量;
linke(program,steel):stdemand;!表25,stdemand for "steel demand"钢材需求量;
linkf(factory,steel):qlinkf;
deepa(factory,program,component):qdeepa;!242=16个量;
deepb(warehouse,program,steel):qdeepb;!344=48个量;
deepc(steel,warehouse,factory):qdeepc;!432=24;
!deepd(factory,component,steel):qdeepd;!224=16;
transa(factory,program):qtransa,ctransa;!本集合和下面两个集合,仓库,车间,项目之间的运输。表26;
transb(warehouse,program):qtransb,ctransb;
transc(warehouse,factory):qtransc,ctransc;
ENDSETS
DATA:
qlinka=
4000 4000 6000
3000 3500 2500
3000 5000 5000
200 250 100;
qlinkb=
15 10 20 0
20 10 15 0;
totaltime= 35000 60000;
time=100 200
200 100;
cost=6600 7800
6500 7300;
cpdemand=
50 100
30 60
100 200
50 80;
stdemand=
100 70 0 100
50 80 0 120
30 90 0 80
70 60 0 200;
ctransa=
100 150 80 70
50 60 80 90;
ctransb=
40 20 30 50
60 40 80 100
50 60 75 85;
ctransc=
40 80
100 20
80 40;
ENDDATA
MIN=@sum(linkc:costqlinkc)+@sum(transa:qtransactransa)+@sum(transb:qtransbctransb)+@sum(transc:qtranscctransc);
!1构件需求约束;
@for(linkd(i,j):@sum(factory(k):qdeepa(k,i,j))=cpdemand(i,j));
!2钢材需求约束;
@for(linke(i,j):@sum(warehouse(k):qdeepb(k,i,j))=stdemand(i,j));
!3车间工时约束;
@for(factory(i):@sum(component(j):time(i,j)qlinkc(i,j))<=totaltime(i));
!4库存钢材数量平衡;
@for(linka(i,j):@sum(program(k):qdeepb(j,k,i))+@sum(factory(m):qdeepc(i,j,m))<=qlinka(i,j));
!5生产运出平衡;
@for(linkc(i,j):@sum(program(k):qdeepa(i,k,j))=qlinkc(i,j));
!6单位构件需钢材量约束;
@for(linkf(i,k):qlinkf(i,k)=@sum(component(j):qlinkc(i,j)qlinkb(j,k)));
!7运输量的约束;
@for(transa(i,j):qtransa=@sum(component(k):qdeepa(i,j,k)));
@for(transb(i,j):qtransb=@sum(steel(k):qdeepb(i,j,k)));
@for(transc(i,j):qtransc=@sum(steel(k):qdeepc(k,i,j)));
@for(linkf(i,j):qlinkf(i,j)=@sum(warehouse(k):qdeepc(j,k,i)));
END
部分结果:
Global optimal solution found at iteration: 80
Objective value: 5770900
Variable Value Reduced Cost
TOTALTIME( 1) 3500000 0000000
TOTALTIME( 2) 6000000 0000000
QLINKA( A, 1) 4000000 0000000
QLINKA( A, 2) 4000000 0000000
QLINKA( A, 3) 6000000 0000000
QLINKA( B, 1) 3000000 0000000
QLINKA( B, 2) 3500000 0000000
QLINKA( B, 3) 2500000 0000000
QLINKA( C, 1) 3000000 0000000
QLINKA( C, 2) 5000000 0000000
QLINKA( C, 3) 5000000 0000000
QLINKA( D, 1) 2000000 0000000
QLINKA( D, 2) 2500000 0000000
QLINKA( D, 3) 1000000 0000000
QLINKB( 1, A) 1500000 0000000
QLINKB( 1, B) 1000000 0000000
QLINKB( 1, C) 2000000 0000000
QLINKB( 1, D) 0000000 0000000
QLINKB( 2, A) 2000000 0000000
QLINKB( 2, B) 1000000 0000000
QLINKB( 2, C) 1500000 0000000
QLINKB( 2, D) 0000000 0000000
TIME( 1, 1) 1000000 0000000
TIME( 1, 2) 2000000 0000000
TIME( 2, 1) 2000000 0000000
TIME( 2, 2) 1000000 0000000
COST( 1, 1) 6600000 0000000
COST( 1, 2) 7800000 0000000
COST( 2, 1) 6500000 0000000
COST( 2, 2) 7300000 0000000
QLINKC( 1, 1) 1500000 0000000
QLINKC( 1, 2) 0000000 1750000
QLINKC( 2, 1) 8000000 0000000
QLINKC( 2, 2) 4400000 0000000
CPDEMAND( 1, 1) 5000000 0000000
CPDEMAND( 1, 2) 1000000 0000000
CPDEMAND( 2, 1) 3000000 0000000
CPDEMAND( 2, 2) 6000000 0000000
CPDEMAND( 3, 1) 1000000 0000000
CPDEMAND( 3, 2) 2000000 0000000
CPDEMAND( 4, 1) 5000000 0000000
CPDEMAND( 4, 2) 8000000 0000000
STDEMAND( 1, A) 1000000 0000000
STDEMAND( 1, B) 7000000 0000000
STDEMAND( 1, C) 0000000 0000000
STDEMAND( 1, D) 1000000 0000000
STDEMAND( 2, A) 5000000 0000000
STDEMAND( 2, B) 8000000 0000000
STDEMAND( 2, C) 0000000 0000000
STDEMAND( 2, D) 1200000 0000000
STDEMAND( 3, A) 3000000 0000000
STDEMAND( 3, B) 9000000 0000000
STDEMAND( 3, C) 0000000 0000000
STDEMAND( 3, D) 8000000 0000000
STDEMAND( 4, A) 7000000 0000000
STDEMAND( 4, B) 6000000 0000000
STDEMAND( 4, C) 0000000 0000000
STDEMAND( 4, D) 2000000 0000000
QLINKF( 1, A) 2250000 0000000
QLINKF( 1, B) 1500000 0000000
QLINKF( 1, C) 3000000 0000000
QLINKF( 1, D) 0000000 0000000
QLINKF( 2, A) 1000000 0000000
QLINKF( 2, B) 5200000 0000000
QLINKF( 2, C) 8200000 0000000
QLINKF( 2, D) 0000000 0000000
QDEEPA( 1, 1, 1) 0000000 0000000
QDEEPA( 1, 1, 2) 0000000 7000000
QDEEPA( 1, 2, 1) 0000000 4000000
QDEEPA( 1, 2, 2) 0000000 1100000
QDEEPA( 1, 3, 1) 1000000 0000000
QDEEPA( 1, 3, 2) 0000000 2000000
QDEEPA( 1, 4, 1) 5000000 0000000
QDEEPA( 1, 4, 2) 0000000 0000000
QDEEPA( 2, 1, 1) 5000000 0000000
QDEEPA( 2, 1, 2) 1000000 0000000
QDEEPA( 2, 2, 1) 3000000 0000000
QDEEPA( 2, 2, 2) 6000000 0000000
QDEEPA( 2, 3, 1) 0000000 5000000
QDEEPA( 2, 3, 2) 2000000 0000000
QDEEPA( 2, 4, 1) 0000000 7000000
QDEEPA( 2, 4, 2) 8000000 0000000
QDEEPB( 1, 1, A) 1000000 0000000
QDEEPB( 1, 1, B) 7000000 0000000
QDEEPB( 1, 1, C) 0000000 6250000
QDEEPB( 1, 1, D) 0000000 2500000
QDEEPB( 1, 2, A) 5000000 0000000
QDEEPB( 1, 2, B) 8000000 0000000
QDEEPB( 1, 2, C) 0000000 4250000
QDEEPB( 1, 2, D) 0000000 2500000
QDEEPB( 1, 3, A) 3000000 0000000
QDEEPB( 1, 3, B) 9000000 0000000
QDEEPB( 1, 3, C) 0000000 5250000
QDEEPB( 1, 3, D) 8000000 0000000
QDEEPB( 1, 4, A) 7000000 0000000
QDEEPB( 1, 4, B) 6000000 0000000
QDEEPB( 1, 4, C) 0000000 7250000
QDEEPB( 1, 4, D) 1200000 0000000
QDEEPB( 2, 1, A) 0000000 8000000
QDEEPB( 2, 1, B) 0000000 4000000
QDEEPB( 2, 1, C) 0000000 8000000
QDEEPB( 2, 1, D) 8000000 0000000
QDEEPB( 2, 2, A) 0000000 8000000
QDEEPB( 2, 2, B) 0000000 4000000
QDEEPB( 2, 2, C) 0000000 6000000
QDEEPB( 2, 2, D) 1200000 0000000
QDEEPB( 2, 3, A) 0000000 1100000
QDEEPB( 2, 3, B) 0000000 7000000
QDEEPB( 2, 3, C) 0000000 1000000
QDEEPB( 2, 3, D) 0000000 5000000
QDEEPB( 2, 4, A) 0000000 1100000
QDEEPB( 2, 4, B) 0000000 7000000
QDEEPB( 2, 4, C) 0000000 1200000
QDEEPB( 2, 4, D) 0000000 5000000
QDEEPB( 3, 1, A) 0000000 5000000
QDEEPB( 3, 1, B) 0000000 1000000
QDEEPB( 3, 1, C) 0000000 5000000
QDEEPB( 3, 1, D) 2000000 0000000
QDEEPB( 3, 2, A) 0000000 8000000
QDEEPB( 3, 2, B) 0000000 4000000
QDEEPB( 3, 2, C) 0000000 6000000
QDEEPB( 3, 2, D) 0000000 3000000
QDEEPB( 3, 3, A) 0000000 8500000
QDEEPB( 3, 3, B) 0000000 4500000
QDEEPB( 3, 3, C) 0000000 7500000
QDEEPB( 3, 3, D) 0000000 1000000
QDEEPB( 3, 4, A) 0000000 7500000
QDEEPB( 3, 4, B) 0000000 3500000
QDEEPB( 3, 4, C) 0000000 8500000
QDEEPB( 3, 4, D) 8000000 0000000
QDEEPC( A, 1, 1) 2250000 0000000
QDEEPC( A, 1, 2) 0000000 0000000
QDEEPC( A, 2, 1) 0000000 1200000
QDEEPC( A, 2, 2) 4000000 0000000
QDEEPC( A, 3, 1) 0000000 8000000
QDEEPC( A, 3, 2) 6000000 0000000
QDEEPC( B, 1, 1) 1500000 0000000
QDEEPC( B, 1, 2) 0000000 4000000
QDEEPC( B, 2, 1) 0000000 8000000
QDEEPC( B, 2, 2) 3500000 0000000
QDEEPC( B, 3, 1) 0000000 4000000
QDEEPC( B, 3, 2) 1700000 0000000
QDEEPC( C, 1, 1) 3000000 0000000
QDEEPC( C, 1, 2) 0000000 6250000
QDEEPC( C, 2, 1) 0000000 5750000
QDEEPC( C, 2, 2) 5000000 0000000
QDEEPC( C, 3, 1) 0000000 1750000
QDEEPC( C, 3, 2) 3200000 0000000
QDEEPC( D, 1, 1) 0000000 8500000
QDEEPC( D, 1, 2) 0000000 1250000
QDEEPC( D, 2, 1) 0000000 1000000
QDEEPC( D, 2, 2) 0000000 2000000
QDEEPC( D, 3, 1) 0000000 9000000
QDEEPC( D, 3, 2) 0000000 5000000
QTRANSA( 1, 1) 0000000 0000000
QTRANSA( 1, 2) 0000000 0000000
QTRANSA( 1, 3) 1000000 0000000
QTRANSA( 1, 4) 5000000 0000000
QTRANSA( 2, 1) 1500000 0000000
QTRANSA( 2, 2) 9000000 0000000
QTRANSA( 2, 3) 2000000 0000000
QTRANSA( 2, 4) 8000000 0000000
CTRANSA( 1, 1) 1000000 0000000
CTRANSA( 1, 2) 1500000 0000000
CTRANSA( 1, 3) 8000000 0000000
CTRANSA( 1, 4) 7000000 0000000
CTRANSA( 2, 1) 5000000 0000000
CTRANSA( 2, 2) 6000000 0000000
CTRANSA( 2, 3) 8000000 0000000
CTRANSA( 2, 4) 9000000 0000000
QTRANSB( 1, 1) 1700000 0000000
QTRANSB( 1, 2) 1300000 0000000
QTRANSB( 1, 3) 2000000 0000000
QTRANSB( 1, 4) 2500000 0000000
QTRANSB( 2, 1) 8000000 0000000
QTRANSB( 2, 2) 1200000 0000000
QTRANSB( 2, 3) 0000000 0000000
QTRANSB( 2, 4) 0000000 0000000
QTRANSB( 3, 1) 2000000 0000000
QTRANSB( 3, 2) 0000000 0000000
QTRANSB( 3, 3) 0000000 0000000
QTRANSB( 3, 4) 8000000 0000000
CTRANSB( 1, 1) 4000000 0000000
CTRANSB( 1, 2) 2000000 0000000
CTRANSB( 1, 3) 3000000 0000000
CTRANSB( 1, 4) 5000000 0000000
CTRANSB( 2, 1) 6000000 0000000
CTRANSB( 2, 2) 4000000 0000000
CTRANSB( 2, 3) 8000000 0000000
CTRANSB( 2, 4) 1000000 0000000
CTRANSB( 3, 1) 5000000 0000000
CTRANSB( 3, 2) 6000000 0000000
CTRANSB( 3, 3) 7500000 0000000
CTRANSB( 3, 4) 8500000 0000000
QTRANSC( 1, 1) 6750000 0000000
QTRANSC( 1, 2) 0000000 0000000
QTRANSC( 2, 1) 0000000 0000000
QTRANSC( 2, 2) 1250000 0000000
QTRANSC( 3, 1) 0000000 0000000
QTRANSC( 3, 2) 1090000 0000000
CTRANSC( 1, 1) 4000000 0000000
CTRANSC( 1, 2) 8000000 0000000
CTRANSC( 2, 1) 1000000 0000000
CTRANSC( 2, 2) 2000000 0000000
CTRANSC( 3, 1) 8000000 0000000
CTRANSC( 3, 2) 4000000 0000000
最后:我对结果只是检验了一下需求量,发现满足,如果你发现有什么不对的地方,可以告诉我,我会对其进行调整。另外我的集合声明中有些如果你觉得繁琐的地方,可以进行修改。****511757449@qqcom,或者直接在百度HI上留言。
附录 LINGO100新增功能介绍
A1 新增功能简介
2006年初,LINDO系统公司正式发布了 LINGO 100版本。与 LINGO 90及更早的版
本相比,该版本的主要改进包括三个方面:
1.LINGO 100最显著的新特征在于增强了用 LINGO编程的能力。这主要包括:
(1)程序流程的控制
在 LINGO 90及更早的版本的计算段( CALC)中,控制程序流程的只有一种语句,即
集合循环函数@FOR引导的语句,此外所有计算段中的语句是顺序执行的。 LINGO100在
计算段中增加了控制程序流程的语句,主要包括条件分支控制(@IFC或@IFC/@ELSE语
句)、条件循环控制( @WHILE语句)、循环跳出控制( @BREAK语句)、程序暂停控制
(@PAUSE语句)以及程序终止控制(@STOP语句)。
(2)子模型( SUBMODEL)
在 LINGO 90及更早的版本中,在每个 LINGO模型窗口中只允许有一个优化模型,可
以称为主模型( MAIN MODEL)。在 LINGO 100中,每个 LINGO模型窗口中除了主模型
外,用户还可以定义子模型(SUBMODEL)。子模型可以在主模型的计算段中被调用,这就
进一步增强了 LINGO的编程能力。相应的新增函数还包括 @SOLVE、@GEN、@PIC、
@SMPI、@RELEASE等。
(3) 其他新增函数
LINGO100增加了输出函数 @TABLE,可以更方便地以格式化的表格形式输出数据;
新增了数学函数 @NORMSINV,即标准正态分布的分布函数的逆函数;新增了缺省输出设
备(文件)的重定义函数 @DIVERT;新增了参数设置函数@SET和@APISET等。
2.对 LINGO内部采用的一些求解程序(如混合整数规划、非线性优化和全局优化求
解程序,包括一些相应的选项)的功能进行了完善和改进,使求解过程更快速、更可靠,对
模型进行调试的能力和对模型错误进行更准确定位的能力也得到了进一步增强。
3.增加了对一些新的软硬件的支持,如支持 64位运算和更大的内存等,以及支持 Java
JNI接口技术,新的@ODBC函数支持 Microsoft SQL Server 等。
我们下面只对第1类新增功能(增强 LINGO编程能力的功能)进行简要介绍,关心第
2、3类新增功能的读者请直接阅读 LINGO在线帮助文件或相关介绍文档。
A2程序流程的控制
A21条件分支控制
在计算段( CALC)中,如果只有当某个条件满足时才执行某个或某些语句,则可以使
用@IFC或@IFC/@ELSE语句,其中 @ELSE部分是可选的(在下面的语法中用方括号表示)。
其基本的使用语法是:
@IFC(condition:
executable statements(可执行语句 1);
[@ELSE
executable statements(可执行语句 2);]
)
其中 condition是一个逻辑表达式(表示相应的条件),当 condition的逻辑值为“真”
(条件成立)时,程序执行语句 1;否则程序执行语句 2。
我们以本书第五章 52节(有瓶颈设备的多级生产计划问题)中的数据来说明这个语句
的用法。在该问题中,项目间的消耗系数 Req是一个非常稀疏的矩阵,仅有 6个非零元。如果
我们想输出这个矩阵,但不显示其中的零元素(即显示为空),可以在原来的程序(本书 177-178
页的程序 exam0502lg4)中增加以下的计算段:
calc:
@WRITE( ' 项目间的消耗系数如下: ');
@WRITE( @NEWLINE(1));
@WRITEFOR(PART(J): 5' ', PART(J));
@FOR( PART(I):
@WRITE( @NEWLINE(1), PART(I));
@FOR( PART(J):
@IFC( Req(i,j) #GT# 00:
@write( @FORMAT( Req(i,j), '#50f'));
@ELSE
@WRITE(' ');
);
);
);
@WRITE( @NEWLINE(2));
endcalc
运行修改后的程序,相应的输出如下(只列出与计算段的输出相关的部分):
项目间的消耗系数如下:
A B C D E F G
A
B 5
C 7
D 9
E 11
F 13
G 15
下面我们作几点说明:
1.请注意上面程序中的函数 @WRITE和@WRITEFOR,他们在 LINGO90中也出现过
(参见本书 112页),但当时主要是用在程序的数据段 (DATA)方便用户控制输出格式,所
输出的变量的取值是程序运行结束后最后结果的相关数据, 并且输出必须定向到@TEXT函
数,即通过@TEXT函数输出到缺省的输出设备(通常就是报告窗口)或文本文件。 LINGO100
中,这两个函数也是为了方便用户控制输出格式,但它们还可以出现在计算段(CALC)随时
输出中间结果,并且不需要使用@TEXT函数,输出的结果也是被定向到缺省的输出设备(通
常就是标准的报告窗口)。如果希望改变缺省的输出设备,可以采用 @DIVERT函数(参见
本附录 A43节)。
作为一个简单例子,我们可以编写以下程序,说明在计算段中可以随时输出中间结果。
calc:
a=5;
@write('a= ',a,@newline(1));
b=8;
a=a+b;
@write('a= ',a,@newline(1));
endcalc
以上程序中第 3行和第 6行的语句是一样的,但输出结果却会不一样:
a= 5
a= 13
2 请读者特别注意,条件分支控制语句的用法只能出现在计算段( CALC)中。这也意
味着,我们不应该对程序运行结束后才能得到最后结果、计算段中尚未确定具体取值的变量
进行上述判断和输出。否则,输出的取值可能只是变量的初始值或中间计算结果。读者可能
会觉得既然如此,那么这种控制语句的用处就不大了,因为计算段处理的似乎都是已知参数
(或从已知参数很容易直接计算得到的变量值)。实际上并非如此,这是由于 LINGO100
增加了子模型功能,而子模型又是可以在计算段进行求解的,这时计算段中的变量所取的值
可能既不是初始参数,又不是整个模型最后的结果,但仍然可以输出中间结果。
而且,LINGO100中还增加了条件循环( @WHILE语句)等其他复杂的控制语句,它
们通常也要用到@IFC语句。我们将在后面介绍子模型和条件循环控制时再通过例子进行说
明。
3.请读者注意,@IFC函数和以前用过的@IF函数的功能是不同的:@IFC是引导流程
控制语句的函数(按照不同条件选择不同的程序分支进行执行),而@IF是一个算术函数,
按照不同条件返回不同的计算结果或表达式(参见本书 114页的介绍)。
A22条件循环控制及相关语句
在 LINGO 90及更早的版本中,只有一种控制程序流程的语句,即集合循环函数 @FOR
引导的语句,该函数对集合的元素逐个进行循环。在 LINGO 100中,如果只要当某个条
件满足时就反复执行某个或某些语句,直到条件不成立为止,则可以使用@WHILE语句。
其基本的使用语法是:
@WHILE(condition:
executable statements(可执行语句);
)
其中 condition是一个逻辑表达式(表示相应的条件),当 condition的逻辑值为“真”
(条件成立)时,程序就执行相应的语句,直到条件不成立为止。请注意,条件循坏控制也
只能出现在计算段(CALC)中。
在条件循环控制中,还经常会使用到循坏跳出控制(@BREAK语句)、程序暂停控制
(@PAUSE语句)以及程序终止控制(@STOP语句):
@BREAK函数不需要任何参数,其功能是立即终止当前循环,继续执行当前循环
外的下一条语句。这个函数可以用在条件循环语句(@WHILE语句)中,也可以
用在集合循环语句(@FOR语句)中。此外,由于一般是在满足一定的特定条件
时才终止当前循环的执行,所以函数@BREAK一般也要结合@IFC/@ELSE使用。
@PAUSE函数暂停程序执行,并d出一个窗口,等待用户选择继续执行(RESUME)
或者终止程序(
INTERRUPT)。如果希望在d出的窗口中显示某些文本信息或某
个变量的当前取值,只需要将这些文本信息或变量作为
@PAUSE的调用参数即可。
@STOP函数终止程序的运行,并d出一个窗口,说明程序已经停止运行。如果希
望在d出的窗口中显示某些文本信息或某个变量的当前取值,只需要将这些文本或
变量作为@STOP的调用参数即可。
例如,如果希望从一个递增排列的正整数数列
X中找到某个具体的数
KEY在数列
X中
所在的位置, 可以采用二分搜索算法。具体的程序是(原程序位于
LINGO安装目录的
examples目录下,文件名为
LOOPBINSLG4,这里加上了中文注释):
MODEL:
TITLE 二分搜索; !Binary-search;
SETS:
S1: X;
ENDSETS
DATA:
KEY = 16;
! 想要找到的数
;
X = 2 7 8 11 16 20 22 32; !递增排列的正整数数列;
ENDDATA
CALC:
IB=1; !搜索位置的最小值
;
IE = @SIZE( S1); ! 搜索位置的最大值(数列中元素的个数)
;
@WHILE( IB #LE# IE:
LOC = @FLOOR((IB + IE)/2); ! 二分法;
@IFC( KEY #EQ# X(LOC):
@BREAK; !找到结果,结束循环
;
@ELSE
@IFC( KEY #LT# X( LOC):
IE = LOC-1;
@ELSE
IB = LOC+1;
);
);
);
@IFC( IB #LE# IE:
@PAUSE( '找到位置: ', LOC); ! 显示结果;
@ELSE
@STOP( ' 数列中找不到相应的数 !!!'); !程序停止运行 ;
);
ENDCALC
END
注:这里集合 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的用法非常类似。
A3子模型功能介绍
A31子模型的定义及求解
在 LINGO 90及更早的版本中,在每个 LINGO模型窗口中只允许有一个优化模型,可
以称为主模型( MAIN MODEL)。在 LINGO 100中,每个 LINGO模型窗口中除了主模型
外,用户还可以定义子模型(SUBMODEL)。子模型可以在主模型的计算段中被调用,这就
进一步增强了 LINGO的编程能力。
子模型必须包含在主模型之内,即必须位于以“ MODEL:”开头、以“ END”结束的模
块内。同一个主模型中,允许定义多个子模型,所以每个子模型本身必须命名,其基本语法
是:
@SUBMODEL mymodel:
可执行语句(约束 +目标函数);
ENDSUBMODEL
其中 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的程序格式写出,命名为文件 knapsack01lg4):
MODEL:
SETS:
ITEM: WGT, VAL, Y;
ENDSETS
DATA:
VAL = 4 6 7 9 11 12 13 15;
WGT = 3 4 6 7 9 10 11 12;
CAP = 30;
ENDDATA
MAX = OBJ;
[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变量;
END
求解本模型,可得到最优解
Y(2)=Y(4)=Y(5)=Y(6)=1(其他
Y(I)为
0),最优值
OBJ=38。
对于这样一个简单的模型,上面的程序中只有主模型。作为一种练习,我们也可以将这
个模型定义为子模型,然后在
CALC中进行求解,相应的程序为(命名为文件
knapsack02lg4)):
MODEL:
SETS:
ITEM: WGT, VAL, Y;
ENDSETS
DATA:
VAL = 4 6 7 9 11 12 13 15;
WGT = 3 4 6 7 9 10 11 12;
CAP = 30;
ENDDATA
SUBMODEL KNAPSACK: !开始定义子模型
KNAPSACK;
MAX = OBJ;
[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的定义;
CALC:
@SOLVE(KNAPSACK); ! 求解子模型
KNAPSACK;
ENDCALC
END
求解本模型,得到的结果与不用子模型时相同。
A32求背包问题的多个最好解的例子
对于上面的背包问题,最优解并不是唯一的。如果我们希望找到所有的最优解(最优值
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,命名为文件 knapsack03lg4)):
SETS:
ITEM: WGT, VAL, Y;
SOLN: RHS; ! RHS表示根据每个最优解生成“割”时的右端项;
SXI(SOLN,ITEM): COF; ! “割”的系数,即 1或-1;
ENDSETS
DATA:
K=7;
VAL = 4 6 7 9 11 12 13 15;
WGT = 3 4 6 7 9 10 11 12;
CAP = 30;
SOLN = 1K;
ENDDATA
SUBMODEL KNAPSACK:
MAX = OBJ;
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);
);
ENDSUBMODEL
CALC:
@divert('knapsacktxt'); !结果保存到文件knapsacktxt;
@FOR( SOLN(ks): ! 对ks=1,2,…,K进行循环;
KSOFAR = ks; ! KSOFAR表示当前正在计算的是第几个最优解;
@SOLVE( KNAPSACK);
RHS(ks) = 1;
!以下打印当前 (第ks个)最优解Y及对应的最优值OBJ;
@WRITE(' ',ks,' ', @FORMAT( OBJ,'30f'),':');
@writefor(ITEM(j):' ',Y(j));
@write(@newline(1));
!以下计算这个解生成的“割”的系数 ;
@FOR( ITEM(j):
@IFC( Y(j) #GT# 5:
COF(KS,j) = -1;
RHS(ks) = RHS(ks) - 1;
@ELSE
COF(KS,j) = 1;
); !分支 @IFC / @ELSE 结束;
); !循环 @FOR( ITEM(j)结束;
); !对ks的循环结束;
@divert();! 关闭文件knapsacktxt,恢复正常输出模式;
ENDCALC
注:计算段中的语句 @divert('knapsacktxt')的含义是,将此后的输出定向到文
本文件knapsacktxt(参见本附录A43节)。
运行这个程序以后,文件 knapsacktxt中将包括以下输出(其他输出略去):
1 38: 0 1 0 1 1 1 0 0
2 38: 1 1 1 1 0 1 0 0
3 38: 1 1 0 0 0 0 1 1
4 37: 1 1 0 0 0 1 0 1
5 37: 0 1 1 1 0 0 0 1
6 37: 1 1 1 1 1 0 0 0
7 37: 0 1 1 0 1 0 1 0
可见,前 7个最好的解中,最优值为 OBJ=38的解一共有 3个,而 OBJ=37的解至少有
4个(因为我们只计算了前 7个最好的解,我们暂时还无法判断 OBJ=37的解是否只有 4个),
每个解(Y的取值)也显示在结果报告中了。
A33多个子模型的例子
同一个 LINGO主模型中,允许定义多个子模型。例如,如果我们希望分别求解以下 4
个优化问题:
(1)在满足约束 x2+4y2≤
1且 x,y非负的条件下,求 x-y的最大值;
(2)在满足约束 x2+4y2≤
1且 x,y非负的条件下,求 x+y的最小值;
(3)在满足约束
x2+4y2≤
1且
x,y可取任何实数的条件下,求
x-y的最大值;
(4)在满足约束
x2+4y2≤
1且
x,y可取任何实数的条件下,求
x+y的最小值。
我们可以编写如下
LINGO程序:
MODEL:
SUBMODEL OBJ1:
MAX=X-Y;
ENDSUBMODEL
SUBMODEL OBJ2:
MIN=X+Y;
ENDSUBMODEL
SUBMODEL CON1:
x^2+4y^2<=1;
ENDSUBMODEL
SUBMODEL CON2:
@free(x);
@free(y);
ENDSUBMODEL
CALC:
@write('问题1的解:', @newline(1));
@solve(OBJ1,CON1);
@write('问题2的解:', @newline(1));
@solve(OBJ2,CON1);
@write('问题3的解:', @newline(1));
@solve(OBJ1,CON1,CON2);
@write('问题4的解:', @newline(1));
@solve(OBJ2,CON1,CON2);
ENDCALC
END
这个程序中定义了
4个子模型,其中
OBJ1和OBJ2只有目标(没有约束),而
CON1和CON2
只有约束(没有目标)。在计算段,我们将它们进行不同的组合,分别得到针对问题(
1)~(4)
的优化模型进行求解。但需要注意,每个
@solve命令所带的参数表中的子模型是先合并后求解
的,所以用户必须确保每个
@solve命令所带的参数表中的子模型合并后是合理的优化模型,例
如最多只能有一个目标函数。
运行这个后,得到的正是我们预想的结果(只列出部分相关的输出结果):
问题1的解:
Objective value: 1000000
Variable Value Reduced Cost
X 1000000 05198798E-08
Y 04925230E-08 1000000
问题2的解:
Objective value: 02403504E-09
Variable Value Reduced Cost
X 0000000 1000000
Y 0000000 1000000
问题3的解:
Objective value: 1118034
Variable Value Reduced Cost
X 08944272 0000000
Y -02236068 0000000
问题4的解:
Objective value: -1118034
Variable Value Reduced Cost
X -08944272 0000000
Y -02236068 0000000
这4个问题都是非常简单的问题,最优解和最优值很容易用解析方法计算得到,读者不
妨用解析方法计算和验证一下以上得到的解的正确性。
A34其他相关函数
1.@GEN
这个函数只能在计算段使用,功能与菜单命令
LINGO|Generate和
LINGO行命令
GEN
类似(参见本书
118页和
132页),即生成完整的模型并以代数形式显示(主要作用是可供
用户检查模型是否有误)。当不使用任何调用参数时,
“@GEN();”语句只对主模型中出现
在当前“@GEN();”语句之前的模型语句进行处理。
例如,如果在上面
A31节的文件
knapsack01lg4中增加以下的计算段:
calc:
@gen();
endcalc
则程序运行时报告窗口的显示为:
MODEL:
[_1] MAX= OBJ ;
[OBJECTIVE] OBJ - 4 Y_1 - 6 Y_2 - 7 Y_3 - 9 Y_4 - 11 Y_5 – 12
Y_6 - 13 Y_7 - 15 Y_8 = 0 ;
[CAPACITY] 3 Y_1 + 4 Y_2 + 6 Y_3 + 7 Y_4 + 9 Y_5 + 10 Y_6 + 11
Y_7 + 12 Y_8 <= 30 ;
@BIN( Y_1); @BIN( Y_2); @BIN( Y_3); @BIN( Y_4); @BIN( Y_5);
@BIN( Y_6); @BIN( Y_7); @BIN( Y_8);
END
function x=linliu(c,A,b)
[n1,n2]=size(A);
A=[A,eye(n1)];c=[-c,zeros(1,n1)];
x1=[zeros(1,n2),b'];lk=[n2+1:n1+n2];
fp=fopen('f:\lium','wt');
fprintf(fp,'初始单纯形表:\n');
while(1)
x=x1(1:n2);
s1=[lk',b,A]
c
x1
fprintf(fp,' 基 b');
for j=1:n2+n1
fprintf(fp,' x%d ',j);
end
fprintf(fp,'\n');
for i=1:n1
fprintf(fp,'%41f %41f',lk(i),b(i));
for j=1:n2+n1
fprintf(fp,'%41f ',A(i,j));
end
fprintf(fp,'\n');
end
fprintf(fp,' ');
for i=1:n1+n2
fprintf(fp,'%41f ',c(i));
end
fprintf(fp,'\n解为:\n');
for i=1:n2+n1
fprintf(fp,'x(%d)=%32f,',i,x1(i));
end
cc=[];ci=[];
for i=1:n1+n2
if c(i)<0
cc=[cc,c(i)];
ci=[ci,i];
end
end
nc=length(cc);
if nc==0
fprintf('达到最优解');
fprintf(fp,'\n达到最优解');
break
end
cliu=cc(1);
cl=ci(1);
for j=1:nc
if abs(cc(j))>abs(cliu)
cliu=cc(j);
cl=j;
end
end
cc1=[];ci1=[];
for i=1:n1
if A(i,cl)>0
cc1=[cc1,A(i,cl)];
ci1=[ci1,i];
end
end
nc1=length(cc1);
if nc1==0
fprintf('无有界最优解');
fprintf(fp,'无有界最优解');
break
end
cliu=b(ci1(1))/cc1(1);
cl1=ci1(1);
for j=1:nc1
if b(ci1(j))/cc1(j)<cliu
cliu=b(ci1(j))/cc1(j);
cl1=ci1(j);
end
end
fprintf(fp,'\nx(%d)入基,x(%d)出基\n',cl,lk(cl1));
fprintf('\nx(%d)入基,x(%d)出基\n',cl,lk(cl1));
b(cl1)=b(cl1)/A(cl1,cl);
A(cl1,:)=A(cl1,:)/A(cl1,cl);
for k=1:n1
if k~=cl1
b(k)=b(k)-b(cl1)A(k,cl);
A(k,:)=A(k,:)-A(cl1,:)A(k,cl);
end
end
c=c-c(cl)A(cl1,:);
x1(lk(cl1))=0;
lk(cl1)=cl;
for kk=1:n1
x1(lk(kk))=b(kk);
end
x=x1(1:n2);
end
fclose(fp);
检验:p31页 运筹学 清华版
format rat
c=[2 3];A=[1 2;4 0;0 4];b=[8;16;12];
x=linliu(c,A,b)
你好,答案如下所示。
没明白你的意思,Lingo它会自动变换x1,x2,p的取值,自动求得最优解
希望你能够详细查看。
如果你有不会的,你可以提问
我有时间就会帮你解答。
希望你好好学习。
每一天都过得充实。
《Lingo 18044破解版》百度网盘资源免费下载:
tcep
Lingo 18044是一款简单好用且功能强大的线性和非线性求解器,该软件内置完整的集成安装包,能够用于构建以及编辑问题的完全功能的环境,适用于各类非线性方程组的求解 *** 作,在教学、科研和工商等领域受到广泛的使用。除此之外,这款软件界面简洁, *** 作使用简单,界面允许用户将LINGO嵌入自己的应用程序中,包含用于线性模型的Primal和Dual Simplex算法,以及扩展功能选项,让模型更加容易构建、更容易理解,便于维护,帮助用户节省大量的开发时间。
model:
sets:
m /m1m6/ ;
v /v1v20/;
links(m,v):t,x,st;
pred(v,v)/v1,v2 v3,v4 v6,v7 v9,v12 v11,v12 v13,v14 v15,v16 v17,v18 v18,v20/;
endsets
@for(links: @bin(x));
@for(m(k):@for(v(i): st(k,i)>= 0));
@for(v(i): @sum(m(k): x(k,i))=1);
@for(pred(i,j):@for(m(k):@for(m(l):st(l,j)x(l,j)+(1-x(l,j))10000>=(st(k,i)+t(k,i))x(k,i))));
@for(m(k):@for(v(i):@for(v(j):x(k,i)x(k,j)(st(k,i)+t(k,i)-st(k,j))(st(k,i)+t(k,i)-st(k,j))>0)));
@for(m(k):@for(v(i):@for(v(j):x(k,i)x(k,j)(st(k,i)-st(k,j))(st(k,i)-st(k,j)-t(k,j))>0)));
min=@max(links(k,i):st(k,i)x(k,i)+t(k,i)x(k,i));
data:
t = 5 40 40 40 7 40 40 40 4 40 40 40 40 40 40 40 3 40 40 40
3 7 40 40 40 4 40 40 5 40 40 40 2 40 40 40 40 40 40 40
40 40 6 40 40 6 40 40 8 40 40 40 6 8 3 40 5 7 40 40
40 40 40 3 40 40 7 40 40 5 6 40 40 40 8 7 40 40 9 40
40 40 40 4 40 40 40 10 40 40 5 4 40 40 40 4 40 40 6 3
40 40 40 11 40 40 12 40 40 40 40 40 40 13 40 40 40 40 40 40;
enddata
end
我稍微做了些简化,有时候lingo确实要用很长时间的,应该能运行出来。
以上就是关于lindo与lingo软件有什么区别全部的内容,包括:lindo与lingo软件有什么区别、lingo软件编程,高手帮帮忙!、求lingo新功能大全、高人来。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)