文档收藏网

首页 » 正文内容 » LINGO数学规划模型

LINGO数学规划模型

时间:2023-01-26 03:36:16  热度:3°C

1、数学建模竞赛中的优化问题/数学建模 培训组 2015/4/教学目的/让大家了解数学建模中常常遇到的问题优化问题; 初步认识数学建模需要准备的算法,软件。/内容提要/1/ 优化模型的基本概念 2/ 优化问题的建模实例 3/ LINGO 软件简介/1/ 优化模型的基本概念/最优化是工程技术、经济管理、科学研究、社会生活中经常遇到的问题/ 如//优化模型和算法的重要意义/结构设计/资源分配/生产计划/运输方案/解决优化问题的手段/经验积累,主观判断/作试验,比优劣/建立数学模型,求解最优策略/最优化/ 在一定条件下,寻求使目标最大(小)的决策/优化问题: 与最大、最小、最长、最短等等有关的问题。 解

2、决最优化问题的数学方法: 运筹学 运筹学主要分支: 线性规划、非线性规划、动态规划、 图与网络分析、存贮论、排队伦、 对策论、决策论。 线性规划 1939年苏联数学家康托洛维奇发表生产组织与计划中的数学问题 1947年美国数学家乔治/丹契克、冯/诺伊曼提出线性规划的一般模型及理论/优化问题三要素:决策变量;目标函数;约束条件/优化问题的一般形式/无约束优化(没有约束)与约束优化(有约束) 可行解(只满足约束)与最优解(取到最优值)/局部最优解与整体最优解/局部最优解 (Local Optimal Solution/ 如 x1 ) 整体最优解 (Global Optimal Solution/

3、如 x2 )/优化模型的 简单分类/线性规划(LP) 目标和约束均为线性函数 非线性规划(NLP) 目标或约束中存在非线性函数 二次规划(QP) 目标为二次函数、约束为线性 整数规划(IP) 决策变量(全部或部分)为整数 整数线性规划(ILP),整数非线性规划(INLP) 纯整数规划(PIP)/ 混合整数规划(MIP) 一般整数规划,0-1(整数)规划/连续优化/离散优化/数学规划/优化模型的简单分类和求解难度/优化/线性规划/非线性规划/二次规划/连续优化/整数规划/问题求解的难度增加/例 家具生产的安排 一家具公司生产桌子和椅子,用于生产的全部劳力共计450个工时,共有4立方的木材。 每张

4、桌子要使用15个工时,0/2立方木材,售价80元。 每张椅子使用10个工时,0/05立方木材,售价45元。问为达到最大的收益,应如何安排生产?/分析: 1/ 求什么? 生产多少桌子? 生产多少椅子? 2/ 优化什么? 收益最大 3/ ***条件? 原料总量 劳力总数/x1 x2 Max f=80 x1+45 x2 0/2 x1 +0/05 x2 4 15 x1 +10 x2 450/一般线性规划的数学模型及解法: min f=cTx s/t/ Ax b A1x=b1 LB x UB Matlab求解程序 x/f=linprog(c/A/b/A1/b1/LB/UB)/一个简单的LINGO程序/例

5、直接用LINGO来解如下二次规划问题:/输入窗口如下:/LINGO简介/LINGO是一种专门用于求解数学规划问题的软件包。由于LINGO执行速度快,易于方便地输入、求解和分析数学规划问题,因此在教学、科研和工业界得到广泛应用。 LINGO主要用于求解线性规划、非线性规划、二次规划和整数规划等问题,也可以用于求解一些线性和非线性方程组及代数方程求根等。/使用入门界面/使用入门菜单命令/“File” “Edit”: match parenthesis:括号匹配,选定某括号的一边,然后点击此选项,程序会自动寻找与之相匹配的括号,如果未找到,会有弹窗提示。 paste function:用来进行函数的

6、插入。 “lingo”: solution:主要是考察结果,可以指定某一行或者某一个项目来考察结果,有文字形式也有图表形式。 range:主要是用于灵敏度分析,在这里要先更改默认设置,将price改为price and range,然后才能运行range。 generate:可以产生相对应的程序。 debug:用于调试程序,只能在程序出错时才能用。/示例: model/ sets/ number/1/6//x/ endsets data/ x = 5 1 3 4 6 10/ enddata end/程序结构集/LINGO的程序一般是一“MODEL:”开头,以“end”结束,内容包括四部分:集部

7、分,数据部分,初始部分,目标函数、约束函数部分。 集部分是LINGO模型的一个可选部分。在LINGO模型中使用集之前,必须在集部分事先定义。集部分以关键字“sets/”开始,以“endsets”结束。一个模型可以没有集部分,或有一个简单的集部分,或有多个集部分。一个集部分可以放置于模型的任何地方,但是一个集及其属性在模型约束中被引用之前必须被定义。/程序结构原始集/集包括原始集和派生集两种。 定义原始集 为了定义一个原始集,必须详细声明: 集的名字 可选,集的成员 可选,集成员的属性 定义一个原始集,用下面的语法: setname/member_list//attribute_list/ 注意

