您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 其它行业文档 > LINGO基本语法和编程
•数学建模课程综合设计王丹理学院数学与系统科学系2016年夏季•LINGO程序的基本结构•LINGO中的集合•LINGO中的简化函数•LINGO中的运算符LINGO程序基本结构1:模型以Model以END结束Model:Title“Example”……END注:在程序中若没有Model和End也能执行,但建议写完整标准的程序LINGO程序基本结构2:五段(Section)结构Model:Title“Example”集合段数据段初始段计算段目标和约束段END五段结构中目标和约束段一般是不可少的,集合段用得比较多,数据段次之,初始段和计算段不一定有。这些段的顺序可调换。LINGO模型的基本结构(1)集合段(SETS):以“SETS:”开始,“ENDSETS”结束,定义必要的集合变量(SET)及其元素(MEMBER,含义类似于数组的下标)和属性(ATTRIBUTE,含义类似于数组)。Sets:Car/12/:lcar;Box/1..7/:hd,zl,js;SL(Car,Box):x;TRI(Car,SL):trx;ENDSETS(2)数据段(DATA):以“DATA:”开始,“ENDDATA”结束,对集合的属性(数组)输入必要的常数数据。格式为:“attribute(属性)=value_list(常数列表);”常数列表(value_list)中数据之间可以用逗号“,”分开,也可以用空格分开(回车等价于一个空格),如:Data:hd=48.75261.37248.75264;zl=200030001000500400020001000;js=8796648;ENDDATA(3)初始段(INIT):以“INIT:”开始,“ENDINIT”结束,对集合的属性(数组)定义初值(因为求解算法一般是迭代算法,所以用户如果能给出一个比较好的迭代初值,对提高算法的计算效果是有益的)。如果有一个接近最优解的初值,对LINGO求解模型是有帮助的。定义初值的格式为:“attribute(属性)=value_list(常数列表);”这与数据段中的用法是类似的。Init:x=11111111111111;Endinit(4)计算段(CALC):以“CALC:”开始,“ENDCALC”结束,对一些原始数据进行计算处理。在实际问题中,输入的数据通常是原始数据,不一定能在模型中直接使用,可以在这个段对这些原始数据进行一定的“预处理”,得到模型中真正需要的数据。例如Calc:TotalWeight=@sum(Box(i):zl(i)*js(i));EndCalc注意计算段只能对常量进行计算,不能对需要通过解优化程序求解出来的变量进行计算。(5)目标与约束段:目标函数、约束条件等,没有段的开始和结束标记,因此实际上就是除其它四个段(都有明确的段标记)外的LINGO模型。这是Lingo程序最重要的部分。MAX=@sum(Car(i):@sum(Box(j):hd(j)/100*x(i,j)));@for(Box(j):x(1,j)+x(2,j)=js(j));@for(Car(i):@sum(Box(j):zl(j)/1000*x(i,j))=40);@for(Car(i):@sum(Box(j):hd(j)/100*x(i,j))=10.2);@for(Car(i):@sum(Box(j)|j#GE#5:hd(j)/100*x(i,j))=3.027);@for(SL(i,j):x(i,j)=0);@for(SL(i,j):@GIN(x(i,j)));一个简单的LINGO程序例直接用LINGO来解如下二次规划问题:40,322100..123.02779821212122212121xxxxxxtsxxxxxxMax输入窗口如下:输出结果:运行菜单命令“LINGO|Solve”最优整数解X=(35.37,64.63)最大利润=11077.87输出结果备注:通过菜单“WINDOW|StatusWindow”看到状态窗口,可看到最佳目标值“BestObj”与问题的上界“ObjBound”已经是一样的,当前解的最大利润与这两个值非常接近,是计算误差引起的。LINGO是将它作为NLP(非线性规划)来求解,找到的是全局最优解。一个复杂一些的LINGO程序例直接用LINGO来解如下线性规划问题:程序如下:集合段数据段初始段计算段目标函数约束条件输出结果LINGO是将它作为ILP(整数线性规划)来求解,找到全局最优解。LINGO程序注意的几个问题LINGO的基本用法的几点注意事项•LINGO中不区分大小写字母;变量和行名可以超过8个字符,但不能超过32个字符,且必须以字母开头。•用LINGO解优化模型时已假定所有变量非负(除非用限定变量取值范围的函数@free或@sub或@slb另行说明)。•变量可以放在约束条件的右端(同时数字也可放在约束条件的左端)。但为了提高LINGO求解时的效率,应尽可能采用线性表达式定义目标和约束(如果可能的话)。•语句是组成LINGO模型的基本单位,每个语句都以分号结尾,编写程序时应注意模型的可读性。例如:一行只写一个语句,按照语句之间的嵌套关系对语句安排适当的缩进,增强层次感。•以感叹号开始的是说明语句(说明语句也需要以分号结束))。集合的基本用法理解LINGO建模语言最重要的是理解集合(Set)及其属性(Attribute)的概念。例SAILCO公司需要决定下四个季度的帆船生产量。下四个季度的帆船需求量分别是40条,60条,75条,25条,这些需求必须按时满足。每个季度正常的生产能力是40条帆船,每条船的生产费用为400美元。如果加班生产,每条船的生产费用为450美元。每个季度末,每条船的库存费用为20美元。假定生产提前期为0,初始库存为10条船。如何安排生产可使总费用最小?用DEM,RP,OP,INV分别表示需求量、正常生产的产量、加班生产的产量、库存量,则DEM,RP,OP,INV对每个季度都应该有一个对应的值,也就说他们都应该是一个由4个元素组成的数组,其中DEM是已知的,而RP,OP,INV是未知数。问题的模型(可以看出是LP模型)目标函数是所有费用的和4,3,2,1)}(20)(450)(400{MINIIINVIOPIRP约束条件主要有三个:1)能力限制:4,3,2,1,40)(RPII2)产品数量的平衡方程:4,3,2,1),()()()1()(IIDEMIOPIRPIINVIINV10)0(INV3)变量的非负约束由于LINGO中没有数组,只能对每个季度分别定义变量,如正常产量就要有RP1,RP2,RP3,RP44个变量等。写起来就比较麻烦,尤其是更多(如1000个季度)的时候。记四个季度组成的集合QUARTERS={1,2,3,4},它们就是上面数组的下标集合,而数组DEM,RP,OP,INV对集合QUARTERS中的每个元素1,2,3,4分别对应于一个值。LINGO正是充分利用了这种数组及其下标的关系,引入了“集合”及其“属性”的概念,把QUARTERS={1,2,3,4}称为集合,把DEM,RP,OP,INV称为该集合的属性(即定义在该集合上的属性)。•QUARTERS集合的属性•DEM•RP•OP•INV•QUARTERS集合•2•3•4•1集合及其属性集合元素及集合的属性确定的所有变量集合QUARTERS的元素1234定义在集合QUARTERS上的属性DEMDEM(1)DEM(2)DEM(3)DEM(4)RPRP(1)RP(2)RP(3)RP(4)OPOP(1)OP(2)OP(3)OP(4)INVINV(1)INV(2)INV(3)INV(4)LINGO中定义集合及其属性LP模型在LINGO中的一个典型输入方式以“MODEL:”开始以“END”结束集合定义部分从(“SETS:”到“ENDSETS”):定义集合及其属性集合定义部分从(“DATA:”到“ENDDATA”)给出优化目标和约束基本集合与派生集合例建筑工地的位置(用平面坐标a,b表示,距离单位:公里)及水泥日用量d(吨)下表给出。有两个临时料场位于P(5,1),Q(2,7),日储量各有20吨。从A,B两料场分别向各工地运送多少吨水泥,使总的吨公里数最小。两个新的料场应建在何处,节省的吨公里数有多大?123456a1.258.750.55.7537.25b1.250.754.7556.57.75d3547611建立模型记工地的位置为,水泥日用量为;料场位置为,日储量为;从料场向工地的运送量为。),(iiba6,1,idi),(jjyx2,1,jejjiijc2622112161MIN1s.t.,1,2,,62,1,23ijjijijiijijijjifcxaybcdicej使用现有临时料场时,决策变量只有(非负),所以这是LP模型;当为新建料场选址时决策变量为和,由于目标函数对是非线性的,所以在新建料场时是NLP模型。先解NLP模型,而把现有临时料场的位置作为初始解告诉LINGO。ijcijcjjyx,fjjyx,本例中集合的概念利用集合的概念,可以定义需求点DEMAND和供应点SUPPLY两个集合,分别有6个和2个元素(下标)。但决策变量(运送量)与集合DEMAND和集合SUPPLY都有关系的。该如何定义这样的属性?ijc集合的属性相当于以集合的元素为下标的数组。这里的相当于二维数组。它的两个下标分别来自集合DEMAND和SUPPLY,因此可以定义一个由二元对组成的新的集合,然后将定义成这个新集合的属性。ijcijc输入程序定义了三个集合,其中LINK在前两个集合DEMAND和SUPPLY的基础上定义表示集合LINK中的元素就是集合DEMAND和SUPPLY的元素组合成的有序二元组,从数学上看LINK是DEMAND和SUPPLY的笛卡儿积,也就是说LINK={(S,T)|SDEMAND,TSUPPLY}因此,其属性C也就是一个6*2的矩阵(或者说是含有12个元素的二维数组)。LINGO建模语言也称为矩阵生成器(MATRIXGENERATOR)。类似DEMAND和SUPPLY直接把元素列举出来的集合,称为基本集合(primaryset),而把LINK这种基于其它集合而派生出来的二维或多维集合称为派生集合(derivedset)。由于是DEMAND和SUPPLY生成了派生集合LINK,所以DEMAND和SUPPLY称为LINK的父集合。输入程序初始段INGO对数据是按列赋值的语句的实际赋值顺序是X=(5,2),Y=(1,7),而不是X=(5,1),Y=(2,7)等价写法:“X=5,2;Y=1,7;”同理,数据段中对常数数组A,B的赋值语句也可以写成A,B=1.251.258.750.750.54.755.75536.57.257.75;输入程序定义目标和约束,与前例的方法是类似(这里包含了派生集合),请注意这里用到了集合函数@SUM和@FOR的用法。由于新建料场的位置理论上讲可以是任意的,所以在约束的最后(模型的“END”语句上面的一行)用@free函数取消了变量X、Y的非负限制在程序开头用TITLE语句对这个模型取了一个标题“LOCATIONPROBLEM;并且对目标行([OBJ])和两类约束(DEMAND_CON、SUPPLY_CON)分别进行了命名(请特别注意这里约束命名的特点)。解答:运行菜单命令“LINGO|Solve”局部最优解X(1)=7.249997,X(2)=5.695940,Y(1)=7.749998,Y(2)=4.928524,C(略),最小运量=89.8835(吨公里)。问题:最小运量89.8835是不是全局最优是用“LINGO|Options”菜单命令打开选项对话框,在“GlobalSolver”选项卡上选择“UseGlobalSolver”,激活全局最优求解程序。问题:最小运量89.8835是不是
本文标题:LINGO基本语法和编程
链接地址:https://www.777doc.com/doc-4472942 .html