CPLEX "out of memory"
Résolu
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?
comment libérer les variables?
ou bien est ce qu'il ya une fonction CPLEX qui utilise le disque dur comme memoire?
A voir également:
- Cmdlcache out of memory
- Windows memory cleaner - Télécharger - Optimisation
- Out of video memory trying to allocate a rendering resource ✓ - Forum Carte graphique
- Out of range - Forum Ecran
- Out of memory ✓ - Forum Matériel & Système
- Out of range écran - Forum Windows
2 réponses
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
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
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!
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