8、:用“ ”表示该部分内容可选。/示例1: model/ sets/ students/John/Linda/Tom//age/gender/ endsets End 示例2: Model/ Sets/ Month/Jan/Dec//temperature/ Endsets end/程序结构原始集/集成员列表的罗列可以有显式罗列和隐式罗列两种,显示罗列如上页所示,即将集成员全部罗列出来。 隐式罗列不必罗列出每个集成员。可采用如下语法: setname/member1/memberN// attribute_list/ 这里的member1是集的第一个成员名,memberN是集的最末一个成员名。L

9、INGO将自动产生中间的所有成员名。LINGO也接受一些特定的首成员名和末成员名,用于创建一些特殊的集。列表如下:隐式成员列表格式示例所产生集成员/程序结构原始集/也可以将集成员在数据部分定义。 示例: !集部分/ sets/ students/sex/age/ endsets !数据部分/ data/ students/sex/age= John 1 16 Jill 0 14 Rose 0 17 Mike 1 13/ Enddata 注意:开头用感叹号(!), 末尾用分号(/)表示注释,可跨多行。/请注意:数据部分的数据之间可以用空格隔开,也可以用逗号隔开。程序默认的数据是从索引1开始分配,

10、即将“students,sex,age”的第一个数据分配完了之后再分配其第二个数据。/再如下例: model/ sets/ students/John/Linda/Tom//age/gender/ Endsets Data/ Age/gender=10/1/11/0/12/1/ enddata End 运行之后便可看出数据分配的结果。/程序结构派生集/定义派生集 为了定义一个派生集,必须详细声明: 集的名字 父集的名字 可选,集成员 可选,集成员的属性 可用下面的语法定义一个派生集: setname(parent_set_list)/member_list//attribute_list/ s

11、etname是集的名字。parent_set_list是已定义的集的列表,多个时必须用逗号隔开。 如果没有指定成员列表,那么LINGO会自动创建父集成员的所有组合作为派生集的成员。 派生集的父集既可以是原始集,也可以是其它的派生集。/示例: model/ sets/ students/John/Linda/Tom//age/gender/ friends/Harry/Green// Links(students/friends)/relationship/ Endsets Data/ Relationship=8/4/9/6/6/8/ enddata End/程序结构派生集/稀疏集可以用显式表

12、示也可以用成员资格过滤器表示。 显式表示可如下示例: Links(students/friends)/John/Harry/Linda/Green//relationship/(1) 成员资格过滤器表示可如下示例: Links(students/friends)|(2) 分别插入程序中,并修改数据,可得到如下结果: (1)RELATIONSHIP( JOHN/ HARRY) 8/000000 RELATIONSHIP( LINDA/ GREEN) 6/000000 (2)RELATIONSHIP( JOHN/ GREEN) 8/000000/程序结构数据/数据部分以关键字“data/”开始,以

13、关键字“enddata”结束。在这里,可以指定集成员、集的属性。其语法如下: object_list = value_list/ 对象列(object_list)包含要指定值的属性名、要设置集成员的集名,用逗号或空格隔开。 一个对象列中至多有一个集名,而属性名可以有任意多。 如果对象列中有多个属性名,那么它们的类型必须一致。如果对象列中有一个集名,那么对象列中所有的属性的类型就是这个集。 数值列(value_list)包含要分配给对象列中的对象的值,用逗号或空格隔开。注意属性值的个数必须等于集成员的个数。看下面的例子。/示例: sets/ set1/A/B/C// X/Y/ endsets d

14、ata/ X=1/2/3/ Y=4/5/6/ Enddata 数据部分也可以如此表示,其本质是一样的: data/ X/Y=1 4 2 5 3 6/ enddata/程序结构数据/Data部分也可以用来定义标量变量,如下所示/ data/ interest_rate = /085/ enddata 也可以同时指定多个参数。 data/ interest_rate/inflation_rate = /085 /03/ enddata 在某些情况,对于模型中的某些数据并不是定值。譬如模型中有一个通货膨胀率的参数,我们想在2%至6%范围内,对不同的值求解模型,来观察模型的结果对通货膨胀的依赖有多么敏

15、感。我们把这种情况称为实时数据处理(what if analysis)。LINGO有一个特征可方便地做到这件事:在本该放数的地方输入一个问号(?)。如下所示: data/ interest_rate/inflation_rate = /085 ?/ enddata 每一次求解模型时,LINGO都会提示为参数inflation_rate输入一个值。在WINDOWS操作系统下,将会接收到一个类似右上角所示的对话框: 直接输入一个值再点击OK按钮,LINGO就会把输入的值指定给inflation_rate,然后继续求解模型。/程序结构数据/指定属性为一个值 可以在数据声明的右边输入一个值来把所有的成

