MODEL  Dist

/*----------------------------------------------------------------------------*/
/* 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


Return la Tabela Modele