A GAMS programozási nyelv

Adattípusok

Skalárok

GAMS-ban a skalárok dinamikus típusúak, értéke lehet tetszőleges szám, illetve acronym. Skalárok az alábbi formában adhatók meg:

 
scalar skalar_neve 
opcionalis_magyarazat 
/numerikus_ertek/;
Megjegyzés:
fontos tudni, hogy a numerikus értéket két '/' jel között kell megadni, nem pedig az értékadás operátorral!

Kezdőérték megadása nem kötelező, később is lehet az adott skalárhoz értéket rendelni, de akkor már az értékadás operátorral. Több skalárt is definiálhatunk egy scalar utasításon belül (mert ez is egy utasítás, mintha C-ben azt mondanánk, hogy: int j = 5; //magyarazat), azokat vesszővel elválasztva egymástól, illetve a scalar kulcsszó használható scalars formában is.

Változók lehetséges típusai

Itt már különböző típusok vannak, ellentétben a skalárokkal. Az általános megadási forma az alábbi:

valtozo_tipus valtozo_neve(setdependecy) 
opcionalis_magyarazat ;

Ahol setdependency mondja meg, hogy mely halmazhoz kapcsolódik (nem kötelező halmazhoz kapcsolnunk a változót!), valtozo_tipus az alábbi lehetséges típusok közül az egyik:

Változó típusa Magyarázat
variable Nincs semmilyen megkötés a változóra, értéke mínusz végtelen és plusz végtelen között bármi lehet.
free variable Ugyanaz, mint az előbbi eset.
positive variable Nemnegatív értékű változó, 0 és plusz végtelen közötti tetszőleges érték megengedett.
negative variable Nempozitív értékű változó, mínusz végtelen és 0 közötti tetszőleges érték megengedett.
binary variable Csak a 0 és az 1 a két megengedett érték, egész értékű programozási feladatban szokás használni.
integer variable Nemnegatív egész értekek megengedettek, alapértelmezésben 0 és 100 között lehet.
SOS1 variable Változók egy csoportja, amelyek közül legfeljebb egy lehet nullától különböző pozitív.
SOS2 variable Változók egy csoportja, amelyek közül legfeljebb kettő lehet nullától különböző pozitív.
semicont variable Szemi-folytonos, értéke lehet 0 vagy egy megadott (pozitív) értéknél nagyobb.
semiint variable Szemi-egész, értéke lehet 0 vagy egy megadott (pozitív) értéknél nagyobb egész.

Változók attribútumai

  1. Alsó korlát (.lo)
  2. Felső korlát (.up)
  3. Fix értékű (.fx): ekkor .lo és .up (és .fx) attribútumok egyenlők.
  4. Szint (.l): a megoldáskori értéke a változónak. Értéke visszaállítódik, ha egy modellt megold a rendszer, amelyben szerepelt az adott változó.
  5. Határ (.m): a változó határértéke, ez is visszaállítódik, ha egy, az adott változót tartalmazó modellt megold a rendszer.

Halmazok

A halmazok a GAMS modell legfontosabb részét képezik. Matematikai értelelmben vett halmazok ezek, minden elem pontosan egyszer szerepelhet bennük. A halmazok elemei karaktersorozatok, ezek szintaktikájára vonatkozó megszorítások a "Nyelvi elemek" fejezet Halmazok elemeinek nevei pontban olvashatók.

Mire is jók a halmazok? Indexek megadására szolgálnak, amely indexekhez különböző adatokat szeretnénk rendelni. De talán a példa alapján világosabbá válik a szerepük.

Általános megadási mód:

SET halmaznev opcionalis_magyarazat / elso_elem_neve opcionalis_magyarazat masodik_elem_neve opcionalis_magyarazat ... / ;
Megjegyzés:
SET helyett a SETS is használható, illetve az elemeket a sorvége jel, vagy a vessző választhatja el egymástól.

Az alábbiakban olvashatók a halmazokkal kapcsolatos legfontosabb tudnivalók, további információk a linkek linkek között található weboldalakon találhatók.

Részhalmazok

Definiálhatjuk halmazok részhalmazait is, az alábbi módon:

SET subsetname(setname) opcionalis_magyarazat / elso_elem_neve opcionalis_magyarazat masodik_elem_neve opcionalis_magyarazat ... / ;
Megjegyzés:
A részhalmaz elemei csakis a szuperhalmaz létező elemei lehetnek (ez elég természetes elvárás). További érdekesség a részhalmazok esetén, hogy az elemeket nem csak explicit módon adhatjuk meg, hanem számíthatók is, ellentétben a halmazokkal. (Erről lásd a következő pontot.)

Elemek megadásának módja

Az elsődleges mód az explicit megadás, azaz felsoroljuk a halmaz elemeit. Ugyanakkor nem szükséges az összes elemet kiírni, ha azok egy sorozatot alkotnak. Például az r1, r2, r3, r4 elemsorozat megadható r1*r4 formában is.

Megjegyzés:
az összevont megadás esetén a szám máshol is lehet az elem nevében, például: 1r*10r is használható.

Megadhatjuk részhalmazok elemeit értékadó utasítással is. Ezt a

setname("setelementname") = yes;

formában tehetjük meg, amely ekvivalens azzal, hogy felsoroljuk a halmaz elemei között a megfelelő elemet. Ha pedig szeretnénk eltávolítani egy adott elemet egy halmazból, akkor használhatjuk a

setname("setelementname") = no;

utasítást. Ha egy részhalmaz eleméről nem mondunk semmit, akkor alapértelmezésben az nem lesz eleme a halmaznak, azaz 'no' az értéke.

Megjegyzés:
a fenti két utasításban ki kell tenni az idézőjeleket! (Lásd: következő pont.)

Definiálhatunk többdimenziós (legfeljebb 10 dimenziós) halmazokat is, a megfelelő elemek közé pontot téve, azaz:

SET multidimset(set1, set2) / set1_elmentname.set2_elementname, ... /;

Hivatkozás halmazok elemeire

Ebben a pontban az alábbi definíciókkal dolgozunk:

SET halmaz "megj.: ez 4000 elemu" / i1*i4000 / ; PARAMETERS x(halmaz) y(halmaz) ; SCALAR z osszeg ;

Következőt szeretnénk: az x paraméter értéke minden egyes halmaz-elemre legyen 4, majd az y paraméter értéke szintén minden halmaz-elemre legyen kétszerese az x-beli értéknek, végül összegezzük a z skalárba x-ben szereplő értékeket. Ezt így tehetjük meg:

x(halmaz) = 4; y(halmaz) = x(halmaz) * 2; z = sum(halmaz, x(halmaz)) ;

Ha pedig egy halmaz egyetlen elemére szeretnénk hivatkozni, akkor azt az elemet idézőjelek között kell megadni. Vagyis ha szeretnénk a fenti x paraméterben a 200. elemet megváltoztatni 10-re, akkor azt az alábbi utasítás teszi meg:

x("i200") = 10;

Halmazműveletek

Egy adott halmaz részhalmazain végezhetünk halmazműveleteket. El lehet készíteni halmazok unióját, metszetét, különbségét és komplementerét. A következő négy sorban ezekre - megfelelő sorrendben - egy-egy példa látható:

subset3(superset) = subset1(superset) + subset2(superset); subset3(superset) = subset1(superset) * subset2(superset); subset3(superset) = subset1(superset) - subset2(superset); subset2(superset) = not subset1(superset);

Műveletek halmazok elemeivel

A halmazokhoz kapcsolódóan négy további művelet van GAMS-ban. Ezek:

  1. ord: Ez a művelet visszadja egy elem relatív pozícióját egy rendezett halmazon belül, egy paramétere van, egy halmazelem, amit a fent leírtak szerint lehet megadni. Egy halmazt akkor tekint a GAMS rendezettnek, ha csakis explicit módon definiált elemei vannak (nincs számított elem). (Az angol nyelvű dokumentáció szerint: Only sets with a priori specified values.)
  2. card: Megadja, hogy egy halmaznak hány eleme van, paramétere a halmaz.
  3. sameas: Két paramétere van, az első kötelezően egy halmazelem, a második lehet halmazelem, vagy idézőjelek közé tett szöveg. A művelet eredménye igaz, ha a két paraméter neve (mint szöveg) megegyezik, hamis különben.
  4. diag: Ez a művelet csak annyiban tér el a sameas művelettől, hogy itt az igaz értéket 1, a hamis értéket pedig 0 helyettesíti.

Paraméterek

A paramétereket halmazokkal kapcsolatos adatok tárolására használhatjuk - mint egy asszociatív tömböt, indexelésük az adott halmaz(ok) elemeivel történik. Legtöbbször egyetlen halmazhoz kapcsolódnak, de köthetők több halmazhoz is (ez esetben célszerűbb a táblázatokat használni, lásd a következő pont). Az általános megadási forma a következő:

parameter param_name(set_dependency) opcionalis_magyarazat / elso_elem ertek_1, masodik_elem ertek_2, ... , utolso_elem ertek_n / ;

A fentiekben a parameter kulcsszó helyett a parameters is írható. Egy parameter utasításon belül több paraméter is definiálható, vesszővel elválasztva egymástól. Többdimenziós paraméter megadásánál a megfelelő halmazelemek közé pontot kell tenni, például így:

Parameters ket_dim(set1, set2) ez most egy ketdimenzios param / set1elem1.set2elem1 ertek11, set1elem1 .set2elem2 ertek12, set1elem9.set2elem1 ertek91, set1elem9 .set2elem2 ertek92 /;

Az explicit módon meg nem adott elemek implicit módon a nullát kapják értékül. Minden halmazelemet legfelejebb egyszer sorolhatunk fel (azaz definiálhatjuk), illetve minden felsorolt elem az adott halmaz egy létező eleme kell legyen. Intervallumokat is megadhatunk az alábbi módon:

parameter param(setname) / (elem1, elem5) ertek_1-5-ig, (elem6*elem18) ertek_6-18-ig /;

Táblázatok

Ha több halmaztól is függő adatokat szeretnénk megadni, célszerűbb a paraméter helyett a táblázatot használni. Táblázat legalább két-, legfeljebb tízdimenziós lehet. (Kettőnél több dimenzió esetén a paramétereknél imént ismertetett módon kell az elemeket megadni.)

Általános megadási forma:

TABLE itemname(set1, set2, ...) opcionalis_megjegyzes set2_elem1 set2_elem ... set1_elem1 value11 value21 ... set1_elem2 value21 value22 ... ... ;
Megjegyzés:
A fentiekben fontos a szöveg rendezése, a táblázat elemeihez rendelt értékek pontosan egy oszlop alá kell essenek! Ha valamely oszlopban nincs megadva érték, az adott elem implicit módon nullát kap értékül.

Karakterliterálok

GAMS-ban az acronym egy speciális adattípus, amely lehetővé teszi karaktersorozatok értékként való használatát. Az eddidiekhez hasonlóan definiálhatunk acronym-okat:

ACRONYM itemname megjegyzes; Acronyms hetfo, kedd, szerda, csutortok, pentek, szombat, vasarnap;

Ezeket az acronym-okat értékül adhatjuk tetszőleges változónak, értékük pedig azzal a szöveggel egyezik meg, amely a nevük is. Matematikai műveletek nem hajthatók végre acronym-okon, illetve ha egy halmaz felett definiált paraméter értékei között szerepel acronym, akkor az adott paraméter elemeire sem végezhetünk numerikus műveleteket. (Ez elég természetes, hiszen mi lenne pl. a "hetfo + 16" eredménye?)