16、员的该属性指定为一个值。看下面的例子。 数据部分的未知数值 有时只想为一个集的部分成员的某个属性指定值,而让其余成员的该属性保持未知,以便让LINGO去求出它们的最优值。在数据声明中输入两个相连的逗号表示该位置对应的集成员的属性值未知。两个逗号间可以有空格。 属性capacity的第2个和第3个值分别为34和20,其余的未知。/示例1: sets/ days /MO/TU/WE/TH/FR/SA/SU//needs/cost/ endsets data/ needs cost = 20 100/ Enddata 示例2: sets/ years/1/5// capacity/ endsets

17、data/ capacity = /34/20// Enddata 属性capacity的第2个和第3个值分别为34和20,其余的未知。/程序结构初始部分/初始部分是LINGO提供的另一个可选部分。在初始部分中,可以输入初始声明(initialization statement),和数据部分中的数据声明相同。对实际问题的建模时,初始部分并不起到描述模型的作用,在初始部分输入的值仅被LINGO求解器当作初始点来用,并且仅仅对非线性模型有用。和数据部分指定变量的值不同,LINGO求解器可以***改变初始部分初始化的变量的值。 一个初始部分以“init/”开始,以“endinit”结束。初始部分的初始

18、声明规则和数据部分的数据声明规则相同。也就是说,我们可以在声明的左边同时初始化多个集属性,可以把集属性初始化为一个值,可以用问号实现实时数据处理,还可以用逗号指定未知数值。 示例: init/ X/ Y = 0/ /001/ endinit Y=log(X)/ X+Y=1//注意:好的初始点会减少模型的求解时间。如左例中,若将x的初始值改为0/9,则可以明显减少迭代次数。/程序结构基本运算符/一、基本运算符 1、算术运算符 算术运算符是针对数值进行操作的。LINGO提供了5种二元运算符: 乘方 乘 除 加 减 LINGO唯一的一元算术运算符是取反函数“”。 这些运算符的优先级由高到底为: 高(

19、取反) 低 运算符的运算次序为从左到右按优先级高低来执行。运算的次序可以用圆括号“()”来改变。/程序结构逻辑运算符/2、逻辑运算符 在LINGO中,逻辑运算符主要用于集循环函数的条件表达式中,来控制在函数中哪些集成员被包含,哪些被排斥。在创建稀疏集时用在成员资格过滤器中。 LINGO具有种逻辑运算符: #not# 否定该操作数的逻辑值,not是一个一元运算符 #eq#若两个运算数相等,则为true;否则为flase #ne# 若两个运算符不相等,则为true;否则为flase #gt# 若左边的运算符严格大于右边的运算符,则为true;否则为flase #ge# 若左边的运算符大于或等于右边

20、的运算符,则为true;否则为flase #lt# 若左边的运算符严格小于右边的运算符,则为true;否则为flase #le# 若左边的运算符小于或等于右边的运算符,则为true;否则为flase #and# 仅当两个参数都为true时,结果为true;否则为flase #or# 仅当两个参数都为false时,结果为false;否则为true 这些运算符的优先级由高到低为: 高 #not# #eq# #ne# #gt# #ge# #lt# #le# 低 #and# #or#/程序结构数学算符/二、数学函数 LINGO提供了大量的标准数学函数: abs(x) 返回x的绝对值 sin(x) 返回

21、x的正弦值,x采用弧度制 cos(x) 返回x的余弦值 tan(x) 返回x的正切值 exp(x) 返回常数e的x次方 log(x) 返回x的自然对数 lgm(x) 返回x的gamma函数的自然对数 sign(x) 如果x=0时,返回不超过x的最大整数;当x0时,返回不低于x的最小整数。 smax(x1/x2/xn) 返回x1,x2,xn中的最大值 smin(x1/x2/xn) 返回x1,x2,xn中的最小值/程序结构概率函数/三、概率函数 1pbn(p/n/x):二项分布的累积分布函数。当n和(或)x不是整数时,用线性插值法进行计算。 2pcx(n/x) :***度为n的2分布的累积分布函数。

22、 3peb(a/x) :当到达负荷为a,服务系统有x个服务器且允许无穷排队时的Erlang繁忙概率。 4pel(a/x) :当到达负荷为a,服务系统有x个服务器且不允许排队时的Erlang繁忙概率。 5pfd(n/d/x) :***度为n和d的F分布的累积分布函数。 6pfs(a/x/c) :当负荷上限为a,顾客数为c,平行服务器数量为x时,有限源的Poisson服务系统的等待或返修顾客数的期望值。a是顾客数乘以平均服务时间,再除以平均返修时间。当c和(或)x不是整数时,采用线性插值进行计算。 7phg(pop/g/n/x) :超几何(Hypergeometric)分布的累积分布函数。pop表示

