优化建模与LINGO第04章.ppt
优化建模与LINDO/LINGO软件,原书相关信息谢金星,薛毅编著,清华大学出版社,2005年7月第1版.http:/,第 4 章 LINGO软件与外部文件的接口,通过文件输入输出数据,通过文件输入输出数据可以将LINGO程序和程序处理的数据分离开来。“程序和数据的分离”是结构化程序设计、面向对象编程的基本要求。实际问题通常需要处理大规模的实际数据,而这些数据通常都是在其它应用系统中生成的,或者已经存放在其它应用系统中的某个文件或数据库中。LINGO计算的结果需要以文件方式提供给其它应用系统使用。,通过WINDOWS剪贴板传递数据 通过文本文件传递数据 通过电子表格文件传递数据LINGO命令脚本文件,内容提要,1.通过WINDOWS剪贴板传递数据,粘贴命令(Edit|Paste)特殊粘贴命令(Edit|Paste Special),粘贴命令(Edit|Paste),将WORD文件或其他外部文件中的数据拷贝到Windows剪贴板在LINGO程序中直接粘贴到需要的地方,步骤:,注意:,粘贴的数据保持了WORD表格的风格,且LINGO能够正常识别甚至编辑其字体等。由于LINGO对集合的属性是按列赋值的,所以在外部文件中的数据与实际需要复制的数据可能发生行列颠倒的情况,需进行调整。类似的方法也可以将LINGO程序中的数据复制到其他外部文件中。,特殊粘贴命令(Edit|Paste Special),选择特殊粘贴命令,则会出现“选择性粘贴”对话框,请你选择粘贴格式。,粘贴一个WORD对象,双击时可以打开WORD进行编辑,将剪贴板中的内容以图形格式插入到LINGO模型中,效果与直接使用“Ctrl+V”的效果是一样的,粘贴的是格式化的文本,选择了“显示为图标”选项,则只显示一个“文档”图标而不显示剪贴板中的具体内容;,选择“粘贴链接”时会建立与原文件的链接,当数据文件改变时,LINGO中这部分的内容也会随之改变,粘贴纯文本文件,不保留文本的格式信息,特殊粘贴命令(Edit|Paste Special),在这种粘贴方式中,只有选择“多信息文本(RTF)”或“未格式化文本”,才能正确输入数据;其他两种方式:WORD文档和图形,LINGO在运行时完全将它们忽略掉;选择“粘贴链接”建立链接关系后,可以随时用“EDIT|LINKS”命令修改这个连接的属性。如果数据不是放在WORD文件,而是EXCEL电子表格文件或者其他应用程序的文件,操作和结果与上面介绍的过程完全类似。,注意:,2.通过文本文件传递数据,通过文本文件输入数据 FILE(filename)通过文本文件输出数据 TEXT(filename),通过文本文件输入数据,FILE函数通常可以在集合段和数据段使用,但不允许嵌套使用。调用格式:FILE(filename)filename为存放数据的文件名(可以包含完整的路径名,或表示在当前目录下寻找这个文件)数据文件中记录之间必须用“”分开,例:,MODEL:SETS:MYSET/FILE(myfile.ldt)/:FILE(myfile.ldt);ENDSETSMIN=SUM(MYSET(I):ORDERED(I)*COST(I);FOR(MYSET(I):ORDERED(I)NEED(I);ORDERED(I)SUPPLY(I);DATA:COST=FILE(myfile.ldt);NEED=FILE(myfile.ldt);SUPPLY=FILE(myfile.ldt);ENDDATAEND,数据文件myfile.ldt的内容:,Lingo程序exam0402.LG4:,每调用一次FILE(myfile.ldt)就输入一个数据记录,Seattle,Detroit,Chicago,DenverCOST,NEED,SUPPLY,ORDERED12,28,15,201600,1800,1200,10001700,1900,1300,1100,如输入数据发生变化,则只要修改数据文件myfile.ldt中的内容,程序不变,实现数据与程序分离,通过文本文件输出数据,TEXT函数通常只在数据段使用 调用格式:TEXT(filename)它用于数据段中将解答结果送到文本文件filename中,当省略filename时,结果送到标准的输出设备(通常就是屏幕)Filename可以使用相对路径或绝对路径,若文件已经存在,则覆盖原文件,例:,TEXT(exam0403.txt)=write(4*,Value,12*,Dual,13*,Decrease,8*,Increase,newline(2);TEXT(exam0403.txt)=write(Variables:,newline(2);TEXT(exam0403.txt)=Ordered,DUAL(Ordered),RANGED(ordered),RANGEU(ordered);TEXT(exam0403.txt)=write(newline(1),NEED Constraints:,newline(2);TEXT(exam0403.txt)=CON1,DUAL(CON1),RANGED(CON1),RANGEU(CON1);TEXT(exam0403.txt)=write(newline(1),SUPPLY Constraints:,newline(2);TEXT(exam0403.txt)=CON2,DUAL(CON2),RANGED(CON2),RANGEU(CON2);TEXT(exam0403.txt)=write(newline(1),Final status for exam0403:,status(),if(status(),(Maybe Not Global Optimal),(Global Optimal),newline(1);,Lingo程序exam0403.LG4(部分):,输出表头,并换行,输出变量Ordered的最优解、对偶价格、敏感性分析,根据status()的值输出是否全局最优,函数RANGED,RANGEU输出敏感性分析信息,但LINGO的缺省设置是不进行敏感性分析的,因此,必须进行设置,这个选项在OPTIONS|General Solver,3.通过电子表格文件传递数据,在LINGO中使用电子表格文件的数据 将LINGO模型嵌入、链接到电子表格文件中,在LINGO中使用电子表格文件的数据,实际应用中,可能有大量数据是存放在各种电子表格中的(如EXCEL表格)。LINGO系统与EXCEL文件传递数据的函数的一般用法是通过OLE函数。调用格式:OLE(spreadsheet_file,range_name_list)输入数据:“属性(或变量)=OLE(.)”输出数据:“OLE(.)=属性(或变量)”,电子表格文件名,数据的单元范围,例:,首先,建立相应的EXCEL数据文件 mydata.xls,并定义相应的数据单元,数据单元定义方法:选择EXCEL的菜单命令“插入|名称|定义”,才谈出对话框中输入单元名称,MODEL:SETS:MYSET/OLE(mydata.xls,CITIES)/:COST,NEED,SUPPLY,ORDERED;ENDSETSMIN=SUM(MYSET(I):ORDERED(I)*COST(I);FOR(MYSET(I):CON1 ORDERED(I)NEED(I);CON2 ORDERED(I)SUPPLY(I);DATA:COST,NEED,SUPPLY=OLE(mydata.xls);OLE(mydata.xls,SOLUTION)=ORDERED;ENDDATAEND,Lingo程序exam0404.LG4:,从文件mydata.xls的CITIES所指示的单元中取出数据,作为集合MYSET的元素。,从文件mydata.xls中相应单元给COST,NEED,SUPPLY赋值。没有指定单元时,从与变量名相同的单元中赋值,将ORDERED的值输出赋给mydata.xls文件中由SOLUTION指定的单元格,输出总结报告,Export Summary Report-Transfer Method:OLE BASED Workbook:mydata.xls Ranges Specified:1 SOLUTION Ranges Found:1 Range Size Mismatches:0 Values Transferred:4,采用OLE方式传输数据;EXCEL文件为mydata.xls;指定的接收单元范围为SOLUTION;在mydata.xls正好找到一个名为SOLUTION的域名;不匹配的单元数为0;传输了4个数值。,LINGO与数据库交换数据,不同的数据库有不同的数据库管理系统(DBMS:DataBase Management System)WINDOWS环境下可以用ODBC(Open DataBase Connectivity)进行连接 LINGO中可以使用函数ODBC,格式为:,ODBC(data_source,table_name,col_1,col_2.)其中data_source是数据库名,table_name是数据表名,col_1,col_2,.是数据列名(数据域名)。,将LINGO模型嵌入、链接到电子表格文件中,打开EXCEL文件菜单命令“插入|对象”选择“新建|LINDO Document”,建立一个空的LINGO文件对象,且在EXCEL中出现LINGO菜单输入LINGO 程序内容,即可在EXCEL中运行LINGO程序,虽然在EXCEL文件中嵌入了LINGO对象,但需要人工干预才能运行这个对象。若希望在EXCEL中自动运行一个LINGO程序,则需要将LINGO程序用命令脚本进行描述,并需要用EXCEL的宏命令进行调用。,4.LINGO命令脚本文件,LINGO命令脚本文件是一个普通的文本文件,但是文件中的内容是由一系列LINGO命令构成的命令序列。使用命令脚本文件,你可以同时运行一系列的LINGO批处理命令。命令脚本文件可用任何文本编辑器生成,也可以用LINGO新建文件(*.ltf文件)进行编辑。,例如:一家快餐公司有多家分店,每家分店都要确定每天所雇用的服务员的人数。每家分店的优化模型的结构本质上是一样的,只是具体数据不同。我们可以把每个分店的人员需求数据存入各自的一个数据文件中,并建立一个统一的程序(命令脚本文件)逐个调用这些数据进行求解,输出结果。,分店AAA周一到周四每天至少需要50人,周五至少80人,周六和周日至少90人;分店BBB周一到周四每天至少需要80人,周五至少120人,周六和周日至少140人;分店CCC周一到周四每天至少需要90人,周五至少120人,周六和周日至少150人。,3家分店(分别表示为AAA,BBB,CCC),!开始输入关于员工聘用的优化模型MODEL:SETS:DAYS/MON TUE WED THU FRI SAT SUN/:REQUIRED,START;ENDSETSDATA:REQUIRED=FILE(AAA.LDT);!读入需求数据REQUIRED;TEXT(F:lindolindo书ch04result/AAA.TXT)=WRITE(员 工 聘 用 计 划 表,NEWLINE(1);TEXT(F:lindolindo书ch04result/AAA.TXT)=WRITE(-,NEWLINE(1);TEXT(F:lindolindo书ch04result/AAA.TXT)=WRITEFOR(DAYS(I):DAYS(I),(星期,I,):,4*,FORMAT(START(I),3.0f),NEWLINE(1);TEXT(F:lindolindo书ch04result/AAA.TXT)=WRITE(-,NEWLINE(1);TEXT(F:lindolindo书ch04result/AAA.TXT)=WRITE(6*,合计:,6*,SUM(DAYS:START),NEWLINE(1);ENDDATAMIN=SUM(DAYS(I):START(I);FOR(DAYS(J):SUM(DAYS(I)|I#LE#5:START(WRAP(J-I+1,7)=REQUIRED(J);FOR(DAYS:GIN(START);ENDGO!下面求解分店AAA的决策问题 ALTER ALL AAABBB!下面转向求解分店BBB的决策问题GOALTER ALL BBBCCC!下面转向求解分店CCC的决策问题GOSET TERSEO 0!恢复参数(恢复以正常方式显示解答结果),命令之间的说明语句不需要以“;”结束;但在程序段中(即位于“MODEL:”和“END”之间)的说明语句必须以“;”结束,否则会因为读入的程序不符合LINGO语法而出错。,输出结果在三个文件“AAA.TXT”、“BBB.TXT”、“CCC.TXT”中,例如,AAA.TXT中的内容是:员 工 聘 用 计 划 表-MON(星期1):0TUE(星期2):4WED(星期3):40THU(星期4):3FRI(星期5):40SAT(星期6):3SUN(星期7):4-合计:94,建立好上面的文件后,用“File|Take Commands”命令打开这个脚本文件,运行时命令窗口将显示一些脚本文件输入和求解模型相关的信息,自己练习,或课上布置,布置作业内容,Thank you very much!,