/*----------------------------------------------------------------------------*/
/* Data Creare
: 18 Mai 1997
*/
/* Data Modificare :
25 Octombrie 1997
*/
/*----------------------------------------------------------------------------*/
/* Sursa : "Oil-Refinery
Modeling with the GAMS Language" by David Kendrick, */
/* Alexander Meeraus
and Jung Sun Suh.
*/
/*
*/
/* Modelul unei companii
ce prelucreaza petrol brut cumparat.
*/
/*
O companie cumpara petrol brut si anumite produse intermediare pentru a
*/
/* produce diverse produse
finale pentru a fi vindute pe piata. Compania are */
/* mai multe unitati
de prelucrare. In procesul de amestec intrebuinteaza si */
/* alte materii
prime.Problema companiei este de a produce in asa fel incit */
/* sa maximizeze venitul
net rezultat din vinzarile de produse finale din care*/
/* se scad toate
costurile implicate pe intreg procesul de productie.
*/
/*----------------------------------------------------------------------------*/
FILE fd="oil.dat"
INTEGER
nrcrude READ fd IS nrcrude >=1; /* Numar tipuri petrol brut */
nrmraw READ fd IS nrmraw >=1; /* Numar materii prime */
nrinter READ fd IS nrinter >=1; /* Numar produse intermediare */
nrpurch READ fd IS {nrpurch >=1; nrpurch <=nrinter};
/* Numar produse intermediare cumparate */
nrfinal READ fd IS nrfinal >=1; /* Numar produse finale */
nrproc READ fd IS nrproc >=1; /* Numar procese */
nrunit READ fd IS nrunit >=1; /* Numar unitati productive */
nrqual READ fd IS nrqual >=1; /* Numar calitati */
nrblend READ fd IS {nrblend >=1; nrblend<=nrfinal*nrinter};
/* Number elemente multime BLEND,configuratii de intermediare */
/* ce pot participa in amestec pentru un anumit produs final */
nrmrint = nrmraw+nrinter
/* Numar materii prime plus produse intermediare */
RANGE
crude = [1,nrcrude ]; /* Coduri interne petrol brut */
mraw = [1,nrmraw ]; /* Coduri interne materii prime */
inter = [1,nrinter]; /* Coduri produse intermediare */
purch = [1,nrpurch]; /* Coduri intermediare cumparate */
final = [1,nrfinal]; /* Coduri produse finale */
proc = [1,nrproc ]; /* Coduri procese tehnologice */
unit = [1,nrunit ]; /* Coduri unitati productive */
qual = [1,nrqual ]; /* Coduri calitati produse */
blend = [1,nrblend]; /* Coduri elemente multime asociata */
mrint = [1,nrmrint] /* Coduri materii prime si intermediare
*/
INTEGER
spurch[purch] READ fd IS /* Coduri prod. interm. cumparate */
FOR[k IN purch] {spurch[k]>0; spurch[k]<=nrinter};
/* Multimea amestec este formata din vectorii: BLENDPF si BLENDPI */
/* blendpi(b) poate participa prin amestec la produsul blendpf(b) */
blendpf[blend] READ fd IS /* Componenta 1 a multimii amestec */
FOR[b IN blend] {blendpf[b]>=1; blendpf[b]<=nrfinal};
blendpi[blend] READ fd IS /* Componenta 2 a multimii amestec */
FOR[b IN blend] {blendpi[b]>=1; blendpi[b]<=nrinter};
blendl[blend] IS /* Indici liniarizati pentru multimea amestec */
FOR[b IN blend] blendl[b]=(blendpf[b]-1)*nrinter + blendpi[b]
REAL io[crude,mrint,proc] READ fd
/* io[c,m,p] este intrare (daca < 0.0) sau iesire (daca >=0.0) */
/* a materialului m, prin folosire tip de petrol c, pe unitate */
/* de nivel a operatiei procesului p */
INTEGER
util [unit,proc] READ fd IS FOR[u IN unit,p IN proc]
util[u,p]=ifs(util[u,p],1,0)
/* util[u,p] = 1 daca procesul p utilizeaza unitatea u,0 altfel */
REAL
cap [unit] READ fd IS FOR[u IN unit] cap[u] >= 0.0;
/* cap[u] este capacitatea initiala a unitatii u */
pricec [crude] READ fd IS FOR[c IN crude] pricec[c] > 0.0;
/* pricec[c] este pretul de cumparare pe baril al petrolului c */
pricep [purch] READ fd IS FOR[p IN purch] pricep[p] > 0.0;
/* pricep[p] pretul pe baril al intermediarului cumparat spurch[p] */
pricef [final] READ fd IS FOR[f IN final] pricef[f] > 0.0;
/* pricef[f] este pretul de vinzare baril pentru produsul final f */
cost [proc] READ fd IS FOR[k IN proc] cost[k] > 0.0;
/* cost[k] este $ pe baril in procesul k */
qmin [final,qual] READ fd IS
FOR[f IN final,q IN qual] qmin[f,q] >= 0.0;
/* Limita inferioara pe calitate la produse finale */
qmax [final,qual] READ fd IS
FOR[f IN final,q IN qual] qmax[f,q] >= 0.0;
/* Limita superioara pe calitate produsele finale */
qboth[inter,qual] READ fd IS
FOR[i IN inter,q IN qual] qboth[i,q] >= 0.0;
qcrude [crude,inter,qual] READ fd IS
FOR[c IN crude,i IN inter, q IN qual] {qcrude[c,i,q] >= 0.0;
lor(ifp(qcrude[c,i,q],0,1,0),ifp(qboth[i,q],0,1,0))=1};
attr [crude,inter,qual] IS FOR[c IN crude,i IN inter,q IN qual]
attr[c,i,q]= ifp(qcrude[c,i,q],qboth[i,q],
qboth[i,q],qcrude[c,i,q]);
/* attr[c,i,q] este marimea atributului q ce contribuie la amestec */
/* prin intermediarul i derivat din tipul de petrol c */
cpmax [crude] READ fd IS FOR[c IN crude] cpmax[c] > 0.0
/* Margine superioara a petrolului cumparat */
INTEGER
nrqminnz= SUM[f IN final,q IN qual](ifp(qmin[f,q],1,0,1));
/* Numarul elementelor qmin[f,q] <>0 */
nrqmaxnz= SUM[f IN final,q IN qual](ifp(qmax[f,q],1,0,1));
/* Numarul elementelor qmax[f,q] <>0 */
find=0; /* Variabila necesara in actiuni SEARCH */
l=1; l1=0; m=1; m1=0 /* Variabile de lucru */
RANGE
/* Domenii necesare mai departe in calcul vectori */
qminnz=[1,nrqminnz];
qminnz1=[1,nrqminnz+1];
qmaxnz=[1,nrqmaxnz];
qmaxnz1=[1,nrqmaxnz+1]
INTEGER
qminnzl[qminnz1] IS FOR[f IN final,q IN qual]
qminnzl[l]=(f-1)*nrqual+q+atr(ifp(qmin[f,q],1,0,1)+l,l);
/* Indici lineari ai perechilor (f,q) unde qmin[f,q]<>0 */
qmaxnzl[qmaxnz1] IS FOR[f IN final,q IN qual]
qmaxnzl[m]=(f-1)*nrqual+q+atr(ifp(qmax[f,q],1,0,1)+m,m)
/* Indici lineari ai perechilor (f,q) unde qmax[f,q]<>0 */
VARIABLES
InCr [crude] IS FOR[c IN crude] InCr[c] <= cpmax[c];
/* Cantitatea de petrol cumparata. Nu trebuie sa depaseasca limita */
InInt[purch,crude];
/* InInt[p,c] este cantitatea cumparata pentru */
/* derivatul spurch[p] din petrolul de tip c */
LevPr [proc,crude]; /* LevPr[p,c] este nivel proces p cu petrol tip c */
LevBl
[blend,crude];/* LevBl[f,i,c] este nivel intermediar i, derivat */
/* din petrol tip c, amestecat in produsul final f*/
Out [final]; /* Out[f] este cantitatea rezultata din produsul f*/
Revenue; /* Venit pe toate produsele finale vindute */
PurchC; /* Costul tuturor materialelor achizitionate */
OperC
/* Costul tuturor operatiilor */
OBJECTIVES
net IS net:= Revenue - PurchC - OperC
/* Venitul net rezultat din vinzari minus costuri */
MAXIMIZE
net
CONSTRAINTS
balcr [mraw,crude] IS FOR [r IN mraw, c IN crude]
balcr[r,c]:=SUM [p IN proc](io[c,r,p] * LevPr[p,c]) + InCr[c] >= 0.0;
/* Inputul pentru fiecare tip petrol din toate procesele */
/* (negativ prin conventie) trebuie sa fie acoperit din achizitii */
balin [inter,crude] IS FOR [i IN inter, c IN crude]
balin[i,c]:=SUM [p IN proc] (io[c,i+nrmraw,p] * LevPr[p,c]) +
search(i, spurch[1],find)* InInt[find,c] >=
SUM[f IN final]( atr( (f-1)*nrinter +i,m) +
search(m,blendl[1],find)*LevBl[find,c]);
/* Cantitatea fiecarui intermediar produs si cumparat trebuie */
/* sa acopere cantitatea necesara in amestec */
balfin[final] IS FOR [f IN final]
balfin[f]:= Out[f] = SUM[i IN inter,c IN crude]
(atr((f-1)*nrinter +i,m) + search(m,blendl[1],find)*LevBl[find,c]);
/* Volumul fiecarui produs final este egal cu volumul */
/* tuturor intermediarelor amestecate pentru producerea sa */
rqmin[qminnz] IS FOR[k IN qminnz] rqmin[k]:=
atr(qminnzl[k],l)+ atr((l-1)/nrqual+1,m) + /* f=m,q=l1 */
atr(l-(m-1)*nrqual,l1) + SUM[i IN inter,c IN crude]
( atr((m-1)*nrinter+i,m1) + search(m1,blendl[1],find)*
attr[c,i,l1]*LevBl[find,c]) >= qmin[m,l1] * Out[m];
/* Calitatile produselor finale nu trebuie sa scada sub minim */
rqmax[qmaxnz] IS FOR [k IN qmaxnz] rqmax[k]:=
atr(qmaxnzl[k],l)+ atr((l-1)/nrqual+1,m) + /* f=m,q=l1 */
atr(l-(m-1)*nrqual,l1) + SUM[i IN inter,c IN crude]
( atr((m-1)*nrinter+i,m1) + search(m1,blendl[1],find)*
attr[c,i,l1]*LevBl[find,c]) <= qmax[m,l1] * Out[m];
/* Calitatile produselor finale nu trebuie sa scada sub minim */
rcap[unit] IS FOR[u IN unit] rcap[u]:= SUM[p IN proc]
(util[u,p] * SUM[c IN crude] (LevPr[p,c])) <= cap[u];
/* Utilizarea unei unitati de catre toate procesele */
/* nu poate sa depaseasca capacitatea specifica a ei*/
dRev IS dRev :=
Revenue = SUM[f IN final] (pricef[f] * Out[f]);
/* Venitul este suma rezultata din valoarea produselor finale */
dPurchC IS dPurchC:= PurchC = SUM[c IN crude](pricec[c] * InCr[c]) +
SUM[p IN purch, c IN crude] (pricep[p]* InInt[p,c]);
/* Total cost al achizitiilor este costul pe achizitia de petrol */
/* plus costul produselor intermediare care sunt cumparate */
dOperC IS dOperC:= OperC = SUM[p IN proc] (cost[p] * SUM[c IN crude] (LevPr[p,c]))
/* Costul total de operare este suma costurilor pentru toate */
/* nivelele de proces ale tipurilor de petrol */
END