23、产品总数,g是正品数。从所有产品中任意取出n(npop)件。pop,g,n和x都可以是非整数,这时采用线性插值进行计算。 8ppl(a/x)Poisson :分布的线性损失函数,即返回max(0/z-x)的期望值,其中随机变量z服从均值为a的Poisson分布。 9pps(a/x) :均值为a的Poisson分布的累积分布函数。当x不是整数时,采用线性插值进行计算。 10psl(x) :单位正态线性损失函数,即返回max(0/z-x)的期望值,其中随机变量z服从标准正态分布。 11psn(x) :标准正态分布的累积分布函数 12ptd(n/x) :***度为n的t分布的累积分布函数。/程序结构q

24、rand/13qrand(seed):产生服从(0/1)区间的拟随机数。qrand只允许在模型的数据部分使用,它将用拟随机数填满集属性。通常,声明一个mn的二维表,m表示运行实验的次数,n表示每次实验所需的随机数的个数。在行内,随机数是***分布的;在行间,随机数是非常均匀的。这些随机数是用“分层取样”的方法产生的。 model/ data/ M=4/ N=2/ seed=1234567/ enddata sets/ rows/1/M// cols/1/N// table(rows/cols)/ x/ endsets data/ X=qrand(seed)/ enddata end 如果没有为函

