二 GAMS简明教程由Richard E. Rosenthal编著(译者:该翻译由华中科技大学能源与动力工程学院小海完成,由于译者水平有限,其中肯定会有些问题,欢迎大家阅读并批评指正!)简介这本书的简介部分以一个详细的例子结束,这个例子是一个用GAMS进行表达、解决和分析的小而简单的优化问题。
由来自蒙特利尔市Naval研究生院的Richard 编写。
通过这个例子我们可以对GAMS有一个快速而全面的了解。
很多地方引用到本书其他章节的知识,方便大家进一步查阅;而阅读这一部分即使不看本书其他章节也能看懂并且有所收获。
例子是一个关于运输的线性规划问题,这个问题在最优化技术发展过程中曾经被当做实验对象。
用这个例子展示GAMS这类代数建模语言的强大功能是很好的选择,因为不管手头要处理的问题有多大,运输问题本身具有一个简单的、可用的代数结构。
你可以发现,如果要解决一个非常大的运输问题,我们将呈现的用于解决小规模运输问题的GAMS输入文件中的内容并不需要改变多少。
在熟悉的运输问题中,我们考虑几个工厂的供应和几个市场的需求的商品,我们也给出从工厂运输商品到市场的单位花费。
这其中的经济学问题是:怎样安排运输使得我们的总运输成本最小这个问题的代数表达常常采用下列方式:Indices:i = plantsj = marketsGiven Data:ia= supply of commodity of plant i (in cases)ijb= demand for commodity at market jijc = cost per unit shipment between plant i and market j ($/case)Decision Variables:ijx = amount of commodity to ship from plant i to market j (cases),Whereijx ≥0, for all i, jConstraints:Observe supply limit at plant i:jij ja x≤∑ for all i (cases)Satisfy demand at market j:ij jix b ≥∑ for all j (cases)Objective Function: Minimizeij ijijcx ∑∑ ($K)注意这个例子显示了一些一般情况下我们认为是好习惯的建模方式,这些在GAMS里面被继承了。
首先,模型程序中的各组成部分都按类型分组定义了。
其次,GAMS程序各组成部分先后次序已经定好了,因此没有标识符能在被定义之前使用。
第三,各组成部分都有特定的单位。
第四,选择的单位要使优化过程中得到的数值具有相对较小的绝对数量级。
(例如标识$K表示dollar的千倍)各组成部分类型的名称在不同的模型中可能不一样。
例如,经济学家分别用外生变量和内生变量来表示已知数据和决策变量。
(译者:在经济模型中,内生变量是指该模型所要决定的变量。
外生变量指由模型以外的因素所决定的已知变量,它是模型据以建立的外部条件。
内生变量可以在模型体系内得到说明,外生变量决定内生变量,而外生变量本身不能在模型体系中得到说明。
参数通常是由模型以外的因素决定的,因此也往往被看成外生变量。
例:P=a+bQ,表示价格与数量的关系,则a、b是参数,都是外生变量;P、Q是模型要决定的变量,所以是内生变量。
除此之外,譬如相关商品的价格,人们的收入等其他于模型有关的变量,都是外生变量)在GAMS中,被采用的相关术语是:sets表示指数下标,parameters表示已知数,variables 表示决策变量,equations表示约束方程和目标方程。
运输问题的GAMS语言表述紧密的联系了上述几个部分。
最主要的区别在于GAMS表述可以被电脑读取和运行。
作为运输问题的例子,假设有两个罐头厂和三个市场,已知数据如表所示。
运输距离的单位是千英里,运输成本是$每箱每千英里。
这个例子的GAMS表述是:Setsi canning plants / seattle, san-diego /j markets / new-york, chicago, topeka / ;Parametersa(i) capacity of plant i in cases/ seattle 350san-diego 600 /b(j) demand at market j in cases/ new-york 325chicago 300topeka 275 / ;Table d(i,j) distance in thousands of milesnew-york chicago topekaseattlesan-diego ;Scalar f freight in dollars per case per thousand miles /90/ ;Parameter c(i,j) transport cost in thousands of dollars per case ; c(i,j) = f * d(i,j) / 1000 ;Variablesx(i,j) shipment quantities in casesz total transportation costs in thousands of dollars ;Positive Variable x ;Equationscost define objective functionsupply(i) observe supply limit at plant idemand(j) satisfy demand at market j ;cost .. z =e= sum((i,j), c(i,j)*x(i,j)) ;supply(i) .. sum(j, x(i,j)) =l= a(i) ;demand(j) .. sum(i, x(i,j)) =g= b(j) ;Model transport /all/ ;Solve transport using lp minimizing z ;Display , ;如果你在GAMS中建立一个文件,将以上内容输入进去,运输模型就可以被建立和进行计算了。
要使GAMS在不同的计算机上运行需要改变一些细节,但是最简单的方法(不提供非必要服务的方法)是在输入文件的名字后面加上GAMS这几个字母。
在程序运行过程中,你将看到一些精练的描述GAMS运行过程的字符行,包括了写入输出结果的文件名。
当GAMS程序结束时,检查文件,如果一切正常的话,那么最优化运输方案将显示如下:new-york chicago topekaseattlesan-diego你还可以得到如下所示边际成本(单纯形乘数):chicago topekaseattlesan-diego这些结果表明,举例来说,采用最优化方案就不要从Seattle送货到Topeka,但是你坚持要这样做的话,你将比最优化方案多付$K($)每箱的成本。
(你能从优化运输方案和已知数据中证明这个数据的正确性吗)(译者:可以这样想,因为只能由Seattle和San Diego向Topeka送货,为了满足Topeka 市场275箱的需求,从SanDiego少送一箱就要从Seattle补送一箱,这样算来,多出的成本就等于(‐)*90=36) GAMS模型的结构本章的剩余部分我们将讨论GAMS模型的基本组成部分,还是以上面提到的运输问题为例。
表列出了基本组成部分。
GAMS中有可供用户选择的输入模块,例如编辑损坏数据的检查信息和要求显示客户结果列表。
其他可供选择的高级特征包括保存和恢复原模型,以及在一次运行中创建联合模型,但是这个教程仅仅讨论基本的部分。
在开始介绍各个部分之前,以下几点需要说明:1. GAMS模型是指一组GAMS语言表述的集合。
而组织这些表述的唯一规则是在模型的一个部分被声明之前它是无法被引用的。
2. GAMS的表述能以任何一种吸引人的排版方式呈现在用户眼前,一个表述占用多行,插入空白行,以及一行中多个表述都是可以的。
在这个教程中你可以了解那些是被允许的格式,但是一些更详细的规则将在下一章给出。
3. 如果你是GAMS新手,你应该在每一个表述的最后加上分号,如例中所示。
GAMS编译器不区分大小写字母,你可以随意使用。
4. 说明文档方便用户看懂数学模型。
说明文档整个集中的被包含在模型表述中比把它分开书写要更为有效(往往也更为准确)。
至少有两种方法向GAMS模型中插入此类说明文件。
第一,GAMS编译器将把以一个星号开头的行作为注解行。
第二,或许更为重要,可以用特定的GAMS语句插入说明文档。
在运输模型中所有的小写文字都是以第二种形式插入的说明文档。
Inputs:SetsDeclarationAssignment of membersData (Parameters, Tables, Scalars)DeclarationAssignment of valuesVariablesDeclarationAssignment of typeAssignment of bounds and/or initial values (optional)EquationsDeclarationDefinitionModel and Solve statementsDisplay statement (optional)Outputs:Echo PrintReference MapsEquation ListingsStatus ReportsResultsTable : The basic components of a GAMS model5. 正如你看到的以上输入部分,建构GAMS组成部分包括两个部分:声明以及赋值或者定义。
声明是指表明其存在性并且给其取个名字。
赋值或者定义是指给其赋予某个值或者格式。
以equations为例,你必须用单独的GAMS表述声明和定义它。
然而对于其他所有的GAMS组成部分,你可以选择在同一个表述中或者单独对其进行声明或赋值。
6. 模型各组成部分的名字必须以字母开头,并且长度不超过31个字符,除第一个字符外可以使用字母或数字。
Sets 指数下标Sets是GAMS模型基本的组成部分,它如同数学公式中的指数下标。
运输例子中该部分表述如下:Setsi canning plants / seattle, san-diego /j markets / new-york, chicago, topeka / ;本表述的作用很明显。
我们声明了两个指数下标并且给它们起名为i 和j。