GAMS中文教程.docx
- 文档编号:13027512
- 上传时间:2023-04-22
- 格式:DOCX
- 页数:42
- 大小:38.59KB
GAMS中文教程.docx
《GAMS中文教程.docx》由会员分享,可在线阅读,更多相关《GAMS中文教程.docx(42页珍藏版)》请在冰豆网上搜索。
GAMS中文教程
二GAMS简明教程由RichardE.Rosenthal编著
(译者:
该翻译由华中科技大学能源与动力工程学院小海完成,由于译者水平有限,其中肯定会有些问题,欢迎大
家阅读并批评指正!
)
2.1简介
这本书的简介部分以一个详细的例子结束,这个例子是一个用GAMS进行表达、解决和分析的小而简单的优化问题。
由来自蒙特利尔市Naval研究生院的RichardE.Rownthal编写。
通过这个例子我们可以对GAMS有一个快速而全面的
了解。
很多地方引用到本书其他章节的知识,方便大家进一步查阅;而阅读这一部分即使不看本书其他章节也能看
懂并且有所收获。
例子是一个关于运输的线性规划问题,这个问题在最优化技术发展过程中曾经被当做实验对象。
用这个例子展示
GAMS这类代数建模语言的强大功能是很好的选择,因为不管手头要处理的问题有多大,运输问题本身具有一个简
单的、可用的代数结构。
你可以发现,如果要解决一个非常大的运输问题,我们将呈现的用于解决小规模运输问题
的GAMS输入文件中的内容并不需要改变多少。
在熟悉的运输问题中,我们考虑几个工厂的供应和几个市场的需求的商品,我们也给出从工厂运输商品到市场的单
位花费。
这其中的经济学问题是:
怎样安排运输使得我们的总运输成本最小?
这个问题的代数表达常常采用下列方式:
Indices:
i=plants
j=markets
GivenData:
i
a=supplyofcommodityofplanti(incases)
ij
b=demandforcommodityatmarketj
ij
c=costperunitshipmentbetweenplantiandmarketj($/case)
DecisionVariables:
ij
x=amountofcommoditytoshipfromplantitomarketj(cases),
Where
ij
x≥0,foralli,j
Constraints:
Observesupplylimitatplanti:
j
ijj
ax≤∑foralli(cases)
Satisfydemandatmarketj:
ijj
i
xb≥∑forallj(cases)
ObjectiveFunction:
Minimize
ijij
ijcx∑∑($K)
注意这个例子显示了一些一般情况下我们认为是好习惯的建模方式,这些在GAMS里面被继承了。
首先,模型程序
中的各组成部分都按类型分组定义了。
其次,GAMS程序各组成部分先后次序已经定好了,因此没有标识符能在被
定义之前使用。
第三,各组成部分都有特定的单位。
第四,选择的单位要使优化过程中得到的数值具有相对较小的
绝对数量级。
(例如标识$K表示dollar的千倍)
各组成部分类型的名称在不同的模型中可能不一样。
例如,经济学家分别用外生变量和内生变量来表示已知数据和
决策变量。
(译者:
在经济模型中,内生变量是指该模型所要决定的变量。
外生变量指由模型以外的因素所决定的
已知变量,它是模型据以建立的外部条件。
内生变量可以在模型体系内得到说明,外生变量决定内生变量,而外生
变量本身不能在模型体系中得到说明。
参数通常是由模型以外的因素决定的,因此也往往被看成外生变量。
例:
P=a+bQ,表示价格与数量的关系,则a、b是参数,都是外生变量;P、Q是模型要决定的变量,所以是内生变量。
除此之外,譬如相关商品的价格,人们的收入等其他于模型有关的变量,都是外生变量)
在GAMS中,被采用的相关术语是:
sets表示指数下标,parameters表示已知数,variables表示决策变量,equations
表示约束方程和目标方程。
运输问题的GAMS语言表述紧密的联系了上述几个部分。
最主要的区别在于GAMS表述可以被电脑读取和运行。
作为运输问题的例子,假设有两个罐头厂和三个市场,已知数据如表2.1所示。
运输距离的单位是千英里,运输成
本是$90.00每箱每千英里。
这个例子的GAMS表述是:
Sets
icanningplants/seattle,san-diego/
jmarkets/new-york,chicago,topeka/;
Parameters
a(i)capacityofplantiincases
/seattle350
san-diego600/
b(j)demandatmarketjincases
/new-york325
chicago300
topeka275/;
Tabled(i,j)distanceinthousandsofmiles
new-yorkchicagotopeka
seattle2.51.71.8
san-diego2.51.81.4;
Scalarffreightindollarspercaseperthousandmiles/90/;
Parameterc(i,j)transportcostinthousandsofdollarspercase;
c(i,j)=f*d(i,j)/1000;
Variables
x(i,j)shipmentquantitiesincases
ztotaltransportationcostsinthousandsofdollars;
PositiveVariablex;
Equations
costdefineobjectivefunction
supply(i)observesupplylimitatplanti
demand(j)satisfydemandatmarketj;
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);
Modeltransport/all/;
Solvetransportusinglpminimizingz;
Displayx.l,x.m;
如果你在GAMS中建立一个文件,将以上内容输入进去,运输模型就可以被建立和进行计算了。
要使GAMS在不同
的计算机上运行需要改变一些细节,但是最简单的方法(不提供非必要服务的方法)是在输入文件的名字后面加上
GAMS这几个字母。
在程序运行过程中,你将看到一些精练的描述GAMS运行过程的字符行,包括了写入输出结果
的文件名。
当GAMS程序结束时,检查文件,如果一切正常的话,那么最优化运输方案将显示如下:
new-yorkchicagotopeka
seattle50.000300.000
san-diego275.000275.000
你还可以得到如下所示边际成本(单纯形乘数):
chicagotopeka
seattle0.036
san-diego0.009
这些结果表明,举例来说,采用最优化方案就不要从Seattle送货到Topeka,但是你坚持要这样做的话,你将比最
优化方案多付0.036$K($36.00)每箱的成本。
(你能从优化运输方案和已知数据中证明这个数据的正确性吗?
)
(译者:
可以这样想,因为只能由Seattle和SanDiego向Topeka送货,为了满足Topeka市场275箱的需求,从San
Diego少送一箱就要从Seattle补送一箱,这样算来,多出的成本就等于(1.8‐1.4)*90=36)
2.2GAMS模型的结构
本章的剩余部分我们将讨论GAMS模型的基本组成部分,还是以上面提到的运输问题为例。
表2.2列出了基本组成
部分。
GAMS中有可供用户选择的输入模块,例如编辑损坏数据的检查信息和要求显示客户结果列表。
其他可供选择的高
级特征包括保存和恢复原模型,以及在一次运行中创建联合模型,但是这个教程仅仅讨论基本的部分。
在开始介绍各个部分之前,以下几点需要说明:
1.GAMS模型是指一组GAMS语言表述的集合。
而组织这些表述的唯一规则是在模型的一个部分被声明之前它是
无法被引用的。
2.GAMS的表述能以任何一种吸引人的排版方式呈现在用户眼前,一个表述占用多行,插入空白行,以及一行中
多个表述都是可以的。
在这个教程中你可以了解那些是被允许的格式,但是一些更详细的规则将在下一章给出。
3.如果你是GAMS新手,你应该在每一个表述的最后加上分号,如例中所示。
GAMS编译器不区分大小写字母,
你可以随意使用。
4.说明文档方便用户看懂数学模型。
说明文档整个集中的被包含在模型表述中比把它分开书写要更为有效(往往
也更为准确)。
至少有两种方法向GAMS模型中插入此类说明文件。
第一,GAMS编译器将把以一个星号开头的
行作为注解行。
第二,或许更为重要,可以用特定的GAMS语句插入说明文档。
在运输模型中所有的小写文字
都是以第二种形式插入的说明文档。
Inputs:
Sets
Declaration
Assignmentofmembers
Data(Parameters,Tables,Scalars)
Declaration
Assignmentofvalues
Variables
Declaration
Assignmentoftype
Assignmentofboundsand/orinitialvalues(optional)
Equations
Declaration
Definition
ModelandSolvestatements
Displaystatement(optional)
Outputs:
EchoPrint
ReferenceMaps
EquationListings
StatusReports
Results
Table2.2:
ThebasiccomponentsofaGAMSmodel
5.正如你看到的以上输入部分,建构GAMS组成部分包括两个部分:
声明以及赋值或者定义。
声明是指表明其存
在性并且给其取个名字。
赋值或者定义是指给其赋予某个值或者格式。
以equations为例,你必须用单独的GAMS
表述声明和定义它。
然而对于其他所有的GAMS组成部分,你可以选择在同一个表述中或者单独对其进行声明
或赋值。
6.模型各组成部分的名字必须以字母开头,并且长度不超过31个字符,除第一个字符外可以使用字母或数字。
2.3Sets指数下标
Sets是GAMS模型基本的组成部分,它如同数学公式中的指数下标。
运输例子中该部分表述如下:
Sets
icanningplants/seattle,san-diego/
jmarkets/new-york,chicago,topeka/;
本表述的作用很明显。
我们声明了两个指数下标并且给它们起名为i和j。
我们还给它们赋了值:
i={Seattle,San-Diego}
j={NewYork,Chicago,Topeka};
你应该注意到GAMS格式和一般数学格式对于列举指数下标元素的区别。
GAMS用‘/’斜杠而不是用‘{}’大括号,
这是因为不是所有的电脑键盘都有大括号这个键。
同时注意到在这里多字名如‘NewYork’不能使用而用了连字号。
Sets表述中小写文字被称为文本。
文本可有可无。
它们仅为内部文档存在,在模型中没有正式的作用。
GAMS编译
器不会在意文本的含义,但是为了方便用户,会保留文本并呈现给用户多次。
将i和j的表述合并并不是必要的。
我们也可以将它们分开:
Seticanningplants/seattle,san-diego/;
Setjmarkets/new-york,chicago,topeka/;
至于使用多少空格和空行(如用大或者小写一样)完全取决于用户。
每一个GAMS用户都愿意遵从自己的格式习惯。
(用单数set还是负数sets也取决于用户。
在进行单个声明的表述中用set,在进行多个声明的表述中用sets,这是
符合英语语法的,但是GAMS不区分set和sets。
)
当要赋的值是一个系列的时候,用星号*是很方便的。
例如:
Setttimeperiods/1991*2000/;
Setmmachines/mach1*mach24/;
这就相当于:
t={1991,1992,1993,.....,2000}
m={mach1,mach2,......,mach24};
这里将赋的值看成字符串,所以t的值不是数字。
另外一个好用的表述是alias,它可以给先前声明的set另外一个名字。
例如:
Alias(t,tp);
在一般数学表达中tp和t’相似。
这对于包含有同一个set中元素交互作用的模型很有用。
例子所示的i,j,t和m是静态的指数下标,它们包含的元素由用户赋予并且不会改变。
GAMS有一定的建立动态
指数下标的能力,这要求它们包含的元素执行集理论和进行逻辑操作。
章节12第107面将讨论动态指数下标。
另
外一个有价值的高级特征是多维指数下标,将在4.5节,39页进行说明。
2.4数据
运输模型GAMS表述展示了所有的三种基本的数据输入格式。
它们是列表、表格和直接赋值。
下面三个小节将讨论这三种格式。
2.4.1列表数据输入
第一种数据输入方式由例子中首个Parameters表述呈现出来:
Parameters
a(i)capacityofplantiincases
/seattle350
san-diego600/
b(j)demandatmarketjincases
/new-york325
chicago300
topeka275/;
这个表述的意思仍然是很明显的,但是有必要分析下其中的细节。
这个表述声明了两个参量的存在,取名为a和b,
并分别给出了指数域i和j(指数域是指指数下标,或者指数小标元组,参量、变量或者方程式在其中被定义)。
该
表述同时给出了每个参量的说明文档并且对于每个i和j赋予了a(i)和b(j)相应的值。
如果你愿意的话,也可以用两
个表述来代替这一个表述:
Parametersa(i)capacityofplantiincases
/seattle350
san-diego600/;
Parametersb(j)demandatmarketjincases
/new-york325
chicago300
topeka275/;
当使用列表方式输入数据时应该注意:
1.只要你愿意你可以以几乎所有的方式呈现出指数域元素和与它们对应的各参量值的列表。
唯一的规定是整个列
表需要用斜杠包括起来,并且各个元素和它们对应的值必须用逗号分开或者从不同的行中输入。
2.在该列表中不需要用分号将名字、指数域和说明文档隔开。
这是因为当你使用列表方式时这个表述即被当做声
明过程又被当做赋值过程。
(这种列表本身不能被GAMS识别,将会导致报错)
3.GAMS编译器有一个称为域检查的特征,它将确认域中各元素是否是相应指数下标中的元素。
例如,你把seti
的声明中的“Seattle”在后面的元素值列表中误拼成“Seatle”,GAMS编译器将报错并给出信息指出“Seatle”
不属于seti。
4.所有参量的默认值是0。
因此,你只需要在列表中输入非零量即可,输入的顺序任意。
5.标量是指没有域的参量,通过Scalar表述来声明和赋值,标量只有一个值,如下所示运输模型中的表述:
Scalarffreightindollarspercaseperthousandmiles/90/;
如果一个参量的域是二维或者多维的,它仍然可以用列表格式输入其值。
这对于输入稀疏的(有少数非零值)和非
常稀疏的(有少数不等的非零值)矩阵很有帮助。
2.4.2表格数据输入
有时候优化工作者会注意到一个大模型的输入数据源于一些相对较小的数据表格。
那么,用表格形式来输入数据是
很方便的。
下面是运输模型中的一个二维表格:
Tabled(i,j)distanceinthousandsofmiles
new-yorkchicagotopeka
seattle2.51.71.8
san-diego2.51.81.4;
这个表述的作用是声明了参量d并且如同i和j的笛卡尔积一样按顺序排好相应域。
d的值在对应的标题下被给出。
在表格中出现空白输入的话将被看做0对待。
就像在列表格式中,GAMS在这里也将用域检查来确定行名和列名是不是相应域下的元素。
而对于在一行中无法输
入所有列值的表格和大于二维的表格将会在章节5,43页中讨论。
2.4.3直接赋值输入
与其上述两种输入方式不同,直接赋值输入通过不同的表述将声明过程和赋值过程分开。
运输模型中对应的这种输
入方法是:
Parameterc(i,j)transportcostinthousandsofdollarspercase;
c(i,j)=f*d(i,j)/1000;
这里要强调一下第一行最后的分号。
如果没有这个分号,GAMS编译器将把两行当做同一个表述的两个部分。
(GAMS
将不能分辨有效的解释,因此将发给用户一个精炼的有用的错误报告)
第一行的表述的作用是声明参量c,指明域(i,j),并且给出说明文档。
第二行的表述给c(i,j)赋值,这些值由
f和d(i,j)决定。
当然,只有在先前的表述中给f和d(i,j)赋值过这里才不会出错。
直接赋值作用了所有c(i,j)的指数域。
如果你想给特定的某个c(i,j)赋值,你应该写上相应域元素的名字并用
引号括起来。
如下所示:
c('Seattle','New-York')=0.40;
这是一个有效的GAMS表述。
同一个参量可以被多次赋值。
每个赋值表述在下一个赋值表述之前有效。
(相比之下,同一个参量不能被多次声明。
这是GAMS中的一种错误检查,它使你避免对两个不同的东西使用同一个名字)
赋值表述的右边可以包含一系列数学表达和内建函数。
假如你熟悉某种科学程序语言例如FORTRAN或者C,那么在
GAMS中写赋值表述对于你而言就很简单了。
(需要注意的是,GAMS有些东西与FORTRAN和C都不一样,例如,
我们不用循环语句就可以对所有的c(i,j)赋值)
GAMS的标准操作和提供的函数将随后给出。
接下来是一些有效赋值的例子。
在所有情况下,确保左边的参量都已
经被声明并且右边的参量都已经在前面的表述中被赋值。
csquared=sqr(c);
e=m*csquared;
w=l/lamda;
eoq(i)=sqrt(2*demand(i)*ordcost(i)/holdcost(i));
t(i)=min(p(i),q(i)/r(i),log(s(i)));
euclidean(i,j)=qrt(sqr(xi(i)-xi(j)+sqr(x2(i)-x2(j)));
present(j)=future(j)*exp(-interest*time(j));
之后介绍的求和和乘积算子也能被直接用于赋值。
2.5变量
在GAMS模型中的决策变量(内生变量)必须用Variables表述予以声明。
每个变量都会有一个名字,合适的话就有
对应的一个域,还有说明文档(不是必须的)。
运输模型中的相关表述如下所示:
Variables
x(i,j)shipmentquantitiesincases
ztotaltransportationcostsinthousandsofdollars;
这个表述为每一对(i,j)做出了装载变量声明。
(在章节8,65页,你将看到GAMS是怎样解决现实世界的问题,
在这个过程中只允许(i,j)的子域用于运输装载)
变量z被声明却没有给出指数域是因为它与取值是一一对应的关系。
每一个GAMS优化模型必须包括这样一个变量,
它是最小化或者最大化的目标。
一旦被声明,每一个变量都必须被赋予一个类型。
表2.3给出了可用的类型:
作为最小化或者最大化的目标的变量必须是变量性质的并且属于free类型。
在这个运输模型例子中,z默认是free
类型,但是x(i,j)通过以下表述限制成非负值:
Positivevariablex;
注意,x的指数域不要在类型表述中出现。
域中所有的条目有相同的类型。
2.10小节将说明如何规定变量的上下边界和初始值。
2.6方程式
GAMS的代数建模语言在创建模型的方程和不等式的时候功能很强大。
这是因为当一组方程式具有相同代数结构的
时候,它们是同时而不是一个个被创建。
2.6.1方程式声明
GAMS中要用单独的表述对方程式进行声明和定义。
其声明的格式与声明GAMS其他部分相同。
首先,在这里要用
到关键字Equations,之后是名字,指数域和一组或者多组被声明方程式或不等式的说明文档。
运输模型中的表述如
下所示:
Equations
costdefineobjectivefunction
supply(i)observesupplylimitatplanti
demand(j)satisfydemandatmarketj;
要记住的是Equation这个词在GAMS中意思很宽泛。
它包含了等式和不等式,而GAMS中一个Equation的名字可以
对应一个或者多个式子。
例如,cost没有指数域所以是一个单独的式子,而supply对应指数域i下定义的一组式子。
2.6.2GAMS求和(连乘)符号
在介绍方程式定义之前我们先说明一下GAMS中的求和符号。
GAMS是以标准键盘和逐行输入检查为标准设计的,
所以在做求和时是不能用标准数学符号的(尽管这对用户造成不便)。
GAMS
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- GAMS 中文 教程