25、数指定种子,那么LINGO将用系统时间构造种子。/程序结构rand/14rand(seed)返回0和1间的伪随机数,依赖于指定的种子。 典型用法是U(I+1)=rand(U(I)。注意如果seed不变,那么产生的随机数也不变。 示例:利用rand产生15个标准正态分布的随机数和***度为2的t分布的随机数。 model/ !产生一列正态分布和t分布的随机数/ sets/ series/1/15// u/ znorm/ zt/ endsets !第一个均匀分布随机数是任意的/ u( 1) = rand( /1234)/ !产生其余的均匀分布的随机数/ for(series( I)| I #GT#

26、1/u( I) = rand( u( I - 1) )/ for( series( I)/ !正态分布随机数/ psn( znorm( I) = u( I)/ !和***度为2的t分布随机数/ ptd( 2/ zt( I) = u( I)/ !ZNORM 和 ZT 可以是负数/ free( znorm( I)/ free( zt( I)/ )/ end/程序结构变量界定函数/四、变量界定函数 变量界定函数实现对变量取值范围的附加***,共4种: bin(x):***x为0或1 bnd(L/x/U):***LxU free(x) :取消对变量x的默认下界为0的***,即x可以取任意实数 gin(x):***

27、x为整数 在默认情况下,LINGO规定变量是非负的,也就是说下界为0,上界为+。free取消了默认的下界为0的***,使变量也可以取负值。bnd用于设定一个变量的上下界/它也可以取消默认下界为0的约束。 应用示例:/(1)若添加free函数: free(x1)/ free(x2)/ 则结果显示为:“Unbounded Solution”,即为***解。 (2)若将添加gin函数: gin(x1)/ gin(x2)/ 则结果显示:x1=0/x2=0,说明gin函数***x为整数的同时也限定x0。 (3)若将程序修改为: max=x1+x2/ x1-x2=2/ x1+2*x2=3/ 则结果显示为x1=2

28、/333333/x2=0/333333, 为全局最优解。 (4)若将添加gin函数: gin(x1)/ gin(x2)/ 则结果显示为:x1=1,x2=1,即为整数最优解。/程序结构集操作函数/五、集操作函数 LINGO提供了几个函数帮助处理集。 1in(set_name/primitive_index_1 /primitive_index_2/) 如果元素在指定集中,返回1;否则返回0。 示例: 全集为I,B是I的一个子集,C是B的补集。 sets/ I/x1/x4// B(I)/x2// C(I)|#not#in(B/ endsets 此例C(I)中的元素为x1/x3/x4。/另见此例:

29、model/ sets/ series/x1/x5// endsets y=in(series/8)/ End 返回的结果为y=0,说明集series中不包括第8个元素; 若程序为: model/ sets/ series/x1/x5// series1/z1/z4// links(series/series1)/ endsets y=in(links/1/4)/ End 返回的结果为y=1,说明在集links中存在第一行第四列的元素。/程序结构集操作函数/2index(set_name/ primitive_set_element) 该函数返回在集set_name中原始集成员primitiv

30、e_set_element的索引。如果set_name被忽略,那么LINGO将返回与primitive_set_element匹配的第一个原始集成员的索引。如果找不到,则产生一个错误。 示例1: 如何确定集成员(B/Y)属于派生集S3。 sets/ S1/A B C// S2/X Y Z// S3(S1/S2)/A X/ A Z/ B Y/ C X// endsets X=in(S3/index(S1/B)/index(S2/Y)/ 看下面的例子,表明有时为index指定集是必要的。 示例2: sets/ girls/debble/sue/alice// boys/bob/joe/sue/fr

31、ed// endsets I1=index(sue)/ I2=index(boys/sue)/ I1的值是2,I2的值是3-=。我们建议在使用index函数时最好指定集。/程序结构集操作函数/3wrap(index/limit) 该函数返回j=index-k*limit,其中k是一个整数,取适当值保证j落在区间1,limit内。该函数相当于index模limit再加1。该函数在循环、多阶段计划编制***别有用。 4size(set_name) 该函数返回集set_name的成员个数。在模型中明确给出集大小时最好使用该函数。它的使用使模型更加数据中立,集大小改变时也更易维护。/程序结构集循环函数/

32、六、集循环函数 集循环函数遍历整个集进行操作。其语法为 function(setname(set_index_list)|conditional_qualifier/expression_list)/ function相应于下面罗列的四个集循环函数之一;setname是要遍历的集;set_ index_list是集索引列表;conditional_qualifier是用来***集循环函数的范围,当集循环函数遍历集的每个成员时,LINGO都要对conditional_qualifier进行评价,若结果为真,则对该成员执行function操作,否则跳过,继续执行下一次循环。expression_li

33、st是被应用到每个集成员的表达式列表,当用的是for函数时,expression_list可以包含多个表达式,其间用分号隔开。这些表达式将被作为约束加到模型中。当使用其余的三个集循环函数时,expression_list只能有一个表达式。如果省略set_index_list,那么在expression_list中引用的所有属性的类型都是setname集。 1for 该函数用来产生对集成员的约束。基于建模语言的标量需要显式输入每个约束,不过for函数允许只输入一个约束,然后LINGO自动产生每个集成员的约束。 示例: 产生序列1/4/9/16/25 sets/ number/1/5//x/ fo

34、r(number(I)/ x(I)=I2)/ endsets/程序结构集循环函数/2sum 该函数返回遍历指定的集成员的一个表达式的和。 示例1: 求向量5,1,3,4,6,10前5个数的和。 model/ data/ N=6/ enddata sets/ number/1/N//x/ endsets data/ x = 5 1 3 4 6 10/ enddata s=sum(number(I) | I #le# 5/ x)/ End 注意:此时如果将集部分和第一个数据部分调换的话,程序无法运行,因为此时N尚未被定义。/3min和max 返回指定的集成员的一个表达式的最小值或最大值。 示例2:

35、 求向量5,1,3,4,6,10前5个数的最小值,后3个数的最大值。 model/ data/ N=6/ enddata sets/ number/1/N//x/ endsets data/ x = 5 1 3 4 6 10/ enddata minv=min(number(I) | I #le# 5/ x)/ maxv=max(number(I) | I #ge# N-2/ x)/ end/LINGO实战file函数/1file函数 该函数用从外部文件中输入数据,可以放在模型中任何地方。该函数的语法格式为file(filename)。这里filename是文件名,可以采用相对路径和绝对路径两

36、种表示方式。file函数对同一文件的两种表示方式的处理和对两个不同的文件处理是一样的,这一点必须注意。 示例:以上例来讲解file函数的用法。 注意到在上例编码中有两处涉及到数据。第一个地方是集部分的6个warehouses集成员和8个vendors集成员;第二个地方是数据部分的capacity,demand和cost数据。 为了使数据和我们的模型完全分开,我们把它们移到外部的文本文件中。修改模型代码以便于用file函数把数据从文本文件中拖到模型中来。/LINGO实战file函数/修改后(修改处代码黑体加粗)的模型代码如下: model/ sets/ warehouses/ file(1_2/

37、txt) // capacity/ vendors/ file(1_2/txt) // demand/ links(warehouses/vendors)/ cost/ volume/ Endsets min=sum(links/ cost*volume)/ for(vendors(J)/ sum(warehouses(I)/ volume(I/J)=demand(J)/ for(warehouses(I)/ sum(vendors(J)/ volume(I/J)=capacity(I)/ data/ capacity = file(1_2/txt) / demand = file(1_2/t

38、xt) / cost = file(1_2/txt) / Enddata end/LINGO实战file函数/模型的所有数据来自于1_2/txt文件。其内容如下: !warehouses成员/ WH1 WH2 WH3 WH4 WH5 WH6 !vendors成员/ V1 V2 V3 V4 V5 V6 V7 V8 !产量/ 60 55 51 43 41 52 !销量/ 35 37 22 32 41 32 43 38 !单位运输费用矩阵/ 6 2 6 7 4 2 5 9 4 9 5 3 8 5 8 2 5 2 1 9 7 4 3 3 7 6 7 3 9 2 7 1 2 3 9 5 7 2 6 5

39、5 5 2 2 8 1 4 3/LINGO实战text函数/2/text函数 该函数被用在数据部分用来把解输出至文本文件中。它可以输出集成员和集属性值。其语法为 text(filename) 这里filename是文件名,可以采用相对路径和绝对路径两种表示方式。如果忽略filename,那么数据就被输出到标准输出设备(大多数情形都是屏幕)。text函数仅能出现在模型数据部分的一条语句的左边,右边是集名(用来输出该集的所有成员名)或集属性名(用来输出该集属性的值)。 我们把用接口函数产生输出的数据声明称为输出操作。输出操作仅当求解器求解完模型后才执行,执行次序取决于其在模型中出现的先后。/LIN

40、GO实战ole函数/3ole函数 OLE是从EXCEL中引入或输出数据的接口函数,它是基于传输的OLE技术。OLE传输直接在内存中传输数据,并不借助于中间文件。当使用OLE时,LINGO先装载EXCEL,再通知EXCEL装载指定的电子数据表,最后从电子数据表中获得Ranges。为了使用OLE函数,必须有EXCEL5及其以上版本。OLE函数可在数据部分和初始部分引入数据。 OLE可以同时读集成员和集属性,集成员最好用文本格式,集属性最好用数值格式。原始集每个集成员需要一个单元(cell),而对于n元的派生集每个集成员需要n个单元,这里第一行的n个单元对应派生集的第一个集成员,第二行的n个单元对应

41、派生集的第二个集成员,依此类推。 OLE只能读一维或二维的Ranges(在单个的EXCEL工作表(sheet)中),但不能读间断的或三维的Ranges。Ranges是自左而右、自上而下来读。/LINGO实战ole函数/sets/ PRODUCT/ !产品/ MACHINE/ !机器/ WEEK/ !周/ ALLOWED(PRODUCT/MACHINE/WEEK)/x/y/ !允许组合及属性/ endsets data/ rate=0/01/ PRODUCT/MACHINE/WEEK/ALLOWED/x/y=OLE(D/IMPORT/XLS)/ OLE(D/IMPORT/XLS)=rate/ e

42、nddata/LINGO实战ole函数/代替在代码文本的数据部分显式输入形式,我们把相关数据全部放在如下电子数据表中来输入。下面是D/IMPORT/XLS的图表。 除了输入数据之外,我们也必须定义Ranges名:PRODUCT,MACHINE,WEEK,ALLOWED,x,y/ 明确的,我们需要定义如下的Ranges名: Name Range PRODUCT B3/B4 MACHINE C3/C4 WEEK D3/D5 ALLOWED B8/D10 X F8/F10 Y G8/G10 rate C13 为了在EXCEL中定义Ranges名: 按鼠标左键拖曳选择Range, 释放鼠标按钮, 选择

43、“插入|名称|定义”, 输入希望的名字, 点击“确定”按钮。/LINGO实战ole函数/LINGO实战ole函数/我们在模型的数据部分用如下代码从EXECL中引入数据: PRODUCT/MACHINE/WEEK/ALLOWED/x/y=OLE(D/IMPORT/XLS)/ OLE(D/IMPORT/XLS)=rate/ 等价的描述为 PRODUCT/MACHINE/WEEK/ALLOWED/x/y =OLE(D/IMPORT/XLS/ PRODUCT/MACHINE/WEEK/ALLOWED/x/y)/ OLE(D/IMPORT/XLS/rate)=rate/ 这一等价描述使得变量名和Rang

44、es不同亦可。/程序结构应用实例/职员时序安排模型 一项工作一周7天都需要有人(比如***工作),每天(周一至周日)所需的最少职员数为20、16、13、16、19、14和12,并要求每个职员一周连续工作5天,试求每周所需最少职员数,并给出安排。注意这里我们考虑稳定后的情况。 model/ sets/ days/mon/sun// required/start/ endsets data/ !每天所需的最少职员数/ required = 20 16 13 16 19 14 12/ enddata !最小化每周所需职员数/ min=sum(days/ start)/ for(days(J)/ sum

45、(days(I) | I #le# 5/ start(wrap(J+I+2/7) = required(J)/ end/程序结构应用实例/计算的部分结果为 Global optimal solution found at iteration/ 0 Objective value/ 22/00000 Variable Value Reduced Cost REQUIRED( MON) 20/00000 0/000000 REQUIRED( TUE) 16/00000 0/000000 REQUIRED( WED) 13/00000 0/000000 REQUIRED( THU) 16/00000

46、 0/000000 REQUIRED( FRI) 19/00000 0/000000 REQUIRED( SAT) 14/00000 0/000000 REQUIRED( SUN) 12/00000 0/000000 START( MON) 8/000000 0/000000 START( TUE) 2/000000 0/000000 START( WED) 0/000000 0/3333333 START( THU) 6/000000 0/000000 START( FRI) 3/000000 0/000000 START( SAT) 3/000000 0/000000 START( SUN

47、) 0/000000 0/000000 从而解决方案是:每周最少需要22个职员,周一安排8人,周二安排2人,周三无需安排人,周四安排6人,周五和周六都安排3人,周日无需安排人。/程序结构辅助函数/七、辅助函数 1if(logical_condition/true_result/false_result) if函数将评价一个逻辑表达式logical_condition,如果为真,返回true_ result,否则返回false_result。 示例1:求解最优化问题 其LINGO代码如下: model/ min=fx+fy/ fx=if(x #gt# 0/ 100/0)+2*x/ fy=if(y

48、 #gt# 0/60/0)+3*y/ x+y=30/ end 2warn(text/logical_condition) 如果逻辑条件logical_condition为真,则产生一个内容为text的信息框。 示例2: model/ x=1/ warn(x是正数/x #gt# 0)/ end/LINGO的语法规定:/(1) 求目标函数的最大值和最小值分别用MAX= 或MIN= 来表示;/(2) 每个语句必须以分号“/”结束,每行可以有多个语句,语句可以跨行;/(3) 变量名称必须以字母(A-Z)开头,由字母、数字(0-9)和下划线“_”组成,长度不超过32个字符,不区分大小写;/(4) 可以给

49、语句加上标号,例如OBJ MAX= ;/(5) 以“!”开头,以“/”结束的语句是注释语句;/(6) 如果对变量的取值范围没有作特殊说明,则默认所有决策变量都非负;/(7) LINGO模型以语句“MODEL/”开头,以“END”结束,对于比较简单的模型,这两句可以省略;/LINGO的基本用法的几点注意事项/LINGO中不区分大小写字母; 8个字符变量和行名 32个字符/且必须以字母开头。 LINGO中假定所有变量非负(除非用限定变量取值范围的函数free或sub或slb另行说明)。 变量可以放在约束条件的右端(同时数字也可放在约束条件的左端)。但为了提高LINGO求解时的效率,应尽可能采用线性

50、表达式定义目标和约束(如果可能的话)。 语句是LINGO的基本单位/每个语句都以分号结尾,编写程序时应注意模型的可读性。例如:一行只写一个语句,按照语句之间的嵌套关系对语句安排适当的缩进,增强层次感。 以感叹号开始的是说明语句(说明语句也需要以分号结束))。/LINGO总是根据“MAX=”或“MIN=”寻找目标函数,而除注释语句和TITLE语句外的其他语句都是约束条件,因此语句的顺序并不重要 。 限定变量取整数值的语句为“GIN(X1)”和“GIN(X2)”,不可以写成“GIN(2)”,否则LINGO将把这个模型看成没有整数变量。 LINGO中函数一律需要以“”开头,其中整型变量函数(BIN、

51、GIN)和上下界限定函数(FREE、SUB、SLB)与LINDO中的命令类似。而且0-1变量函数是BIN函数。/LINGO的基本用法的几点注意事项/工具栏/File|Open (F3) 打开文件/File|Print (F7) 打印文件/Edit|Copy (Ctrl+C) 复制/Edit|Undo (Ctrl+Z) 取消操作/Edit|Find (Ctrl+F) 查找/LINGO|Solution (Alt+O)显示解答/Edit|Match Parenthesis (Ctrl+P) 匹配括号/LINGO|Options (Ctrl+I) 选项设置/Window|Close All (Alt

52、+X) 关闭所有窗口/Help|Contents (F1) 在线帮助/File|New (F2) 新建文件/File|Save (F4) 保存文件/Edit|Cut (Ctrl+X) 剪切/Edit|Paste (Ctrl+V) 粘贴/Edit|Redo (Ctrl+Y) 恢复操作/Edit | Go To Line (Ctrl+T) 定位某行/LINGO|Solve (Ctrl+S) 求解模型/LINGO|Picture (Ctrl+K) 模型图示/Window|Send to Back (Ctrl+B) 窗口后置/Window|Tile (Alt+T) 平铺窗口/上下文相关的帮助/输出特殊

53、格式文件/MPS格式文件/MPI格式文件/IBM开发的数学规划文件 标准格式/LINDO公司制定的数学规划 文件格式/用户基本信息/该命令弹出一个对话框/要求 输入用户名和密码(这些信息 在用ODBC函数访问数据库要用到)/选择性粘贴/该命令把Window剪贴板中的内容插入到光标所在位置//插入新对象/链接/修改模型内插入对象的链接性质//对象的性质/在模型中选择一个链接或嵌入对象/用本命令可以查看和修改这个对象的属性//灵敏度分析/该命令产生当前模型的灵敏度分析报告//(1)最优解保持不变的情况下/目标 函数的系数变化范围/ (2)在影子价格和缩减成本系数都 不变的前提下/约束条件右边的 常

54、数变化范围//例/ 做下列模型的灵敏度分析/MAX=200*X1+300*X2/ X1=100/ X2=120/ X1+2*X2=160//注//灵敏性分析耗费相当多的求解时间,因此当速度很关键时/就没有必要激活它/生成模型的展开形式/为当前模型生成一个用代数表达式表示的完整形式,即LINGO将所有基于***的表达式(目标函数和约束条件)扩展成为等价的完全展开的普通数学表达式模型//生成图形/由模型生成图形,以矩阵形式显示模型的系数//调试/模型统计资料/调试结果,找到充分行(Sufficient Rows)和必要行(Necessary Rows)//查看(以为本方式显示模型内容)/命令行窗口/

55、主要是为用户交互地测试命令脚本而设计/(通常不用)/状态窗口/变量/约束/非零系数/内存使用量/已运行时间/求解器状态/扩展求解器状态/LINGO 软件主要具有两大优点/内置建模语言,允许以简练、直观的方式描述较大规模的优化问题,所需的数据可以以一定格式保存在***的文件中。/可用于求解非线性规划问题,包括非线性整数规划问题//LINGO的文件类型/2/ 优化问题的建模实例/企业生产计划/1 奶制品的生产与销售/空间层次/工厂级:根据外部需求和内部设备、人力、原料等条件,以最大利润为目标制订产品生产计划;/车间级:根据生产计划、工艺流程、资源约束及费用参数等,以最小成本为目标制订生产批量计划。/

56、时间层次/若短时间内外部需求和内部资源等不随时间变化,可制订单阶段生产计划,否则应制订多阶段生产计划。/例1 加工奶制品的生产计划/50桶牛奶/时间480小时/至多加工100公斤A1/制订生产计划,使每天获利最大/35元可买到1桶牛奶,买吗?若买,每天最多买多少?/可聘用临时工人,付出的工资最多是每小时几元?/A1的获利增加到 30元/公斤,应否改变生产计划?/每天:/x1桶牛奶生产A1/x2桶牛奶生产A2/获利 243x1/获利 164 x2/原料供应/劳动时间/加工能力/决策变量/目标函数/每天获利/约束条件/非负约束/线性规划模型(LP)/时间480小时/至多加工100公斤A1/模型分析

57、与假设/比例性/可加性/连续性/xi对目标函数的“贡献”与xi取值成正比/xi对约束条件的“贡献”与xi取值成正比/xi对目标函数的“贡献”与xj取值无关/xi对约束条件的“贡献”与xj取值无关/xi取值连续/A1/A2每公斤的获利是与各自产量无关的常数/每桶牛奶加工出A1/A2的数量和时间是与各自产量无关的常数/A1/A2每公斤的获利是与相互产量无关的常数/每桶牛奶加工出A1/A2的数量和时间是与相互产量无关的常数/加工A1/A2的牛奶桶数是实数/线性规划模型/模型求解/图解法/约束条件/目标函数/z=c (常数) 等值线/在B(20/30)点得到最优解/目标函数和约束条件是线性函数/可行域

58、为直线段围成的凸多边形/目标函数的等值线为直线/最优解一定在凸多边形的某个顶点取得。/单纯形法/单纯形法/运行状态窗口/Variables(变量数量): 变量总数(Total)、 非线性变量数(Nonlinear)、 整数变量数(Integer)。/Constraints(约束数量): 约束总数(Total)、 非线性约束个数(Nonlinear)。/Nonzeros(非零系数数量): 总数(Total)、 非线性项系数个数(Nonlinear)。/Generator Memory Used (K) (内存使用量)/Elapsed Runtime (hh/mm/ss) (求解花费的时间)/求解器(求解程序)状态框/当前模型的类型 /LP,QP,ILP,IQP,PILP, PIQP,NLP,INLP,PINLP (以I开头表示IP,以PI开头表示PIP)/当前解

温馨提示:
1. 文档收藏网仅展示《LINGO数学规划模型》的部分公开内容,版权归原著者或相关公司所有。
2. 文档内容来源于互联网免费公开的渠道,若文档所含内容侵犯了您的版权或隐私,请通知我们立即删除。
3. 当前页面地址:https://doc.bogoing.com/doc/dfc1dc2bdedc9a26.html 复制内容请保留相关链接。