例子程序:
Sets 是GAMS模型的基本组成部分,如同数学公式的下标
声明两个指数下标,起名为i,j并且赋值
列举指数时为什么不用"{}",而用"//",因为有的计算机键盘没有大括号
new york 表示成new-york,
将i,j的表述合并并不是必要的,也可以这样。
Set i canning plants / seattle, san-diego / ;
Set j markets
单数,复数Set,Sets一样。
Set t time periods /1991*2000/ 等价于 t = {1991,1992,...,2000}
Set m machines
GAMS 三种基本数据输入格式
列表数据输入
Parameters
声明了两个参量的存在,取名为a,b并且给出了指数下标i,j,同时给出了每个参量的说明文档,并且对于每个i,j赋予了值。。
也可以这样写:
规定:每个列表必须用//包括起来,而且每个元素和他对应的值必须用逗号隔开,或者写在不同的行
标量是没有域的参量,Scalar f freight in dollars per case thousand miles /90/;
表格数据据输入
Table d(i,j) distance in thousands of miles
直接赋值输入,通过不同的表述将声明过程和赋值过程分开
Parameter c(i,j) transport cost in thousands of dolllars per case;
注意第一行的分号不能少。
给某个特定的c(i,j)赋值,可以写上相应域元素的名字并用括号括起来。
变量
在GAMS模型中的决策变量(内生变量)必须用Varibales表述予以声明,每个变量都会有一个名字,合适的话就有一个域,还有说明文档(不是必须的)。
Variables
z是优化目标
变量一旦被声明,就必须赋予一个类型,默认free自由类型
作为最大化或最小化的目标变量必须是 free类型
Positive variable x;
注意,x的指数域不要在类型的表述中出现,域中所有条目有相同的类型。
方程式声明
GAMS 里面的求和符号和数学中的用法一样
Sum(index of summation,summand)用一个逗号分隔两个自变量。
Sum(j,x(i,j))
Sum((i,j),c(x,j)*x(i,j))
连乘符号用prod代替sum
方程式定义:
被定义的方程式名字
注意:
1.关系运算符有三种 =l=小于
2.指数域对用单个GAMS表述联立方程组进行控制。约束denand的定义产生了对域j的每个元素的约束
GAMS输出显示为:
DEMAND(new-york).. X(seattle,new-york) + X(san-diego,new-york) =G=325 ;
DEMAND(chicago)..
DEMAND(topeka)..
模型和运算表述
单词 model 在 GAMS中有很明确的意思。它是指一系列方程式。就像其他 GAMS组成部分一样,在声明过程中我们
要给它一个名字。对模型进行声明的格式是在关键字 model 后面输入模型的名字,随后在斜杠中输入该模型所包含
的方程式的名字。如果模型包含之前所有定义的方程式,你可以输入/all/来代替它们名字的详细列表,表述如下:
model transport /all/ ;
这个表述看起来是多余的,但是对于在同一个 GAMS文件中可能建立多个模型的高级用户来说是有用。如果我们要
用详细列表,上述表述替换为:
model transport / cost, supply, demand / ;
因为指数域不是方程式的名字,在这里它们被省略了。当且仅当现存方程式的子域包含有一个正在建立的模型(或
者说是子模型)时,列表才会被使用。
一旦一个模型被声明和赋予了方程式,就做好了运算的准备了。这时我们会用到 solve 表述:
solve transport using lp minimizing z ;
如下为 solve 表述的格式:
1.
2.
3.
4.
lp
qcp
nlp
dnlp
mip
rmip
miqcp
minlp
rmiqcp
rminlp
mcp
mpec
cns
5.
6.
2.10
GAMS被设计带有一个小的数据库系统,它用于维护关于变量和方程式的记录。记录中最为重要的领域是:
.lo
.l
.up
.m
引用这些相关量的格式是,变量或者方程式的名字,随后是领域名, (如果需要的话)再是指数域(或者指数域中
的元素) 。
GAMS 允许用户完成读取和写入数据库。现在这些或许对你没有什么用,但是对于高级用户而言这是一个相当有价
值的特点。以下举一些使用数据库的例子。
2.10.1
变量的下边界和上边界根据变量的类型(free,positive,negative,binary,integer)而自动的设定,但是用户可以
重新设定这些边界。下面是一些例子:
x.up(i,j) = capacity(i,j) ;
x.lo(i,j) = 10.0 ;
x.up('seattle','new-york') = 1.2*capacity(seattle','new-york') ;
第一个和第三个例子中假定 capacity (i, j) 这个参量已经被声明和赋值过了。 这些表述必须在声明变量之后, 在 solve
表述之前。右手边可以使用所有赋值过程中可用的数学表达。
在非线性规划问题中,建模过程要尽可能的缩小上下边界之间的差值,这对于运算过程很重要,而为搜寻最优化值
的运算指出一个初始值也很重要。例如,在一个带有约束的库存模型中,变量是 quantity(i) ,而且已知非约束情
况下的最优化值是 eoq(i) 。作为对约束情况的猜测,我们输入:
quantity.l(i) = 0.5*eoq(i) ;
(一般情况下默认的初始值被设为 0,除非 0 不在边界范围内,而在这种情况下,它取最接近 0 的边界值)
注意,.lo 和.up 值完全由用户控制。相比之下,虽然.l 和.m 也要用户赋予初始值,但是它们由算法控制。