Decision Optimization

Decision Optimization

Delivers prescriptive analytics capabilities and decision intelligence to improve decision-making.

 View Only
  • 1.  File not found error

    Posted Sun November 04, 2018 08:35 PM

    Originally posted by: SanaeB


    Hi Alex,

    When i run a config, i have the error "file not found". I already red what you answered to other users and i can tell you that:

    • The program worked well, and it started to display this error knowing that i have'nt change the work directory nor any significant code in the model
    • I tried with oplrun and I have the following error with opl run:  <<< setup

      *** ERROR[INTERFACE_000] at 131:1-1:1 Cas plusieurs commandes.mod: Fichier "C:\Users\Sanae\opl\Cas plusieurs commandes\Cas plusieurs commandes.mod" non trouvé.
      main returns -2 <<< main 

    • i use and always have used cplex 12.8
    • Here is my workplace: C:\Users\Sanae\AppData\Roaming\IBM\ILOG\CPLEX_Studio128\workspace
    • Here is the directory when the data file and mod file are stored: C:\Users\Sanae\opl\Cas plusieurs commandes
    • i tried creating  a new project with no space in the names of the project, the config, .mod and .ops ( i copied pasted the content of data and model) and it gave me the same error
    • i dont have this error with orther configurations in different projects
    • I have an academic access to opl

    .MOD:

    /*********************************************
     * OPL 12.8.0.0 Model
     * Author: Sanae
     * Creation Date: 2018-09-18 at 11:06:13
     *********************************************/
     
    //DONNEES
    int NE=...; // Nombre d'Employés
    float TH=...; // Taux horaire de chaque employé
    int NC=...; //Nombre de commandes
    setof(int) COMMANDES= asSet(1..NC); //Ensemble des commandes
    int NT[COMMANDES]=...;// Nombre de tâches pour chaque commande
    int NU[COMMANDES]=...;// Nombre d'unités par commande'
    int NTMax=max(c in COMMANDES) NT[c]; // permet de calculer le nombre maximal de tâches toutes commandes confondues
    int NTMin=min(c in COMMANDES) NT[c]; // on pourrait l'utiliser pour s'assurer que les données en entrée sont cohérentes: NSmin doit etre inférieur ou egal à NTMin. pas de lien avec NECMin car des employes peuvent se partager une tache et une tache peut être partagée par plusieurs employés
    setof(int) TASKS[c in COMMANDES]= asSet(1..NT[c]);// liste des tâches d'une commmande'
    int NSMin=...;// Nombre de stations minimales (le même pour chacune des commandes)
    assert NTMin>=NSMin;// permet de s'assurer que la ligne ayant le moindre nombre de tâche est coherente avec la contrainte de nombre de stations minimales'
    int NECMin=...;
    int NECMax=NE-(NC-1)*maxl(NSMin,NECMin); // Valider Nombre d'Employés maximal par ligne, permet de borner les l et les k. LA vraie formule serait NECMax=NE-(NC-1)*max(NSMin,NECMin)
    tuple tasksbis {int c;int i; int j;};
    {tasksbis} TASKSBIS= {<c,i,j>|c in COMMANDES, i in TASKS[c], j in TASKS[c] union {NT[c]+1} : j>=i+1}; // l'ensemble des couples de taches d'une commande composé de chaque tache et ses successeurs'
    tuple employesbis {int k; int l;}; 
    {employesbis} EMPLOYESBIS= {<k,l>|k,l in 1..NECMax : l>=k && k>=1};
    float t[COMMANDES][1..NTMax]=...; // temps de la tâche i (i ayant une positiion 1 à NTmax) de la commande c ayant NT commandes
    assert forall(c in COMMANDES, i in 1..NTMax) (i>NT[c]=>t[c][i]==0);// s'assure que les tâches dont l'index depasse NT pour une commande ont un temps nul
    float ts [c in 1..NC][i in 1..NTMax][j in 1..NTMax]=sum (l in i..j)(t[c][l]);// temps entre deux taches d'une commande ts cij: doit être du même format que t
    float delai[COMMANDES]=...;// donnée ajoutée délai maximal pour chaque commande en heures
    float ProductiviteCMin=...;
    float ProductiviteUMin=...;
    setof (string) TYC={"Ref","NSMin","NECMin","NE","NU","t","NT","delai", "ProducC", "ProducU"};// Utile pour indiquer dans le fichier output le type de contrainte des instances utilisés
     
    // VARIABLES
    dvar float+ CT; // coût total à minimiser
    dvar int NEC[COMMANDES];// Le nombre d'employés affecté à chaque commande / à voir si ce n'Est pas pluutôt une variable d'expression
    dvar boolean X[<c,i,j> in TASKSBIS][<k,l> in EMPLOYESBIS];// déclaration des variables binaires Xcijkl
    dvar float+ TCP[COMMANDES][1..NECMax]; // Valider la formulation de la vriable TCPcl (temps de cycle partiel de la ligne de la commande c lorsque l emoloyés y sont affectés)
    dexpr float TC[c in COMMANDES] = sum(l in 1..NECMax)TCP[c][l];// équivaut contrainte 15 // Calcul du temps de cycle (avec la solution retenue) d'une ligne a partir des temps de cycle de la ligne avec l employés (TCP)'
    dexpr int NS[c in COMMANDES]=sum (i in 1..NT[c], j in i+1..NT[c]+1, k in 1..NECMax, l in k..NECMax ) X[<c,i,j>][<k,l>]; // est-ce que c'Est pas bizarre ici de faire varien c aussi dans le tuple TASKSbis alors que c a deja ete predeterminé pour NS'
    dvar boolean Z[COMMANDES][1..NECMax]; //Valider la formulation de la variable, est vrai lorsque l employés sont affectés à la commande c
    dvar float coutP[c in COMMANDES][l in 1..NECMax]; // cout de la commande avec l employés qui y sont affectés, sera nul avec les nombres d'employés non retenus'
    dexpr float coutC[c in COMMANDES]=sum(l in 1..NECMax) coutP[c][l]; // coût de la commande
    dexpr float TPr[c in COMMANDES]=((NU[c])*TC[c])/3600;// temps de production total de la commande en heures car le temps de cycle sera donné en secondes- Hypothèse : toutes les unités prennent le même temps de fabrication: le temps de cycle.
    dexpr float ProductiviteS[<c,i,j> in TASKSBIS][<k,l> in EMPLOYESBIS]=(X[<c,i,j>][<k,l>]*ts[c][i][j-1]/k)/TC[c];// Valider. Calcul de la productivité de la station cijkl.
    dexpr float ProductiviteC[c in COMMANDES]= sum (i in 1..NT[c], j in i+1..NT[c]+1, k in 1..NECMax, l in k..NECMax) k/l*ProductiviteS[<c,i,j>][<k,l>];//VALIDER Productivité de la commande c. N'accepte pas que je mette NEC en division'
    dexpr float ProductiviteU=(sum (c in COMMANDES) ProductiviteC[c]*NEC[c])/sum (c in COMMANDES)NEC[c];
     
    //FONCTION OBJECTIF
    minimize CT;
     
    // CONTRAINTES
     
    subject to {
     
    forall (c in COMMANDES)sum (j in 2..NT[c]+1, k in 1..NECMax, l in k..NECMax)X[<c,1,j>][<k,l>]==1; // Contrainte 9
    forall (c in COMMANDES,i in asSet(2..NT[c]), l in 1..NECMax) sum (j in 1..(i-1)) sum (k in 1..l)X[<c,j,i>][<k,l>]==sum(j in (i+1)..(NT[c]+1))sum(k in 1..l)X[<c,i,j>][<k,l>]; // Contrainte 10
    forall (c in COMMANDES) NEC[c]==sum(i in 1..NT[c], j in i+1..NT[c]+1, k in 1..NECMax, l in k..NECMax) k*X[<c,i,j>][<k,l>];// premiere moitié de la contrainte 11 // Valider variation début et de fin de k. es fois c'est k qui est en fonction de l et des fois c l qui en fonction de k'
    forall (c in COMMANDES) NEC[c]== sum(j in 2..NT[c]+1, k in 1..NECMax, l in k..NECMax) l*X[<c,1,j>][<k,l>]; // 2ème  moitié de la contrainte 11 // valider  variation début et fin de k. Des fois c'est k qui est en fonction de l et des fois c l qui en fonction de k'
    sum (c in COMMANDES) NEC[c]<=NE; // Contrainte 12
    forall (c in COMMANDES, i in 1..NT[c], j in i+1..NT[c]+1, k in 1..NECMax, l in k..NECMax) X[<c,i,j>][<k,l>]*ts[c][i][j-1]/k<=TCP[c][l];// Contrainte 13 // Valider les intervalles de k et l
    forall (c in COMMANDES, l in 1..NECMax) TCP[c][l]<=ts[c][1][NT[c]]*sum (i in 1..NT[c], j in i+1..NT[c]+1, k in 1..l) X[<c,i,j>][<k,l>];// Contrainte 14 // Valider cette borne
    forall (c in COMMANDES, i in 1..NT[c], j in i+1..NT[c]+1) sum(k in 1..NECMax, l in k..NECMax)X[<c,i,j>][<k,l>]<=1; // Contrainte 16, pas sure que cette contrainte est nécessaire
    forall (c in COMMANDES, l in 1..NECMax) sum(k in 1..l, j in 2..NT[c]+1)X[<c,1,j>][<k,l>]==Z[c][l]; // Contrainte 17
    forall (c in COMMANDES, l in 1..NECMax) coutP[c][l]<=Z[c][l]*ts[c][1][NT[c]]*l*TH/3600*NU[c]; // Contrainte 19 // Valider cette borne
    forall (c in COMMANDES, l in 1..NECMax) coutP[c][l]>=TCP[c][l]*l*TH/3600*NU[c]; //Contrainte 20
    CT==sum (c in COMMANDES, l in 1..NECMax)coutP[c][l]; // Contrainte 21
    forall (c in COMMANDES) NS[c]>=NSMin; // Contrainte ajoutée pour controle le nombre minimal de station par ligne
    forall (c in COMMANDES) NEC[c]>=NECMin; // Contrainte ajoutée pour controle le nombre minimal d'employés par ligne'
    forall (c in COMMANDES) TPr[c]<=delai[c]; // contrainte ajoutée pour tenir en compte le délai de chaque commande. Exprimee en heures
    //forall (c in COMMANDES) ProductiviteC[c]>=ProductiviteCMin;
    //ProductiviteU>=ProductiviteUMin;
    }
     
    //Main: base prise à partir de sum basic model.mod
    main {
      var v; // pour décrire les fichiers de data. Indicateur de la position dans l'ensemble TYC (de 0 à 9 car 10 types de contraintes)
      var tyc; // pour décrire les fichiers de data Indicateur de la valeur de tyc (En fonctionde la position spécifiée dans l'ensemble TYC')
      var dc; // pour décrire les fichiers de data. indicateur du degré de contrainte, de 0 à 3 mais tous les degrées n'Existent pas pour tous les types de contraintes. Voir si cela pose problème'
      var nc; // pour décrire les fichiers de data. indicateur de NC ()nombre de lignes(Commandes)) (peut prendre la valeur 2, 6, ou 10) Voir si cela marche ou bien il faut leur assigner des positions
      var cfg; // pour décrire les fichiers de data. indicateur de quel numéro de configuration de tâche (de 1 à 10)
      var status;
      var before;
      var after;
      var totaltime;
      var source = new IloOplModelSource("Cas plusieurs commandes.mod");
      var cplex = new IloCplex(); 
      var def = new IloOplModelDefinition(source);       
      var opl1 = new IloOplModel(def,cplex); 
      var data = new IloOplDataSource("Ref_0_2_1.dat"); // juste pour initialiser la lecture des données
      opl1.addDataSource(data); 
      opl1.generate(); 
      for (v=0; v=1; v++) //indique la position dans l'ensemble de type de contraintes
      {
      tyc=Opl.item(opl1.TYC,v);
      var f = new IloOplOutputFile(tyc+"_"+"Output.txt");
     
      //Definition de paramètres// Cette section a été gardée telle quelle du code d'origine
     
     f.writeln("parallelmode = \t ",cplex.parallelmode); 
      f.writeln("threads = \t ",cplex.threads); 
      //cplex.tilim = 1200;
      f.writeln("time limit = \t", cplex.tilim); 
      //cplex.nodefileind = 3;
      f.writeln("nodefileind = \t", cplex.nodefileind);
     //cplex.workmem = 4096.0;
      f.writeln("workmem = \t", cplex.workmem);
      //cplex.symmetry = -1; 
      f.writeln("symmetry = \t", cplex.symmetry);
     //cplex.workdir="F:/IBM/ILOG/Basic Model"; // ou il stocke les noeuds: // A remplacer par? "C:\Users\Sanae\AppData\Roaming\IBM\ILOG\Repertoire modele de base"  les barres sont inversées
      cplex.workdir="C:/Users/Sanae/opl/Cas plusieurs commandes"
      f.writeln("\t Numero Instance \t Degre de contrainte \t Numero configuration \t NC \t NE \t NU \t NSMin \t NECMin \t delai \t Cout Total (CT) \t coutC ©\t NEC © \t TC © (Temps de cycle)\t NS © \t TPr © \t ProductiviteC© \t ProductiviteU \t Statut \t Temps de resolution \t BestLB \t Detail statut \t Nnodes\t TCP \t ");
     
      for (dc=0; dc<=0; dc++) //indique, dans le titre du fichier .dat, le degré de la contrainte mais ce degré n'est pas applicable a tous les types de contraintes'
    {
      for (nc=2; nc<=2; nc+=4) // Valider Formulation. indique, dans le titre du fichier .dat, le nombre de comande mais ce derniers prend uniquement 3 valeur 2,6 et 10
      {
        for (cfg=1; cfg<=4; cfg++)
      {
      cplex = new IloCplex(); 
      /*f.writeln("parallelmode = \t ",cplex.parallelmode); 
      f.writeln("threads = \t ",cplex.threads); */
      cplex.tilim = 1200;
      //f.writeln("time limit = \t", cplex.tilim); 
      cplex.nodefileind = 3;
      //f.writeln("nodefileind = \t", cplex.nodefileind);
      cplex.workmem = 4096.0;
      //f.writeln("workmem = \t", cplex.workmem);
      cplex.symmetry = -1; 
      //f.writeln("symmetry = \t", cplex.symmetry);*/
      //cplex.workdir="F:/IBM/ILOG/Basic Model"; // ou il stocke les noeuds: // A remplacer par? "C:\Users\Sanae\AppData\Roaming\IBM\ILOG\Repertoire modele de base"  les barres sont inversées
     cplex.workdir="C:/Users/Sanae/opl/Cas plusieurs commandes"
      // cplex.workdir="C:/Users/Sanae/AppData/Roaming/IBM/ILOG/CPLEX_Studio128/workspace"
      source = new IloOplModelSource("Cas plusieurs commandes.mod"); 
      def = new IloOplModelDefinition(source); 
      var opl = new IloOplModel(def,cplex); 
      var dataset=new IloOplFile (tyc+"_"+dc+"_"+nc+"_"+cfg+".dat");
      if (dataset.exists){
      var data = new IloOplDataSource(tyc+"_"+dc+"_"+nc+"_"+cfg+".dat");
      opl.addDataSource(data); 
      opl.generate(); 
      before = new Date(); 
      status = cplex.solve(); 
      after = new Date();
      totaltime = after - before;
      f.write("\t", tyc+"_"+dc+"_"+nc+"_"+cfg); 
      f.write("\t", dc); 
      f.write("\t", cfg); 
      f.write("\t", opl.NC); 
      f.write("\t", opl.NE);  
      f.write("\t", opl.NU); 
      f.write("\t", opl.NSMin); 
      f.write("\t", opl.NECMin); 
      f.write("\t", opl.delai);  
      f.write("\t", cplex.getObjValue()); // borne supérieur. cout total, quel est la difference avec best objectif value
      f.write("\t", opl.coutC);  
      f.write("\t", opl.NEC); 
      f.write("\t", "a corriger  TC"); 
      //f.write("\t", opl.TC); 
    //f.write("\t", opl.NS);  
    f.write("\t", "a corriger"); 
    // f.write("\t", opl.TPr);  
    //   f.write("\t", opl.ProductiviteS);  
      //f.write("\t", opl.ProductiviteU); 
      f.write("\t", "a corriger");  
      f.write("\t", "a corriger"); 
      f.write("\t", "a corriger");
    f.write("\t", status);
    f.write("\t", totaltime);
      f.write("\t", cplex.getBestObjValue()); // Best LB. Comment avoir celui qui calcule le GAP// pas sure que c'est une solution optimale réelle. pas entière.'
      f.write("\t", cplex.getCplexStatus()); // 
      f.write("\t", cplex.getNnodes()); //indication nombre de calcul qu'il afaite, pour savoir combien de calcul qu'il a fait
      f.write("\t", opl.TCP)  
      cplex.clearModel;
      opl.settings.mainEndEnabled = true;
      opl.end();
      data.end();
      def.end();
      cplex.end();
      source.end();
          // ci après le détail des xijk dans le programme une ligne. Pour le moment je n'Affiche rien des xijik par commande.'
          
          /*var i //première tâche d'une statio xijk'
      var j // dernière tache+1 d'une station xijk'
      var k // nombre d'employés affectés à une station'
      var p=0 // compteur position de la station
      var nsg=0 // compteur nombre de station goulot
      var psg=100 // sert pour calculer position de la première station goulot, initialement très haut pour être mis à jour après
      var tcsmin= opl.tcl // temps de cycle de station minimal
      for (i=1; i<=opl.NT; i++)
      {
      for(j=i+1; j<=opl.NT+1; j++)
      {
      for(k=1; k<=opl.NE; k++)
      {
      if(opl.X[i][j][k]==1) 
      {
      var p = p+1 // incrémente le numéro de la station à chaque fois que xijk =1
      {if (opl.tcl<=opl.X[i][j][k]*opl.ts[i][j-1]/k+0.000000000001 && opl.tcl>=opl.X[i][j][k]*opl.ts[i][j-1]/k-0.000000000001)// pas eu besoin de définir le tcs comme variable d'expression'
        {  
            nsg=nsg+1 // incrémente le nombre de stations goulot à chaque fois qu'il en trouve 1, c a d que tcs=tcl
            psg=Math.min(p,psg) // calcule la position de première station goulot 
            //f.write("\t", "station goulot=", p) // Affiche  la liste de toutes les stations goulot
            }
            else 
            {
            tcsmin=Math.min(tcsmin,opl.X[i][j][k]*opl.ts[i][j-1]/k)// calcule le plus petit temps de cycle de station pour une ligne     
            }   
            }
        }   
        }
           } 
         } 
       
           //ci-dessus, je quitte la boucle ijk car ce que j'affiche ci-dessous est relié à l'instance (la ligne excel) et basé sur ce que j'Ai calculé pour chaque station'
         f.write("\t", nsg); // afficher le nombre de stations goulot
         f.write("\t", psg);    // afficher la position de la première station  goulot.
         f.write("\t", psg/opl.NS); // afficher la position relative de la 1ère station goulot
         f.write("\t", tcsmin); // Afficher le plus petit temps de cycle de station pour une ligne
         f.write("\t", opl.tcl/tcsmin); // affiche le rapport entre tcl et le temps de cycle de station minimal
         
         // ci-après je refais une boucle ijk car je dois afficher les détails de chaque station
        for (i=1; i<=opl.NT; i++)
      {
      for(j=i+1; j<=opl.NT+1; j++)
      {
      for(k=1; k<=opl.NE; k++)
      {
      if(opl.X[i][j][k]==1) 
      {  
            f.write("\t"," " ,"\t",i,"\t",j-1,"\t",k)
        }   
        }
        }
         }       
        // ici je termine la 2eme boucle des xijk car j'Ai fini les affichages reliés aux regroupements (Stations)' */
        f.writeln("\t") // je reviens à la ligne après avoir terminé toutes les boucles ijk pour une instance (une ligne excel)
    }  
    }
    }
    }
    }
     
     
    }

     

     

    .DAT:

    NC=2;
    NE=14;
    NU=[1000,1000];
    NSMin=2;
    NECMin=2;
    delai=[7000,7000];
    ProductiviteCMin=0;
    ProductiviteUMin=0;
    TH=12;
    NT=[5,25];
    t=[ [ 5.1 3.2 3.9 7.8 1.7 ] [ 7.9 9.7 2.8 9.9 9.8 9.2 3.5 2 8.5 0.1 8.8 9.9 9 2.7 8.6 4.8 0.9 7.9 6.9 0.8 5.4 8.5 1.7 3 8.8 ] ];

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 2.  Re: File not found error

    Posted Mon November 05, 2018 05:28 AM

    Originally posted by: FredericDelhoume


    It would help if you give us the line that corresponds to the error (line 131).

    Also can you give your complete oplrun command (with the directory you are executing the command in) ?

     

    You may look at OPL setting "settings.resolverpath".

     


    #DecisionOptimization
    #OPLusingCPLEXOptimizer


  • 3.  Re: File not found error

    Posted Mon November 05, 2018 09:54 AM

    Originally posted by: SanaeB


    Problem is resolved. Error was here:

    for (v=0; v=1; v++). i shoud have written for (v=0; v<=1; v++);

    Thank you


    #DecisionOptimization
    #OPLusingCPLEXOptimizer