CPLEX "out of memory"

Résolu/Fermé
lotchello - 24 sept. 2007 à 00:09
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 - 5 juin 2011 à 12:35
j'ai un prog mathématique codé sur CPLEX (C++) le nombre de variables et de contraintes sont tres grandes, mais je reois un message out of memory.
comment libérer les variables?
ou bien est ce qu'il ya une fonction CPLEX qui utilise le disque dur comme memoire?

2 réponses

mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 7 802
24 sept. 2007 à 09:46
Les objets Ilo... se désallouent en leur appliquant la méthode end(). En général tu fais ça dans le destructeur de ton solveur. A priori CPLEX tourne en RAM, si le système doit swapper (écrire temporairement sur le disque dur) c'est le système qui gère (fichier d'échange sous windows, swap sous linux).

Si ton problème CPLEX ne tient pas en mémoire c'est sans doute qu'il est mal construit ou mal modélisé. Typiquement si tu résous un problème dans un graphe avec des contraintes portant sur des chemins, le nombre de chemin explose avec la taille du graphe et il n'est souvent pas possible de générer toutes les contraintes portant sur les chemins.

En fait on s'aperçoit que souvent pour résoudre un problème il n'est pas nécessaire de générer toutes les contraintes, car on n'optimise que dans une seule direction. Il suffit donc de générer dynamiquement les facettes de ton polytope dynamiquement (cf décomposition de Benders). Tu as également possiblité d'utiliser la vision duale (génération de colonnes).

Si aucune de ces 2 méthodes ne tient en mémoire ou est trop longue à résoudre, il faut passer par des méta heuristiques et une résolution approchée.

Bonne chance
0
Salut tout le monde,

pouvez-vous expliquer un peu plus sur la manière de dire à CPLEX de rajouter telle ou telle contrainte (hyperplan d'appui) dans notre programme de manière dynamique SVP?

Merci d'avance!
0
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 7 802
Modifié par mamiemando le 5/06/2011 à 12:37
Je peux juste te dire que j'utilisais "concert" qui permet de travailler plus facilement avec cplex et qu'il y avait des méthodes pour ajouter dans un problème des contraintes.

Le gros piège c'est qu'il faut veiller à ce que la partie constante soit à droite du signe de comparaison (<=, =>,...) dans les inégalités que tu ajoutes, sinon ça ne marche pas...

Voici un extrait de ce que j'avais codé à l'époque :

#include <ilcplex/ilocplex.h> 

class cplex_solver_t{ 
  protected: 
    IloEnv env; 
    IloModel model; 
    IloCplex cplex; 

    // Variables du problème, tu définis autant de vecteur que tu en as besoin 
    IloBoolVarArray vars; 

    // Contraintes de domaine 
    IloRangeArray constraints; 

    // Fonction objectif 
    IloObjective obj; 

  //... 

  public: 

  // Constructeur 
  cplex_solver_t(){ 
    cplex.setOut(env.getNullStream()); 
  } 

  // Destructeur 
  ~cplex_solver_t(){ 
    model.end(); 
    cplex.end(); 
    vars.end(); 
    constraints.end(); 
    env.end(); 
    obj.end(); 
  } 

  // Valeur de l'objectif une fois le problème résolu 
  inline IloNum get_obj_value() { 
    return cplex.getObjValue(); 
  } 

  // Lance la résolution 
  inline bool solve(){ 
    cplex.extract(model); 
    IloBool res = cplex.solve(); 
    return res == IloTrue; 
  } 

  // Lire depuis un fichier 
  inline void read(const char *filename){ 
    cplex.importModel(model, filename); 
  } 

  // Écrire dans un fichier 
  inline void write(const char *filename){ 
    cplex.exportModel(filename); 
  } 

  // Ajouter une coupe 
  inline void add_cut(){ 
    IloExpr expr(env); 
    // 1.x0 + 2.x1 
    expr = 1.0 * vars[0] + 2.0 * vars[1]; 
    // tu peux aussi utiliser += 
    // 1.x0 + 2.x1 >= 3 
    model.add(expr >= 3); 
    expr.end(); 
  } 
}


Toutefois, merci d'ouvrir un nouveau fil de discussion car ta question est hors sujet par rapport au problème initial (qui est résolu qui plus est !). Je précise tout de suite, ce code en l'état ne fonctionnera pas car il manque des choses spécifiques à ton problème (initialisation de vars, des contraintes de domaine etc...) c'est juste pour te donner une idée.

Bonne chance
0
MERCI
0