/*----------------------------------------------------------------------------*/
/* Data Creare
: 17 Martie 1997
*/
/* Data Modificare :
21 Octombrie 1997
*/
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Sursa : Exemple AMPL.
*/
/*
*/
/*
Modelul determina un plan de productie care se trebuie sa respecte */
/* restrictii de inventar
si sa satisfaca cererile de produse in modul cel mai*/
/* economic.Formularea
este motivata de experienta multor producatori din SUA */
/*
*/
/*
Prezentul model este in fapt un prototip care se poate instantia in*/
/* trei moduri prin
selectia fisierului de date atasate dintre : prod03.dat, */
/* prod08.dat si prod13.dat
rezultind de fiecare data un model concret.
*/
/*----------------------------------------------------------------------------*/
FILE fprod="prod03.dat"
/* DATE PENTRU PERIOADE SI ORIZONT DE LUCRU */
INTEGER
first READ fprod IS first > 0; /* Prima perioada de productie */
last READ fprod IS last > first /* Ultima perioada de productie */
RANGE
timeph = [ first, last]; /* Orizont de planificare */
timephse = [ first, last+1];/* Orizont extins superior */
timephie = [ first-1, last] /* Orizont extins inferior */
/* DATE DESPRE
PRODUCTIE */
INTEGER nrprd READ fprod IS nrprd >0 /* Numar produse finite */
RANGE prd = [ 1, nrprd] /* Domeniu coduri interne produse */
REAL
pt[ prd ] READ fprod IS FOR [ k IN prd ] pt [k] >0;
/* Ore-echipa necesare in producerea a 1000 unitati */
pc[ prd ] READ fprod IS FOR [ k IN prd ] pc [ k] >0
/* Cost productie pe 1000 unitati used to compute inventory and shortage
costs? */
/* DATE PRIVIND
ANGAJATII */
INTEGER
cs READ fprod IS cs > 0; /* Lucratori pe echipa */
sl READ fprod IS sl > 0 /* Timp regulat pe schimb */
REAL
rtr READ fprod IS rtr >0; /* Salariu pe ora in program normal */
otr READ fprod IS otr >rtr/* Salariu pe ora peste program normal */
/* Crews employed at start of first period */
INTEGER
iw READ fprod IS iw >=0
/* Echipe utilizate la inceputul primei perioade */
/* Regular working days IN a production period */
REAL
dpp[timeph] READ fprod IS FOR [k IN timeph] dpp[k] > 0;
/* Zile normale intr-o perioada de productie */
ol[timeph] READ fprod IS FOR [k IN timeph] ol[k]>= 0;
/* Maxim ore-echipa peste program normal in perioada */
cmin[timeph] READ fprod IS FOR [k IN timeph] cmin[k]>= 0;
/* Limita inferioara pe medie angajat in perioada */
cmax[timeph] READ fprod IS FOR [k IN timeph] cmax[k]>= cmin[k]
/* Limita superioara pe medie angajat in perioada */
INTEGER
hc[timeph] READ fprod IS FOR [k IN timeph] hc[k] >= 0;
/* Cost de penalizare pentru angajarea unei echipe */
lc[timeph] READ fprod IS FOR [k IN timeph] lc[k] >= 0
/* Cost de penalizare pentru disponibilizarea unei echipe */
/* DATE DESPRE
CERERE DE PRODUSE */
REAL
dem [timephse,prd] READ fprod IS
FOR [j IN timephse,k IN prd] dem[j,k] >= 0
/* Cereri (in 1000s) de satisfacut din productia curenta si stoc */
INTEGER
pro[timephse,prd] READ fprod IS
FOR [j IN timephse,k IN prd] pro[j,k] = ifs(pro[j,k],1,0)
/* Indicator daca produsul este o promotie speciala in perioada */
/* DATE DE INVENTAR
SI LIPSURI PRODUSE */
REAL
rir READ fprod IS rir >= 0;
/* Proportia a unei cereri nepromovate care trebuie sa fie in stoc */
/* la precedenta perioada */
pir READ fprod IS pir >= 0
/* Proportia a unei cereri promovate care trebuie sa fie in stoc */
/* la precedenta perioada */
/* Upper limit on number of periods that any product may sit in */
/* inventory */
INTEGER life READ fprod IS life > 0
/* Limita superioara a numarului de perioade cit este permis ca */
/* un produs sa ramina in stoc */
REAL cri[prd] READ fprod IS FOR [k IN prd] cri[k] > 0;
/* Cost de stocare pe 1000 unitati */
crs[prd] READ fprod IS FOR [k IN prd ] crs[k]> 0;
/* Cost de lipsa produs pe 1000 unitati */
iinv[prd] READ fprod IS FOR [k IN prd ] iinv[k]>= 0;
/* Stoc la startul
primei perioade; asteptare necunoscuta */
iil[prd,timeph] IS FOR [p IN prd,t IN timeph]
iil[p,t] = Dip(iinv[p],SUM [m IN [first,t]](dem[m,p]));
/* Stoc initial disponibil pentru alocare la sfirsit de perioada */
minv[prd,timeph] IS FOR [p IN prd,t IN timeph]
minv[p,t] = ifs( pro[t+1,p], pir, rir) *dem[t+1,p]
/* Limita inferioara pe stoc la sirsit de perioada */
VARIABLES
Crews[timephie] IS {Crews[first-1] = iw;
FOR [t IN timeph] Crews[t] IN [cmin[t] , cmax[t]] };
/* Number mediu de echipe utilizate in fiecare perioada */
Hire[timeph]; /* Echipe angajate din precedente la perioada curenta */
Layoff[timeph]; /* Echipe disponibilizate pentru perioada curenta */
Rprd[prd,timeph]; /* Productia in program normal si in 1000s */
Oprd[prd,timeph]; /* Productia peste program si in 1000s */
Inv [prd,timeph,[1,life]]IS
FOR[ p IN prd,v IN [1,life-1],a IN [v+1,life]]Inv[p,first+v-1,a] = 0;
/* In perioada v (incepind de la prima) nici un stoc mai mult */
/* de vechime v perioade. Stocul initial este tratat separat */
/* Inv[p,t,a] este cantitate de produs p care asteapta in stoc*/
/* de a perioade incluzind si perioada t */
Short [prd,timeph]
/* Cereri nesatisfacute la sfirsit de perioada */
OBJECTIVES
cost
IS cost:= SUM [t IN timeph] (rtr * sl * dpp[t] * cs * Crews[t]) +
SUM [t IN timeph] (hc[t] * Hire[t]) +
SUM [t IN timeph] (lc[t] * Layoff[t]) +
SUM [t IN timeph, p IN prd](otr * cs * pt[p] * Oprd[p,t]) +
SUM [t IN timeph, p IN prd, a IN [1,life]]
(cri[p] * pc[p] * Inv[p,t,a]) +
SUM [t IN timeph, p IN prd] (crs[p] * pc[p] * Short[p,t])
/* Salarii regulate si peste program pentru echipe, plus penalizari */
/* pe angajari sau sau disponibilizari de echipe, plus costurile de */
/* stocare sau penalizari la cereri nesatisfacute la timp.Toate alte*/
/* costuri sunt presupuse ca depind de stocul si cererile initiale
*/
/* si de aceea n-au fost incluse explicit aici. */
MINIMIZE
cost
CONSTRAINTS
rlim [timeph] IS FOR [t IN timeph] rlim[t]:=
SUM [p IN prd] (pt[p] * Rprd[p,t]) <= sl * dpp[t] * Crews[t];
/* Ore necesare pentru productia regulata intr-o perioada */
/* nu pot depasi orele disponibile pe toate schimburile */
olim [timeph] IS FOR [t IN timeph] olim[t]:=
SUM [p IN prd](pt[p] * Oprd[p,t]) <= ol[t];
/* Orele neregulate dintr-o perioada nu poate depasi limita impusa */
empl [timeph] IS FOR [t IN timeph] empl[t]:=
Crews[t] = Crews[t-1] + Hire[t] - Layoff[t];
/* Balanta disponibilului de forta de munca */
dreqf [prd] IS FOR [p IN prd] dreqf[p]:= Rprd[p,first] + Oprd[p,first] +
Short[p,first]- Inv[p,first,1] = Dip(dem[first,p], iinv[p]);
/* Balanta productiei,stocului,restantelor si cererilor de produse */
/* la prima perioada de productie */
dreq [ prd, [first+1,last]] IS FOR[ p IN prd, t IN [first+1,last]]
dreq[p,t]:= Rprd[p,t] + Oprd[p,t] + Short[p,t] - Short[p,t-1] +
SUM [a IN [1,life]] (Inv[p,t-1,a] - Inv[p,t,a]) =
Dip(dem[t,p],iil[p,t-1]);
/* Balanta productiei,stocului,restantelor si cererilor de produse */
/* in perioadele de productie urmatoare la prima */
ireq [ prd, timeph] IS FOR [p IN prd,t IN timeph]
ireq[p,t]:= SUM [a IN [1,life]] (Inv[p,t,a]) + iil[p,t] >= minv[p,t];
/* Stocul la sfirsit de perioada satisface un minim */
ilimf [prd,timeph] IS FOR [p IN prd, t IN timeph]
ilimf[p,t]:= Inv[p,t,1] <= Rprd[p,t] + Oprd[p,t];
/* Noul stoc nu poate depasi productia din cea ma recenta perioada */
ilim [prd, [first+1,last], [2,life]] IS
FOR [p IN prd,t IN [first+1,last], a IN [2,life]]
ilim[p,t,a]:= Inv[p,t,a] <= Inv[p,t-1,a-1]
/* Stocul ramas din perioada (t+1)-p poate numai descreste */
END