附录三运筹学的LNGO软件 §1简介 LINGO软件有多种版本,如LINDO,GINO和LINGO(包括LINGO NL)软件. LNDO是一种专门用于求解数学规划问题的优化计算软件包,版权现在由美国 LINDO系统公司(Lindo System Inc.)所拥有。LINDO软件包的特点是程序执行速度 快,初 、修改、求解和分析 就 (优化问题),因此LINDO在 应用。有关该软件的发行版木,发行价格和其 还提供部分 5点http/Www.lndo,com LNDO由美国芝加哥大学的Lim e数授首先开发,随后又推出了GNO LNGO,LINGO NL(仅称LNGO2)what's best!等优化软件,现在 般仍用LNDO 作为这些软件的统称。各组件的功能各有侧重,分别简要介绍如下: (i)LNDO是Linear Interactive and Discrete Optimizer字首的缩写形式,可以用米 求解线性规划(LP一Linear Programming),整数规划(IP一Integer Programming)和二次规 划QP-Quadratic Programming)问题。 (ii)GNO是General Interactive Optimizer字首的缩写形式,可以用来求解非线 量的概率E 数) 非线性知整数想问题 ,非线性和整数规划问题 LNDO和GNO不同的是,LNGO和LINGO NL (LINGO2)包含 内置的建模 语言,允许以简练,直观的方式描述较大规模的优化问题,模型中所需的数据可以以 定格式保存在独立的文件中。 (v)“what's best!”组件主要用于数据文件是由电子表格软件(如LUTOSI-2-3 和MS OFFICE等)生成的情形。 LNDO软1 包有多种 发本,但其软件内核和使用方法基本上是类似的。下面介绍 LNGO组件的基本使用方法。 S2LING0快速入门 始运行LINGO系统时,会得到一个窗 外层是主框架窗口, 包含了所有菜单命令和工 有的窗口将被包含在主 窗口之下,在主窗口内的标题为LINGO Mode-LCO1的窗口是LINGO的默认模型窗 口,建立的模型都都要在该窗口内编码实现。下面举两个例子。 例2.1如何在LING0中求解如下的LP问题: min 2x+3x2 x+52350 s.t. x≥100 2x.+x,≤600 x,20 由于LG0中已假所有的支是是负的,所以丰负约不多入计机中
-314- 附录三 运筹学的 LINGO 软件 § 1 简介 LINGO 软件有多种版本,如 LINDO,GINO 和 LINGO(包括 LINGO NL)软件。 LINDO 是一种专门用于求解数学规划问题的优化计算软件包,版权现在由美国 LINDO 系统公司(Lindo System Inc.)所拥有。LINDO 软件包的特点是程序执行速度 快,易于方便地输入、修改、求解和分析一个数学规划(优化问题),因此 LINDO 在 教学,科研和工业界得到广泛应用。有关该软件的发行版本,发行价格和其它最新信息 都可以从 LINDO 系统公司的 INTERNET 网络站点 http://www.lindo.com 获取,该站点 还提供部分 LINDO 软件的演示版本或测试版本。 LINDO 由美国芝加哥大学的 Linus Schrage 教授首先开发,随后又推出了 GINO, LINGO, LINGO NL (又称LINGO2) 和“what’s best!”等优化软件,现在一般仍用 LINDO 作为这些软件的统称。各组件的功能各有侧重,分别简要介绍如下: (i)LINDO 是 Linear Interactive and Discrete Optimizer 字首的缩写形式,可以用来 求解线性规划(LP—Linear Programming),整数规划(IP—Integer Programming)和二次规 划(QP—Quadratic Programming)问题。 (ii)GINO 是 General Interactive Optimizer 字首的缩写形式,可以用来求解非线 性规划(NLP-Non-Linear Programming)问题,也可用于求解一些线性和非线性方程 (组)以及代数方程求根等。GINO 中包含了各种一般的数学函数(包括大量的概率函 数),可供使用者建立问题模型时调用。 (iii)LINGO 可以用来求解线性,非线性和整数规划问题。 (iv)LINGO NL (LINGO2) 可以用来求解线性,非线性和整数规划问题。 与 LINDO 和 GINO 不同的是,LINGO 和 LINGO NL (LINGO2) 包含了內置的建模 语言,允许以简练,直观的方式描述较大规模的优化问题,模型中所需的数据可以以一 定格式保存在独立的文件中。 (v)“what’s best!” 组件主要用于数据文件是由电子表格软件(如 LUTOS1-2-3 和 MS OFFICE 等)生成的情形。 LINDO 软件包有多种版本,但其软件內核和使用方法基本上是类似的。下面介绍 LINGO 组件的基本使用方法。 §2 LINGO 快速入门 当你在 windows 下开始运行 LINGO 系统时,会得到一个窗口: 外层是主框架窗口,包含了所有菜单命令和工具条,其它所有的窗口将被包含在主 窗口之下。在主窗口内的标题为 LINGO Model – LINGO1 的窗口是 LINGO 的默认模型窗 口,建立的模型都都要在该窗口内编码实现。下面举两个例子。 例 2.1 如何在 LINGO 中求解如下的 LP 问题: 1 2 min 2x + 3x s.t. ⎪ ⎪ ⎩ ⎪ ⎪ ⎨ ⎧ ≥ + ≤ ≥ + ≥ , 0 2 600 100 350 1 2 1 2 1 1 2 x x x x x x x 由于 LINGO 中已假设所有的变量是非负的,所以非负约束不必再输入到计算机中
LG0也不区分变量中的大小写字符(任何小写字符将被转换为大写字符):约束条件 中的”<”及 ”可用”<”及”代替。在模型窗口中入如下代吗: 100 2*x1+x2<600: 然后点击工具条上的按钮回即可。 例2.2使用LING0软件计算6个发点8个收点的最小费用运输问题。产销单位运 价如下表 单 位 销地 运 B B 产量 产地 A 7 4 60 55 51 3 As 2 5 2 6 5 41 As 5 5 2 2 8 1 4 3 52 销量 353722324132 43 38 eoe使用INo0软件,制程序如下: !6发点8收点运输问题: sets: /:wh6/: ouses,ven rs):cost,volume endsets !目标函数; m (links:cost*volume)i !需求约束 8e9sm:volume,- !产量约束; efor(warehouses(I): ndors(J):volume(I,J))<=capacity(I))i !这里是数据 data: c03t-62674295 -315-
-315- LINGO 也不区分变量中的大小写字符(任何小写字符将被转换为大写字符);约束条件 中的”<=”及”>=”可用”<”及”>”代替。在模型窗口中输入如下代码: min=2*x1+3*x2; x1+x2>350; x1>100; 2*x1+x2<600; 然后点击工具条上的按钮 即可。 例 2.2 使用 LINGO 软件计算 6 个发点 8 个收点的最小费用运输问题。产销单位运 价如下表。 单 位 销地 运 价 产地 B1 B2 B3 B4 B5 B6 B7 B8 产量 A1 6 2 6 7 4 2 5 9 60 A2 4 9 5 3 8 5 8 2 55 A3 5 2 1 9 7 4 3 3 51 A4 7 6 7 3 9 2 7 1 43 A5 2 3 9 5 7 2 6 5 41 A6 5 5 2 2 8 1 4 3 52 销量 35 37 22 32 41 32 43 38 使用 LINGO 软件,编制程序如下: model: !6 发点 8 收点运输问题; sets: warehouses/wh1.wh6/: capacity; vendors/v1.v8/: 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=60 55 51 43 41 52; demand=35 37 22 32 41 32 43 38; cost=6 2 6 7 4 2 9 5
5228143: enddata 然后点击工具条上的按钮⑤即可。 Ligo模型由4个部分构成:目标与约束,集合,数据,初始。 Lingo中的集合类型见下图: 集合 派生集合○ 基本集合> 稀疏集合>稠密集合 元煮列表法元素过滤法 直接列举法隐式列举法 Lig0中有三类运算符:算术运算符,逻辑运算符和关系运算符。运算符的优先级 见下表: 优先级运算符 最高 #NOT#,一(负号) 号) #NI #G正#,#GT#,#LE#,#T #AND#.#OR# 最低,=,> 注意使用Lingo中的四个集合循环函数:FOR,SUM,MAX,MN 在Ling0中可以使用外部数据文件,有如下几种方法: (1)复制-粘贴方法(Copy一Paste): (2)@FILE输入数据,@TEXT输出数据: (3)@OLE函数与电子表格软件(如EXCEL)连接: (4)@ODBC函数与数据库连接。 §3LING0中的集 对实际问题建模的时候,总会遇到一群或多群相联系的对象,比如工厂、消费者群 体、交通工具和雇工等等。LING0允许把这些相联系的对象聚合成集(sets)。一旦把 对象聚合成集,就可以利用集来最大限度的发挥LIG0建模语言的优势。 -316
-316- 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 5 5 2 2 8 1 4 3; enddata end 然后点击工具条上的按钮 即可。 Lingo 模型由 4 个部分构成:目标与约束,集合,数据,初始。 Lingo 中的集合类型见下图: Lingo 中有三类运算符:算术运算符,逻辑运算符和关系运算符。运算符的优先级 见下表: 优先级 运算符 最高 #NOT# ,-(负号) ^ * ,/ +,-(减号) #EQ#,#NE#,#GE#,#GT#,#LE#,#LT# #AND#,#OR# 最低 <,=,> 注意使用 Lingo 中的四个集合循环函数:FOR,SUM,MAX,MIN。 在 Lingo 中可以使用外部数据文件,有如下几种方法: (1)复制-粘贴方法(Copy-Paste); (2)@FILE 输入数据,@TEXT 输出数据; (3)@OLE 函数与电子表格软件(如 EXCEL)连接; (4)@ODBC 函数与数据库连接。 §3 LINGO 中的集 对实际问题建模的时候,总会遇到一群或多群相联系的对象,比如工厂、消费者群 体、交通工具和雇工等等。LINGO 允许把这些相联系的对象聚合成集(sets)。一旦把 对象聚合成集,就可以利用集来最大限度的发挥 LINGO 建模语言的优势
3.1什么是集 的对象, 这些对 象也称为集的成员。 个集可能是 列产品 可以预 以是未知 个价格属性 有待于的 性 雇员可以有 水屈性,也可以有 锈生日展性等等 LINGO有两种类型的集:原始集(primitive set)和派生集(derived set)。 一个原始集是由一些最基本的对象组成的。 一个派生集是用一个或多个其它集来定义的,也就是说,它的成员来自于其它已存 在的集。 3.2模型的集部分 型的一个可选部分。在LIG0模型中使 集之前, 事先定 set “endse部分 方,但是 有多不 个集及其属性在模型约束中被引用之前必须定义了它们。 3.2.1定义原始集 为了定义一个原始集,必须详细声明: ·集的名字 ·可选,集的成员 ·可选,集成员的属性 定义一个原始集,用下面的语法: 用0 setname /member_.list/[:attribute_.list] 注意: 合标准 :以拉丁 的 读性 集名字必须严格符 拉伯数字(0, 总长 后由 ,且不区分 小写 注意:该命名规则同样适用于集成员名和属性名等的命名。 Member_Iist是集成员列表。如果集成员放在集定义中,那么对它们可采取显式罗 列和隐式罗列两种方式。如果集成员不放在集定义中,那么可以在随后的数据部分定义 它们 ①当显式罗列成员时,必须为每个成员输入一个不同的名字,中间用空格或逗号 搁开 可以定 一个名为students的原始集,它具有成员John、Jill、Rose利 endisnta/gohn 11,nose /:xe ②当隐式罗列成员时,不必罗列出每个集成员。可采用如下语法: setname/memberl.memberN/[:attribute_list]; 这里的member1是集的第一个成员名,emberN是集的最末 个成员名。LING0将自动 生中间的所有成员名。LING0也接受一些特定的首成员名和末成员名,用于创建一些 特殊的集。列表如下: 隐式成员列表格式 示例 所产生集成员 317
-317- 3.1 什么是集 集是一群相联系的对象,这些对象也称为集的成员。一个集可能是一系列产品、卡 车或雇员。每个集成员可能有一个或多个与之有关联的特征,我们把这些特征称为属性。 属性值可以预先给定,也可以是未知的,有待于 LINGO 求解。例如,产品集中的每个产 品可以有一个价格属性;卡车集中的每辆卡车可以有一个牵引力属性;雇员集中的每位 雇员可以有一个薪水属性,也可以有一个生日属性等等。 LINGO 有两种类型的集:原始集(primitive set)和派生集(derived set)。 一个原始集是由一些最基本的对象组成的。 一个派生集是用一个或多个其它集来定义的,也就是说,它的成员来自于其它已存 在的集。 3.2 模型的集部分 集部分是 LINGO 模型的一个可选部分。在 LINGO 模型中使用集之前,必须在集部分 事先定义。集部分以关键字“sets:”开始,以“endsets”结束。一个模型可以没有集 部分,或有一个简单的集部分,或有多个集部分。一个集部分可以放置于模型的任何地 方,但是一个集及其属性在模型约束中被引用之前必须定义了它们。 3.2.1 定义原始集 为了定义一个原始集,必须详细声明: ·集的名字 ·可选,集的成员 ·可选,集成员的属性 定义一个原始集,用下面的语法: setname[/member_list/][:attribute_list]; 注意:用“[]”表示该部分内容可选。下同,不再赘述。 Setname 是你选择的来标记集的名字,最好具有较强的可读性。集名字必须严格符 合标准命名规则:以拉丁字母或下划线(_)为首字符,其后由拉丁字母(A—Z)、下划 线、阿拉伯数字(0,1,.,9)组成的总长度不超过 32 个字符的字符串,且不区分大 小写。 注意:该命名规则同样适用于集成员名和属性名等的命名。 Member_list 是集成员列表。如果集成员放在集定义中,那么对它们可采取显式罗 列和隐式罗列两种方式。如果集成员不放在集定义中,那么可以在随后的数据部分定义 它们。 ① 当显式罗列成员时,必须为每个成员输入一个不同的名字,中间用空格或逗号 搁开,允许混合使用。 例 3.1 可以定义一个名为 students 的原始集,它具有成员 John、Jill、Rose 和 Mike,属性有 sex 和 age: sets: students/John Jill, Rose Mike/: sex, age; endsets ② 当隐式罗列成员时,不必罗列出每个集成员。可采用如下语法: setname/member1.memberN/[: attribute_list]; 这里的 member1 是集的第一个成员名,memberN 是集的最末一个成员名。LINGO 将自动 产生中间的所有成员名。LINGO 也接受一些特定的首成员名和末成员名,用于创建一些 特殊的集。列表如下: 隐式成员列表格式 示例 所产生集成员
1.0 1.5 1.2.3.4.5 StringM.StringN Car2.car14 Car2,Car3,Car4,.Car14 DayM.DayN Mon.Fri Mon,Tue,Wed,Thu,Fri MonthM.MonthN Oct.Ian Oct.Nov.Dec.Ian MonthYearM.MonthYearN 0ct200L.Jan2002 Oct2001,Nov2001,Dec2001,Jan2002 ③集成员不放在集定义中,而在随后的数据部分来定义。 例3.2 数据部分 students,sex,age- e017 enddat 注意:开头用感叹号(!)末尾用分号(:),!表示注释,可跨多行。 在集部分只定义了一个集students,并未指定成员。在数据部分罗列了集成员 John、Jill、Rose和Mike,并对属性sex和age分别给出了值。 集成员无论用何种字符 标 它的 引都是从1开始连续计数。在attribute_list 可以 `或彩 成页 可以把集、集成员和集属性同C语言中的 体作个类比。如下图 集成员一一结构体的域 集属性·一结构体实伤 LG0内置的建模语言是一种描述性语言,用它可以描述现实世界中的一些问题 然后再借助于LIG0求解器求解。因此,集属性的值一旦在模型中被确定,就不可能再 更改。在LIG0中,只有在初始部分中给出的集属性值在以后的求解中可更改。这与前 面并不矛盾,初始部分是LING0求解器的需要,并不是描述问题所必须的。 3.2.2定义派生集 派生集,必须详细声明: 9者学 ,可洗。集成局的尿 可用下面的语法定义 ,个派生集 setname(parent_set_list)[/member_list/][:attribute_list]: setname是集的名字。parent_set_list是已定义的集的列表,多个时必须用逗号 隔开。如果没有指定成员列表,那么LING0会自动创建父集成员的所有组合作为派生集 的成员。派生集的父集既可以是原始集,也可以是其它的派生集。 例3.3
-318- 1.n 1.5 1,2,3,4,5 StringM.StringN Car2.car14 Car2,Car3,Car4,.,Car14 DayM.DayN Mon.Fri Mon,Tue,Wed,Thu,Fri MonthM.MonthN Oct.Jan Oct,Nov,Dec,Jan MonthYearM.MonthYearN Oct2001.Jan2002 Oct2001,Nov2001,Dec2001,Jan2002 ③ 集成员不放在集定义中,而在随后的数据部分来定义。 例 3.2 !集部分; sets:students:sex,age; endsets !数据部分; data: students,sex,age= John 1 16 Jill 0 14 Rose 0 17 Mike 1 13; enddata 注意:开头用感叹号(!),末尾用分号(;),!表示注释,可跨多行。 在集部分只定义了一个集 students,并未指定成员。在数据部分罗列了集成员 John、Jill、Rose 和 Mike,并对属性 sex 和 age 分别给出了值。 集成员无论用何种字符标记,它的索引都是从 1 开始连续计数。在 attribute_ list 可以指定一个或多个集成员的属性,属性之间必须用逗号隔开。 可以把集、集成员和集属性同 C 语言中的结构体作个类比。如下图: 集 ←→ 结构体 集成员 ←→ 结构体的域 集属性 ←→ 结构体实例 LINGO 内置的建模语言是一种描述性语言,用它可以描述现实世界中的一些问题, 然后再借助于 LINGO 求解器求解。因此,集属性的值一旦在模型中被确定,就不可能再 更改。在 LINGO 中,只有在初始部分中给出的集属性值在以后的求解中可更改。这与前 面并不矛盾,初始部分是 LINGO 求解器的需要,并不是描述问题所必须的。 3.2.2 定义派生集 为了定义一个派生集,必须详细声明: ·集的名字 ·父集的名字 ·可选,集成员 ·可选,集成员的属性 可用下面的语法定义一个派生集: setname(parent_set_list)[/member_list/][:attribute_list]; setname 是集的名字。parent_set_list 是已定义的集的列表,多个时必须用逗号 隔开。如果没有指定成员列表,那么 LINGO 会自动创建父集成员的所有组合作为派生集 的成员。派生集的父集既可以是原始集,也可以是其它的派生集。 例 3.3 sets: product/A B/; machine/M N/;