/*----------------------------------------------------------------------------*/
/* Data Creerii
: 14 Aprilie 1997
*/
/* Data Ultimei Modificari
: 02 Octombrie 1997
*/
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Model preluat din
exemplele AMPL.
*/
/*----------------------------------------------------------------------------*/
/* Acest model determina
un plan de productie si distributie care satisface */
/* cererea pentru o
multime de bunuri. Formularea este motivata de experienta */
/* multor producatori
din Statele Unite ale Americii.
*/
/*
*/
/* O companie
produce un numar de produse in citeva centre de fabricatie.
*/
/* Produsele sunt transportate
la anumite centre de distributie. Produsele pot*/
/* fi transportate mai
departe la depozitele de marfa pentru satisfacerea unor*/
/* cereri.
*/
/* Centrele
de fabricatie sunt din multimea centrelor de distributie, iar
*/
/* acestea din urma
sunt elemente din multimea depozitelor de marfa.
*/
/* Pe o
anumita ruta se poate impune o restrictie de transport in sensul ca */
/* se permite acesta
numai daca se transporta o anunita cantitate minima. Se */
/* cere de asemenea
ca pe orice ruta sa nu se depaseasca un cost maxim.
*/
/* Procesul
de productie impune restrictii capacitati - timpi de productie. */
/* Functia
de cost se refera la intregul proces de fabricatie precum si la */
/* operatiunile de distribuire
si transport produse.
*/
/* Acest
prototip poate fi instantiat in trei moduri prin selectare fisier
*/
/* cu date pentru 3,
8 si 13 produse : dist03.dat, dist08.dat si dist13.dat. */
/* Rezulta astfel trei
modele diferite modificind numai instructiunea FILE. */
/*----------------------------------------------------------------------------*/
FILE
fdist="dist13.dat" /* Fisier cu date asociat acestui prototip.*/
/* MULTIMI IMPLICATE IN TRANSPORT SI DATE AFERENTE */
/*-------------------------------------------------*/
INTEGER nrwhse READ fdist IS nrwhse > 1
/* Numar depozite de marfa din care se satisface cererea de produse */
RANGE whse=[1,nrwhse] /* Domeniu coduri interne pentru aceste depozite */
INTEGER whses[whse] READ fdist IS FOR[w IN whse]
{whses[w]>=1; whses[w]<=1000}
/* Multimea de coduri externe pentru depozitele de marfa.*/
/* Domeniul [1,1000] poate fi modificat dupa necesitati. */
INTEGER nrdctr READ fdist IS { nrdctr >=1; nrdctr <nrwhse}
/* Numar centre distributie */
RANGE dctr=[1,nrdctr] /* Domeniu coduri interne centre distributie */
INTEGER find=0; /* Variabila de lucru necesara pentru functia SEARCH */
dctrs[dctr] READ fdist IS FOR[d IN dctr]
dctrs[d]= SEARCH(dctrs[d],whses[1],find)*dctrs[d]
/* Multimea de coduri externe pentru centrele de distributie. */
/* Testul de apartenenta la depozitele de marfa este facut cu*/
/* functia SEARCH care returneaza 1= este, 0=nu este = eroare */
REAL sc [whse,dctr] READ fdist IS FOR [w IN whse,d IN dctr] sc[w,d]>=0.0
/* Costul de transport de la dctr la whse in $/100 lb (livra) */
INTEGER
msr [whse,dctr] READ fdist IS FOR[w IN whse,d IN dctr]
msr[w,d]=Ifs(msr[w,d],1,0)
/* Restrictii de aprovizionare directa. Daca msr[w,d] = 1 este */
/* permis transportul direct a unei cantitati minime pe ruta : */
/* centru distributie dctrs[d] ----> depozit de marfa whses[w] */
REAL dsr [dctr] READ fdist IS FOR[d IN dctr] dsr[d] >=0.0;
/* Minimul de transport direct cerut pe ruta de mai sus */
huge READ fdist IS huge > 0.0
/* Maximul cost permis pe o ruta de transport */
/* MULTIMI DE PLANIFICARE SI DATE AFERENTE */
/*-----------------------------------------*/
INTEGER nrfact READ fdist IS {nrfact >0; nrfact<= nrdctr}
/* Numar centre de fabricatie */
RANGE fact=[1,nrfact]
/* Domeniu codurilor interne pentru centrele de fabricatie */
INTEGER facts[fact] READ fdist IS FOR[f IN fact]
facts[f]=SEARCH(facts[f],dctrs[1],find)*facts[f]
/* Multimea codurilor externe a centrelor de fabricatie.
*/
/* Solicita testul de apartenenta la centrele de distributie.*/
REAL rtmin READ fdist IS rtmin >= 0.0;
/* Timp minim regulat pe schimb si pe toate centrele de fabricatie */
rtmax READ fdist IS rtmax >= rtmin;
/* Timp maxim regulat pe schimb si pe toate centrele de fabricatie */
otmin READ fdist IS otmin >= 0.0;
/* Timp minim suplimentar la toate centrele de fabricatie */
otmax READ fdist IS otmax >= otmin;
/* Timp maxim suplimentar la toate centrele de fabricatie */
rmin[fact] READ fdist IS FOR[f IN fact] rmin[f] >= 0.0;
/* Timp minim (mediu) regulat si pe centre fabricatie */
rmax[fact] READ fdist IS FOR[f IN fact] rmax[f] >= rmin[f];
/* Timp maxim (mediu) regulat si pe centre fabricatie */
omin[fact] READ fdist IS FOR[f IN fact] omin[f] >= 0.0;
/* Timp minim suplementar pe centre de fabricatie */
omax[fact] READ fdist IS FOR[f IN fact] omax[f] >= omin[f];
/* Timp maxim suplementar pe centre de fabricatie */
hd[fact] READ fdist IS FOR[f IN fact] hd[f]>= 0.0;
/* Timp regulat in ore pe zi lucratoare */
dp[fact] READ fdist IS FOR[f IN fact] dp[f] > 0.0
/* Zile lucratoare in perioada curenta de plan */
/* MULTIMI LEGATE DE PRODUCTIE SI DATE AFERENTE */
/*----------------------------------------------*/
INTEGER nrprod READ fdist IS nrprod >0 /* Numar produse fabricate */
RANGE prod = [1,nrprod] /* Domeniu coduri interne produse fabricate */
REAL wt [prod] READ fdist IS FOR[p IN prod] wt[p]>0.0;
/* Greutatea produselor in 100 lb / 1000 cazuri */
cpp[prod] READ fdist IS FOR[p IN prod] cpp[p]>0.0;
/* Cazuri al produselor pe paleta de transport */
tc [prod] READ fdist IS FOR[p IN prod] tc[p]>=0.0;
/* Costul de transport in $ / 1000 cazuri */
pt [fact,prod] READ fdist IS FOR[f IN fact,p IN prod] pt[f,p] >= 0.0;
/* Timp necesar in producerea 1000 cazuri */
rpc [fact,prod] READ fdist IS FOR[f IN fact,p IN prod] rpc[f,p] >=0.0;
/* Costul productiei pe timp regulat , in $ / 1000 cazuri */
opc [fact,prod] READ fdist IS FOR[f IN fact,p IN prod] opc[f,p] >= 0.0
/* Costul productiei pe timp suplementar , in $ / 1000 cazuri */
/* DEMAND SETS AND PARAMETERS */
/*----------------------------*/
REAL dt [prod] READ fdist IS FOR[p IN prod] dt[p] >= 0.0;
/* Cererile totale de produse, in 1000s */
ds [whse,prod] READ fdist IS FOR[w IN whse,p IN prod]
{ ds[w,p] >= 0.0; ds[w,p] <= 1.0};
/* Istoric al cererilor, necesar in partajarea pe depozite */
dstot[prod] IS FOR[p IN prod] dstot[p]= SUM [w IN whse](ds[w,p]);
/* Total cereri partajate; ar trebui sa fie 1,sunt si exceptii */
dem[prod,whse] IS FOR[p IN prod, w IN whse]
dem[p,w]= dt[p] * ds[w,p] / dstot[p]
/* Cererile proiectate sa fie satisfacute, in 1000s */
INTEGER rtl[dctr,whse] IS FOR[d IN dctr,w IN whse]
rtl[d,w]=And(
And(Ifp(dctrs[d]-whses[w],1,0,1),
Ifp(sc[w,d]-huge,1,0,0)
),
And(Lor(search(whses[w],dctrs[1],find),
Ifp(SUM[p IN prod](dem[p,w]),0,0,1)
),
Not(And(msr[w,d],
Ifp(SUM[p IN prod](1000*dem[p,w]/cpp[p])
-dsr[d],1,0,0)
)
)
)
)
/* Daca rtl[d,w]=1 este permis transportul de la dctr d la whse w */
INTEGER nrrt=SUM[d IN dctr,w IN whse](rtl[d,w])
/* Numarul combinatiilor pentru care este permis transportul de sus */
RANGE rt=[1,nrrt];rte=[1,nrrt+1] /* Domenii legate de caile permise */
INTEGER h=1 /* Variabila de lucru in calculul rtindl */
INTEGER rtindl[rte] IS FOR[d IN dctr,w IN whse]
rtindl[h]=atr(h+ifs(rtl[d,w],1,0),h)+(d-1)*nrwhse+w
/* Indicii liniarizati ai rutelor permise */
INTEGER nrrpcz = SUM[f IN fact,p IN prod](Ifp(rpc[f,p],0,1,0))
/* Numarul in care rpc[f,p] este zero */
RANGE rpcz=[1,nrrpcz];rpcze=[1,nrrpcz+1]
INTEGER l=1 /* Variabila de lucru */
INTEGER rpczindl[rpcze] IS FOR[f IN fact,p IN prod]
rpczindl[l]=atr(l+Ifp(rpc[f,p],0,1,0),l)+(f-1)*nrprod+p
/* Indici liniarizati pe situatiile rpc[f,p]=0 */
INTEGER nropcz = SUM[f IN fact,p IN prod](Ifp(opc[f,p],0,1,0))
/* Numarul in care opc[f,p] este zero */
RANGE opcz=[1,nropcz];opcze=[1,nropcz+1]
INTEGER m=1 /* Variabila de lucru */
INTEGER opczindl[opcze] IS FOR[f IN fact,p IN prod]
opczindl[m]=atr(m+Ifp(opc[f,p],0,1,0),m)+(f-1)*nrprod+p
/* Indici liniarizati pentru cazurile opc[f,p]=0 */
VARIABLES
Rprd[prod,fact] IS FOR[j IN rpcz]
Rprd[atr(rpczindl[j],h)+ atr((h-1)/nrprod+1,m)+h-(m-1)*nrprod,m]=0.0;
/* Timpul regulat de productie pe fiecare produs si*/
/* fiecare centru de fabricatie,in 1000s de cazuri */
Oprd[prod,fact] IS FOR[j IN opcz]
Oprd[atr(opczindl[j],h)+atr((h-1)/nrprod+1,m)+h-(m-1)*nrprod,m]=0.0;
/* Timpul suplementar de productie pe fiecare produs */
/* si fiecare centru de fabricatie,in 1000s */
Ship[prod,rt];
/* Cantitatea transportata pe fiecare ruta permisa in 1000s */
Trans[prod,dctr]
/* Cantitatea transportata la fiecare centru distributie in 1000s */
OBJECTIVES
cost IS cost:= SUM [p IN prod, f IN fact] (rpc[f,p] * Rprd[p,f]) +
SUM [p IN prod, f IN fact] (opc[f,p] * Oprd[p,f]) +
SUM [p IN prod, dw IN rt] (sc[atr(rtindl[dw],h) +
atr((h-1)/nrwhse+1,m) + h-(m-1)*nrwhse,m] * wt[p] * Ship[p,dw]) +
SUM [p IN prod, d IN dctr] (tc[p] * Trans[p,d])
/* Costul total pe productie regulata, pe productie in ore */
/* suplementare, transport la depozite si centre distributie */
MINIMIZE
cost
CONSTRAINTS
rtlim IS rtlim:= SUM [p IN prod, f IN fact]
((pt[f,p] * Rprd[p,f]) / (dp[f] * hd[f])) IN [rtmin,rtmax];
/* Total pe productie regulata trebuie sa fie in limitele impuse */
otlim IS otlim:= SUM [p IN prod, f IN fact]
(pt[f,p] * Oprd[p,f]) IN [otmin,otmax];
/* Total pe productie in afara ore program sa fie in limitele impuse */
rlim[fact] IS FOR[f IN fact] rlim[f]:= SUM [p IN prod]
((pt[f,p] * Rprd[p,f]) / (dp[f] * hd[f])) IN [rmin[f],rmax[f]];
/* Total productie regulata pe fiecare centru de */
/* fabricatie trebuie sa fie intre limitele impuse */
olim[fact] IS FOR[f IN fact] olim[f]:= SUM [p IN prod]
(pt[f,p] * Oprd[p,f]) IN [omin[f],omax[f]];
/* Total pe productie in afara ore program si pe fiecare */
/* centru de fabricatie trebuie sa fie intre limitele impuse */
bal[prod,whse] IS FOR[p IN prod, w IN whse] bal[p,w]:= SUM[d IN dctr]
(atr(rtl[d,w]*((d-1)*nrwhse+w),h)+search(h,rtindl[1],find)*Ship[p,find]) +
search(whses[w],facts[1],find) * (Rprd[p,find] + Oprd[p,find])= dem[p,w] +
search(whses[w],dctrs[1],h) *
SUM[v IN whse](atr(rtl[h,v]*((h-1)*nrwhse+v),m)+
search(m,rtindl[1],find)*Ship[p,find]);
/* Balanta materiala a produselor si pe fiecare depozit de marfa */
/* Cantitatea importata
de depozit de la centrele de distributie */
/* plus cantitatea
fabricata aici daca depozitul este si centru */
/* de fabricatie
trebuie sa fie egala cu cerinta pe acel produs */
/* plus ceea ce
a transmis la alte depozite daca depozitul este */
/* si centru de
distributie.
*/
trdef[prod,dctr] IS FOR[p IN prod, d IN dctr] trdef[p,d]:= Trans[p,d] >=
SUM[w IN whse]((atr(rtl[d,w]*((d-1)*nrwhse+w),m) +
search(m,rtindl[1],find))*Ship[p,find]) -
search(dctrs[d],facts[1],find) * (Rprd[p,find]+Oprd[p,find])
/* Cantitatea de produs transportata la un centru de distributie */
/* trebuie sa fie mai mare sau egala cu ceea ce s-a transportat */
/* de aici in afara la depozite minus productia proprie daca este*/
/* si centru de fabricatie.
*/
END