source: trunk/CoinMP/src/CoinCbc.cpp @ 360

Last change on this file since 360 was 360, checked in by bjarni, 10 years ago

Move SemiLower? to CoinCbc? and name it storeLowerBound

File size: 43.1 KB
Line 
1
2/*  CoinCbc.cpp  */
3
4
5#include "CoinProblem.h"
6#include "CoinResult.h"
7#include "CoinSolver.h"
8
9#include <cfloat>
10
11#include "CoinHelperFunctions.hpp"
12#include "CoinMessageHandler.hpp"
13
14#include "ClpSimplex.hpp"
15#include "ClpPrimalColumnSteepest.hpp"
16#include "ClpDualRowSteepest.hpp"
17#include "ClpEventHandler.hpp"
18
19#include "OsiSolverInterface.hpp"
20#include "OsiClpSolverInterface.hpp"
21
22#include "CbcModel.hpp"
23#include "CbcSolver.hpp"
24#include "CbcEventHandler.hpp"
25#include "CbcBranchActual.hpp"   // CbcSOS
26#include "CbcBranchLotsize.hpp"  // CbcLotsize
27
28#include "CglProbing.hpp"
29#include "CglGomory.hpp"
30#include "CglKnapsackCover.hpp"
31#include "CglOddHole.hpp"
32#include "CglClique.hpp"
33#include "CglLiftAndProject.hpp"
34#include "CglSimpleRounding.hpp"
35
36
37#include "CoinCbc.h"
38
39#define NEW_STYLE_CBCMAIN
40
41
42/************************************************************************/
43/*  Message Callback Handler                                            */
44/************************************************************************/
45
46
47class CBMessageHandler : public CoinMessageHandler {
48public: 
49        void setCallback(MSGLOGCALLBACK msgCallback);
50        virtual int print();
51private:
52        MSGLOGCALLBACK msgCallback_;
53};
54
55
56void CBMessageHandler::setCallback(MSGLOGCALLBACK msgCallback)
57{
58  msgCallback_ = msgCallback;
59}
60
61
62int CBMessageHandler::print()
63{
64        msgCallback_(const_cast<char*>(messageBuffer()));
65        return CoinMessageHandler::print();
66}
67
68
69
70/************************************************************************/
71/*  Iteration Callback Handler                                          */
72/************************************************************************/
73
74
75class CBIterHandler : public ClpEventHandler {
76
77public: 
78   void setIterCallback(ITERCALLBACK iterCallback);
79
80        virtual int event(Event whichEvent);
81   
82  /** Default constructor. */
83  CBIterHandler();
84  /// Constructor with pointer to model (redundant as setEventHandler does)
85  CBIterHandler(ClpSimplex * model);
86  /** Destructor */
87  virtual ~CBIterHandler();
88  /** The copy constructor. */
89  CBIterHandler(const CBIterHandler & rhs);
90  /// Assignment
91  CBIterHandler& operator=(const CBIterHandler & rhs);
92  /// Clone
93  virtual ClpEventHandler * clone() const ;
94
95
96private:
97        ITERCALLBACK iterCallback_;
98};
99
100
101void CBIterHandler::setIterCallback(ITERCALLBACK iterCallback)
102{
103  iterCallback_ = iterCallback;
104}
105
106
107
108int CBIterHandler::event(Event whichEvent)
109{
110        int numIter;
111        double objValue;
112        int isPrimalFeasible;
113        int isDualFeasible;
114        double sumPrimalInfeas; 
115        double sumDualInfeas;
116        int cancelAsap;
117
118        if ((whichEvent==endOfIteration)) {
119                numIter = model_->getIterationCount();
120                objValue = model_->getObjValue();
121                sumDualInfeas = model_->sumDualInfeasibilities();
122                sumPrimalInfeas = model_->sumPrimalInfeasibilities();
123                isPrimalFeasible = model_->primalFeasible();
124                isDualFeasible = model_->dualFeasible();
125                cancelAsap = iterCallback_(numIter, objValue, isPrimalFeasible&&isDualFeasible, sumPrimalInfeas);
126                if (cancelAsap) {
127                        return 5;
128                }
129        }
130        return -1;
131}
132
133
134// Default Constructor
135CBIterHandler::CBIterHandler () : ClpEventHandler() {}
136
137// Copy constructor
138CBIterHandler::CBIterHandler (const CBIterHandler & rhs) : ClpEventHandler(rhs) {}
139
140// Constructor with pointer to model
141CBIterHandler::CBIterHandler(ClpSimplex * model) : ClpEventHandler(model) {}
142
143// Destructor
144CBIterHandler::~CBIterHandler () {}
145
146// Assignment operator
147CBIterHandler & CBIterHandler::operator=(const CBIterHandler& rhs)
148{
149  if (this != &rhs) {
150    ClpEventHandler::operator=(rhs);
151  }
152  return *this;
153}
154
155// Clone
156ClpEventHandler * CBIterHandler::clone() const
157{
158        CBIterHandler * iterhandler;
159
160   iterhandler = new CBIterHandler(*this);
161        iterhandler->iterCallback_ = this->iterCallback_;
162        return iterhandler;
163}
164
165
166
167/************************************************************************/
168/*  MIP Node Callback Handler                                           */
169/************************************************************************/
170
171
172class CBNodeHandler : public CbcEventHandler {
173
174public: 
175   void setCallback(MIPNODECALLBACK mipNodeCallback);
176
177        virtual CbcAction event(CbcEvent whichEvent);
178   
179  /** Default constructor. */
180  CBNodeHandler();
181  /// Constructor with pointer to model (redundant as setEventHandler does)
182  //JPF CBNodeHandler(ClpSimplex * model);
183  CBNodeHandler(CbcModel * model);
184 
185
186  /** Destructor */
187  virtual ~CBNodeHandler();
188  /** The copy constructor. */
189  CBNodeHandler(const CBNodeHandler & rhs);
190  /// Assignment
191  CBNodeHandler& operator=(const CBNodeHandler & rhs);
192  /// Clone
193  virtual CbcEventHandler * clone() const ;
194
195
196private:
197        MIPNODECALLBACK mipNodeCallback_;
198        int lastSolCount_;
199};
200
201
202void CBNodeHandler::setCallback(MIPNODECALLBACK mipNodeCallback)
203{
204        mipNodeCallback_ = mipNodeCallback;
205        lastSolCount_ = 0;
206}
207
208
209CBNodeHandler::CbcAction CBNodeHandler::event(CbcEvent whichEvent)
210{
211        int numIter;
212        int numNodes;
213        double bestBound;
214        double objValue;
215        int solCount;
216        int cancelAsap;
217
218        if (whichEvent==node) {
219                numIter = model_->getIterationCount();
220                numNodes = model_->getNodeCount();
221                objValue = model_->getObjValue();
222                bestBound = model_->getBestPossibleObjValue();
223                solCount = model_->getSolutionCount();
224                cancelAsap = mipNodeCallback_(numIter, numNodes, bestBound, objValue, solCount != lastSolCount_);
225                lastSolCount_ = solCount;
226                if (cancelAsap) {
227                        return stop;
228                }
229        }
230        return noAction;
231}
232
233
234// Default Constructor
235CBNodeHandler::CBNodeHandler () : CbcEventHandler() {}
236
237// Copy constructor
238CBNodeHandler::CBNodeHandler (const CBNodeHandler & rhs) : CbcEventHandler(rhs) {}
239
240// Constructor with pointer to model
241//JPF: CBNodeHandler::CBNodeHandler(ClpSimplex * model) : CbcEventHandler(model) {}
242CBNodeHandler::CBNodeHandler(CbcModel * model) : CbcEventHandler(model) {}
243
244// Destructor
245CBNodeHandler::~CBNodeHandler () {}
246
247// Assignment operator
248CBNodeHandler & CBNodeHandler::operator=(const CBNodeHandler& rhs)
249{
250  if (this != &rhs) {
251    CbcEventHandler::operator=(rhs);
252  }
253  return *this;
254}
255
256// Clone
257CbcEventHandler * CBNodeHandler::clone() const
258{
259        CBNodeHandler * nodehandler;
260
261        nodehandler = new CBNodeHandler(*this);
262        nodehandler->mipNodeCallback_ = this->mipNodeCallback_;
263        nodehandler->lastSolCount_ = this->lastSolCount_;
264        return nodehandler;
265}
266
267
268/************************************************************************/
269/*  Coin Problem Info Structure                                         */
270/************************************************************************/
271
272typedef struct {
273                                ClpSimplex *clp;
274                                ClpSolve *clp_presolve;
275                                OsiClpSolverInterface *osi;
276                                CbcModel *cbc;
277
278                                CglProbing *probing;
279                                CglGomory *gomory;
280                                CglKnapsackCover *knapsack;
281                                CglOddHole *oddhole;
282                                CglClique *clique;
283                                CglLiftAndProject *liftpro;
284                                CglSimpleRounding *rounding;
285
286                                // callback handlers
287                                CBMessageHandler *msghandler;
288                                CBIterHandler *iterhandler;
289                                CBNodeHandler *nodehandler;
290
291                                } CBCINFO, *PCBC;
292
293
294HCBC CbcCreateSolverObject(void)
295{
296        PCBC pCbc;
297
298        pCbc = (PCBC)malloc(sizeof(CBCINFO));
299        if (!pCbc) {
300                return NULL;
301        }
302        memset(pCbc, 0, sizeof(CBCINFO));
303
304        pCbc->clp = new ClpSimplex();
305        pCbc->clp_presolve = new ClpSolve();
306        pCbc->osi = new OsiClpSolverInterface(pCbc->clp);
307        pCbc->cbc = NULL;  /* ERRORFIX 2/22/05: Crashes if not NULL when trying to set message handler */
308
309        pCbc->msghandler = NULL;
310        pCbc->iterhandler = NULL;
311        pCbc->nodehandler = NULL;
312        return (HCBC)pCbc;
313}
314
315
316void CbcClearSolverObject(HCBC hCbc)
317{
318        PCBC pCbc = (PCBC)hCbc;
319        if (!pCbc) {
320                return;
321        }
322        if (pCbc->clp) delete pCbc->clp;
323        if (pCbc->clp_presolve) delete pCbc->clp_presolve;
324        //if (pCbc->osi) delete pCbc->osi;
325        if (pCbc->cbc) delete pCbc->cbc;
326
327        if (pCbc->msghandler)   delete pCbc->msghandler;
328        if (pCbc->iterhandler)  delete pCbc->iterhandler;
329        if (pCbc->nodehandler)  delete pCbc->nodehandler;
330
331        free(pCbc);
332}
333
334/************************************************************************/
335/*  Callback Handling                                                   */
336/************************************************************************/
337
338
339
340int CbcSetMsgLogCallback(HCBC hCbc, MSGLOGCALLBACK MsgLogCallback)
341{
342        PCBC pCbc = (PCBC)hCbc;
343        int LogLevel;
344
345        if (!MsgLogCallback) {
346                return CBC_CALL_FAILED;
347        }
348        //pCbc->MsgLogCallback = MsgLogCallback;
349        delete pCbc->msghandler;
350        pCbc->msghandler = new CBMessageHandler();
351        pCbc->msghandler->setCallback(MsgLogCallback);
352        LogLevel = CbcGetIntOption(COIN_INT_LOGLEVEL);
353        pCbc->msghandler->setLogLevel(LogLevel);
354        if (pCbc->clp) pCbc->clp->passInMessageHandler(pCbc->msghandler);
355        if (pCbc->cbc) pCbc->cbc->passInMessageHandler(pCbc->msghandler);
356        if (pCbc->osi) pCbc->osi->passInMessageHandler(pCbc->msghandler);
357        return CBC_CALL_SUCCESS;
358}
359
360
361
362int CbcSetIterCallback(HCBC hCbc, ITERCALLBACK IterCallback)
363{
364        PCBC pCbc = (PCBC)hCbc;
365
366        if (!IterCallback) {
367                return CBC_CALL_FAILED;
368        }
369        //pCbc->IterCallback = IterCallback;
370        delete pCbc->iterhandler;
371        pCbc->iterhandler = new CBIterHandler(pCbc->clp);
372        pCbc->iterhandler->setIterCallback(IterCallback);
373        if (pCbc->clp) pCbc->clp->passInEventHandler(pCbc->iterhandler);
374        return CBC_CALL_SUCCESS;
375}
376
377
378int CbcSetMipNodeCallback(HCBC hCbc, MIPNODECALLBACK MipNodeCallback)
379{
380        PCBC pCbc = (PCBC)hCbc;
381
382        if (!MipNodeCallback) {
383                return CBC_CALL_FAILED;
384        }
385        //pCbc->MipNodeCallback = MipNodeCallback;
386        delete pCbc->nodehandler;
387        pCbc->nodehandler = new CBNodeHandler(pCbc->cbc);
388        pCbc->nodehandler->setCallback(MipNodeCallback);
389        if (pCbc->cbc) pCbc->cbc->passInEventHandler(pCbc->nodehandler);
390        return CBC_CALL_SUCCESS;
391}
392
393
394int CbcSetAllCallbacks(HCBC hCbc, PSOLVER pSolver)
395{
396        CbcSetMsgLogCallback(hCbc, pSolver->MsgLogCallback);
397        CbcSetIterCallback(hCbc, pSolver->IterCallback);
398        CbcSetMipNodeCallback(hCbc, pSolver->MipNodeCallback);
399        return CBC_CALL_SUCCESS;
400}
401
402
403
404/************************************************************************/
405/*  Option Setting                                                      */
406/************************************************************************/
407
408
409int CbcSetClpOptions(HCBC hCbc)
410{
411        PCBC pCbc = (PCBC)hCbc;
412        ClpSolve::SolveType method;
413        ClpSolve::PresolveType presolve;
414
415        /* check if it has been changed, leave alone otherwise */
416        if (CbcGetOptionChanged(COIN_INT_SCALING))                      pCbc->clp->scaling(CbcGetIntOption(COIN_INT_SCALING));
417        if (CbcGetOptionChanged(COIN_INT_PERTURBATION))         pCbc->clp->setPerturbation(CbcGetIntOption(COIN_INT_PERTURBATION));
418
419        if (CbcGetOptionChanged(COIN_REAL_MAXSECONDS))          pCbc->clp->setMaximumSeconds(CbcGetRealOption(COIN_REAL_MAXSECONDS));
420        if (CbcGetOptionChanged(COIN_INT_MAXITER))                      pCbc->clp->setMaximumIterations(CbcGetIntOption(COIN_INT_MAXITER));
421
422        if (CbcGetOptionChanged(COIN_REAL_PRIMALOBJLIM))        pCbc->clp->setPrimalObjectiveLimit(CbcGetRealOption(COIN_REAL_PRIMALOBJLIM));
423        if (CbcGetOptionChanged(COIN_REAL_DUALOBJLIM))          pCbc->clp->setDualObjectiveLimit(CbcGetRealOption(COIN_REAL_DUALOBJLIM));
424        if (CbcGetOptionChanged(COIN_REAL_PRIMALOBJTOL))        pCbc->clp->setPrimalTolerance(CbcGetRealOption(COIN_REAL_PRIMALOBJTOL));
425        if (CbcGetOptionChanged(COIN_REAL_DUALOBJTOL))          pCbc->clp->setDualTolerance(CbcGetRealOption(COIN_REAL_DUALOBJTOL));
426
427        if (CbcGetOptionChanged(COIN_INT_PRIMALPIVOTALG)) {
428                ClpPrimalColumnSteepest primalSteepest(CbcGetIntOption(COIN_INT_PRIMALPIVOTALG));
429                pCbc->clp->setPrimalColumnPivotAlgorithm(primalSteepest);
430        }
431
432        if (CbcGetOptionChanged(COIN_INT_DUALPIVOTALG)) {
433                ClpDualRowSteepest dualSteepest(CbcGetIntOption(COIN_INT_DUALPIVOTALG));
434                pCbc->clp->setDualRowPivotAlgorithm(dualSteepest);
435        }
436
437        if (CbcGetOptionChanged(COIN_INT_CRASHIND)) { 
438                if (CbcGetIntOption(COIN_INT_CRASHIND)) {
439                        pCbc->clp->crash(CbcGetRealOption(COIN_REAL_CRASHGAP),
440                                                                CbcGetIntOption(COIN_INT_CRASHPIVOT));
441                }
442        }
443
444        if (CbcGetOptionChanged(COIN_INT_SOLVEMETHOD)) {
445                switch (CbcGetIntOption(COIN_INT_SOLVEMETHOD)) {
446                        case 0: method = ClpSolve::useDual;                             break;
447                        case 1: method = ClpSolve::usePrimal;                   break;
448                        case 2: method = ClpSolve::usePrimalorSprint;   break;
449                        case 3: method = ClpSolve::useBarrier;                  break;
450                        case 4: method = ClpSolve::useBarrierNoCross;   break;
451                        case 5: method = ClpSolve::automatic;                   break;
452                        default: method = ClpSolve::usePrimal;
453                }
454                pCbc->clp->setSolveType(method);   //ClpSolve::usePrimal
455        }
456
457        if (CbcGetOptionChanged(COIN_INT_PRESOLVETYPE)) {   
458                switch (CbcGetIntOption(COIN_INT_PRESOLVETYPE)) {
459                        case 0: presolve = ClpSolve::presolveOn;                 break;
460                        case 1: presolve = ClpSolve::presolveOff;                break;
461                        case 2: presolve = ClpSolve::presolveNumber;     break;
462                        default: presolve = ClpSolve::presolveOn;
463                }
464                pCbc->clp_presolve->setPresolveType(presolve);   //ClpSolve::presolveOn
465        }
466        return 1;
467}
468
469
470int CbcSetCbcOptions(HCBC hCbc)
471{
472        PCBC pCbc = (PCBC)hCbc;
473
474        if (!pCbc->cbc) {
475                return 0;
476        }
477        if (CbcGetOptionChanged(COIN_INT_MIPMAXNODES))          pCbc->cbc->setMaximumNodes(CbcGetIntOption(COIN_INT_MIPMAXNODES));
478        if (CbcGetOptionChanged(COIN_INT_MIPMAXSOL))            pCbc->cbc->setMaximumSolutions(CbcGetIntOption(COIN_INT_MIPMAXSOL));
479        if (CbcGetOptionChanged(COIN_REAL_MIPMAXSEC))           pCbc->cbc->setDblParam(CbcModel::CbcMaximumSeconds,CbcGetRealOption(COIN_REAL_MIPMAXSEC));
480
481        if (CbcGetOptionChanged(COIN_INT_MIPFATHOMDISC))        pCbc->cbc->setIntParam(CbcModel::CbcFathomDiscipline,CbcGetIntOption(COIN_INT_MIPFATHOMDISC));
482
483        // JPF commented: pCbc->cbc->setHotstartStrategy(CbcGetIntOption(COIN_INT_MIPHOTSTART));
484        //              pCbc->cbc->setForcePriority(CbcGetIntOption(COIN_INT_MIPFORCEPRIOR));
485
486        if (CbcGetOptionChanged(COIN_INT_MIPMINIMUMDROP))       pCbc->cbc->setMinimumDrop(CbcGetIntOption(COIN_INT_MIPMINIMUMDROP));
487        if (CbcGetOptionChanged(COIN_INT_MIPMAXPASSROOT))       pCbc->cbc->setMaximumCutPassesAtRoot(CbcGetIntOption(COIN_INT_MIPMAXPASSROOT));
488        if (CbcGetOptionChanged(COIN_INT_MIPMAXCUTPASS))        pCbc->cbc->setMaximumCutPasses(CbcGetIntOption(COIN_INT_MIPMAXCUTPASS));
489        if (CbcGetOptionChanged(COIN_INT_MIPSTRONGBRANCH))      pCbc->cbc->setNumberStrong(CbcGetIntOption(COIN_INT_MIPSTRONGBRANCH));
490        if (CbcGetOptionChanged(COIN_INT_MIPSCANGLOBCUTS))      pCbc->cbc->setHowOftenGlobalScan(CbcGetIntOption(COIN_INT_MIPSCANGLOBCUTS));
491
492        if (CbcGetOptionChanged(COIN_REAL_MIPINTTOL))           pCbc->cbc->setIntegerTolerance(CbcGetRealOption(COIN_REAL_MIPINTTOL));
493        if (CbcGetOptionChanged(COIN_REAL_MIPINFWEIGHT))        pCbc->cbc->setInfeasibilityWeight(CbcGetRealOption(COIN_REAL_MIPINFWEIGHT));
494        if (CbcGetOptionChanged(COIN_REAL_MIPCUTOFF))           pCbc->cbc->setDblParam(CbcModel::CbcCutoffIncrement,CbcGetRealOption(COIN_REAL_MIPCUTOFF));
495        if (CbcGetOptionChanged(COIN_REAL_MIPABSGAP))           pCbc->cbc->setAllowableGap(CbcGetRealOption(COIN_REAL_MIPABSGAP));
496        if (CbcGetOptionChanged(COIN_REAL_MIPFRACGAP))          pCbc->cbc->setAllowableFractionGap(CbcGetRealOption(COIN_REAL_MIPFRACGAP));
497        return 1;
498}
499
500
501int CbcSetCglOptions(HCBC hCbc)
502{
503        PCBC pCbc = (PCBC)hCbc;
504
505        /* see CbcModel.hpp has commments on calling cuts */
506        if (CbcGetIntOption(COIN_INT_MIPCUT_PROBING)) {
507                pCbc->probing = new CglProbing();
508                if (CbcGetOptionChanged(COIN_INT_MIPPROBE_MODE))        pCbc->probing->setMode(CbcGetIntOption(COIN_INT_MIPPROBE_MODE));
509                if (CbcGetOptionChanged(COIN_INT_MIPPROBE_USEOBJ))      pCbc->probing->setUsingObjective(CbcGetIntOption(COIN_INT_MIPPROBE_USEOBJ) ? true : false);
510                if (CbcGetOptionChanged(COIN_INT_MIPPROBE_MAXPASS))     pCbc->probing->setMaxPass(CbcGetIntOption(COIN_INT_MIPPROBE_MAXPASS));
511                if (CbcGetOptionChanged(COIN_INT_MIPPROBE_MAXPROBE))    pCbc->probing->setMaxProbe(CbcGetIntOption(COIN_INT_MIPPROBE_MAXPROBE));
512                if (CbcGetOptionChanged(COIN_INT_MIPPROBE_MAXLOOK))     pCbc->probing->setMaxLook(CbcGetIntOption(COIN_INT_MIPPROBE_MAXLOOK));
513                if (CbcGetOptionChanged(COIN_INT_MIPPROBE_ROWCUTS))     pCbc->probing->setRowCuts(CbcGetIntOption(COIN_INT_MIPPROBE_ROWCUTS));
514                pCbc->cbc->addCutGenerator(pCbc->probing,CbcGetIntOption(COIN_INT_MIPPROBE_FREQ),"Probing");
515        }
516
517        if (CbcGetIntOption(COIN_INT_MIPCUT_GOMORY)) {
518                pCbc->gomory = new CglGomory();
519                if (CbcGetOptionChanged(COIN_INT_MIPGOMORY_LIMIT))      pCbc->gomory->setLimit(CbcGetIntOption(COIN_INT_MIPGOMORY_LIMIT));
520                if (CbcGetOptionChanged(COIN_REAL_MIPGOMORY_AWAY))      pCbc->gomory->setAway(CbcGetRealOption(COIN_REAL_MIPGOMORY_AWAY));
521                pCbc->cbc->addCutGenerator(pCbc->gomory,CbcGetIntOption(COIN_INT_MIPGOMORY_FREQ),"Gomory");
522        }
523
524        if (CbcGetIntOption(COIN_INT_MIPCUT_KNAPSACK)) {
525                pCbc->knapsack = new CglKnapsackCover();
526                if (CbcGetOptionChanged(COIN_INT_MIPKNAPSACK_MAXIN))    pCbc->knapsack->setMaxInKnapsack(CbcGetIntOption(COIN_INT_MIPKNAPSACK_MAXIN));
527                pCbc->cbc->addCutGenerator(pCbc->knapsack,CbcGetIntOption(COIN_INT_MIPKNAPSACK_FREQ),"Knapsack");
528        }
529
530        if (CbcGetIntOption(COIN_INT_MIPCUT_ODDHOLE)) {
531                pCbc->oddhole= new CglOddHole();
532                if (CbcGetOptionChanged(COIN_REAL_MIPODDHOLE_MINVIOL))  pCbc->oddhole->setMinimumViolation(CbcGetRealOption(COIN_REAL_MIPODDHOLE_MINVIOL));
533                if (CbcGetOptionChanged(COIN_REAL_MIPODDHOLE_MINVIOLPER))       pCbc->oddhole->setMinimumViolationPer(CbcGetRealOption(COIN_REAL_MIPODDHOLE_MINVIOLPER));
534                if (CbcGetOptionChanged(COIN_INT_MIPODDHOLE_MAXENTRIES))        pCbc->oddhole->setMaximumEntries(CbcGetIntOption(COIN_INT_MIPODDHOLE_MAXENTRIES));
535                pCbc->cbc->addCutGenerator(pCbc->oddhole,CbcGetIntOption(COIN_INT_MIPODDHOLE_FREQ),"OddHole");
536        }
537
538        if (CbcGetIntOption(COIN_INT_MIPCUT_CLIQUE)) {
539                pCbc->clique= new CglClique(CbcGetIntOption(COIN_INT_MIPCLIQUE_PACKING) ? true : false);
540                if (CbcGetOptionChanged(COIN_INT_MIPCLIQUE_STAR))               pCbc->clique->setDoStarClique(CbcGetIntOption(COIN_INT_MIPCLIQUE_STAR) ? true : false);
541                if (CbcGetOptionChanged(COIN_INT_MIPCLIQUE_STARMETHOD)) pCbc->clique->setStarCliqueNextNodeMethod((CglClique::scl_next_node_method)CbcGetIntOption(COIN_INT_MIPCLIQUE_STARMETHOD));
542                if (CbcGetOptionChanged(COIN_INT_MIPCLIQUE_STARMAXLEN)) pCbc->clique->setStarCliqueCandidateLengthThreshold(CbcGetIntOption(COIN_INT_MIPCLIQUE_STARMAXLEN));
543                if (CbcGetOptionChanged(COIN_INT_MIPCLIQUE_STARREPORT)) pCbc->clique->setStarCliqueReport(CbcGetIntOption(COIN_INT_MIPCLIQUE_STARREPORT) ? true : false);
544                if (CbcGetOptionChanged(COIN_INT_MIPCLIQUE_ROW))                pCbc->clique->setDoRowClique(CbcGetIntOption(COIN_INT_MIPCLIQUE_ROW) ? true : false);
545                if (CbcGetOptionChanged(COIN_INT_MIPCLIQUE_ROWMAXLEN))  pCbc->clique->setRowCliqueCandidateLengthThreshold(CbcGetIntOption(COIN_INT_MIPCLIQUE_ROWMAXLEN));
546                if (CbcGetOptionChanged(COIN_INT_MIPCLIQUE_ROWREPORT))  pCbc->clique->setRowCliqueReport(CbcGetIntOption(COIN_INT_MIPCLIQUE_ROWREPORT) ? true : false);
547                if (CbcGetOptionChanged(COIN_REAL_MIPCLIQUE_MINVIOL))   pCbc->clique->setMinViolation(CbcGetRealOption(COIN_REAL_MIPCLIQUE_MINVIOL));
548                pCbc->cbc->addCutGenerator(pCbc->clique,CbcGetIntOption(COIN_INT_MIPCLIQUE_FREQ),"Clique");
549        }
550
551        if (CbcGetIntOption(COIN_INT_MIPCUT_LIFTPROJECT)) {
552                pCbc->liftpro = new CglLiftAndProject();
553                if (CbcGetOptionChanged(COIN_INT_MIPLIFTPRO_BETAONE))   pCbc->liftpro->setBeta(CbcGetIntOption(COIN_INT_MIPLIFTPRO_BETAONE) ? 1 : -1);
554                pCbc->cbc->addCutGenerator(pCbc->liftpro,CbcGetIntOption(COIN_INT_MIPLIFTPRO_FREQ),"LiftProject");
555        }
556
557        if (CbcGetIntOption(COIN_INT_MIPCUT_SIMPROUND)) {
558                pCbc->rounding = new CglSimpleRounding();
559                pCbc->cbc->addCutGenerator(pCbc->rounding,CbcGetIntOption(COIN_INT_MIPSIMPROUND_FREQ),"Rounding");
560        }
561        return 1;
562}
563
564
565/************************************************************************/
566/*  Setup CBC Objects                                                  */
567/************************************************************************/
568
569
570void CbcCopyNamesList(HCBC hCbc, PPROBLEM pProblem)
571{
572        int i;
573        PCBC pCbc = (PCBC)hCbc;
574
575        /* Load names */
576        if (pProblem->RowNamesList || pProblem->ColNamesList) {
577                std::vector<std::string> rowNamesVect;
578                std::vector<std::string> colNamesVect;
579                rowNamesVect.reserve(pProblem->RowCount);
580                colNamesVect.reserve(pProblem->ColCount);
581                if (pProblem->RowNamesList) {
582                        for (i = 0; i < pProblem->RowCount; i++) {
583                                rowNamesVect.push_back(pProblem->RowNamesList[i]);
584                        }
585                }
586                if (pProblem->ColNamesList) {
587                        for (i = 0; i < pProblem->ColCount; i++) {
588                                colNamesVect.push_back(pProblem->ColNamesList[i]);
589                        }
590                }
591                pCbc->clp->copyNames(rowNamesVect, colNamesVect);
592        }
593}
594
595
596int CbcSetColumnIntegers(HCBC hCbc, PPROBLEM pProblem)
597{
598        int i;
599        PCBC pCbc = (PCBC)hCbc;
600
601        if (pProblem->numInts == 0) {
602                return CBC_CALL_FAILED;
603        }
604        for (i = 0; i < pProblem->ColCount; i++) {
605                if (pProblem->IsInt[i]) {
606                        pCbc->cbc->solver()->setInteger(i);
607                        pCbc->osi->setInteger(i);
608                }
609        }
610        return CBC_CALL_SUCCESS;
611}
612
613
614int CbcAddPriorObjects(HCBC hCbc, PPROBLEM pProblem)
615{
616        int *priorVar;
617        int *priorCbc;
618        int i,k;
619        PCBC pCbc = (PCBC)hCbc;
620
621        if ((pProblem->PriorCount == 0) || (pProblem->numInts == 0)) {
622                return CBC_CALL_FAILED;
623        }
624        priorVar = (int *)malloc(pProblem->ColCount * sizeof(int));
625        if (!priorVar) {
626                return CBC_CALL_FAILED;
627        }
628        //reset the priorVar
629        for (i = 0; i < pProblem->ColCount; i++) {
630                priorVar[i] = 1000;
631        }
632        for (i = 0; i < pProblem->PriorCount; i++) {
633                if ((pProblem->PriorIndex[i] < 0) || 
634                        (pProblem->PriorIndex[i] >= pProblem->ColCount)) {
635                        free(priorVar);
636                        return CBC_CALL_FAILED;
637                }
638                priorVar[pProblem->PriorIndex[i]] = pProblem->PriorValues[i];
639        }
640        //Create an array to give to cbc
641        priorCbc = (int *)malloc(pProblem->numInts * sizeof(int));
642        if (!priorCbc) {
643                free(priorVar);
644                return CBC_CALL_FAILED;
645        }
646        k = 0;
647        for (i = 0; i < pProblem->ColCount; i++) {
648                if (pProblem->IsInt[i]) {
649                        priorCbc[k++] = priorVar[i];
650                }
651        }
652        pCbc->cbc->passInPriorities(priorCbc, false);
653        free(priorCbc);
654        free(priorVar);
655        return CBC_CALL_SUCCESS;
656}
657
658
659int CbcAddSosObjects(HCBC hCbc, PPROBLEM pProblem)
660{
661        int sos, count;
662        int* which;
663        int type;
664        PCBC pCbc = (PCBC)hCbc;
665
666        if (pProblem->SosCount == 0) {
667                return CBC_CALL_FAILED;
668        }
669        for (sos = 0; sos < pProblem->SosCount; sos++) {
670                count = pProblem->SosBegin[sos+1] - pProblem->SosBegin[sos];
671                which = &pProblem->SosIndex[pProblem->SosBegin[sos]];
672                type = pProblem->SosType[sos];
673                CbcObject *sosObject = new CbcSOS(pCbc->cbc, count, which, NULL, 0, type);
674                pCbc->cbc->addObjects(1, &sosObject);
675                delete sosObject;
676        }
677        return CBC_CALL_SUCCESS;
678}
679
680
681int CbcAddSemiContObjects(HCBC hCbc, PPROBLEM pProblem)
682{
683        double points[4];
684        int i, semicol;
685        PCBC pCbc = (PCBC)hCbc;
686
687        if (pProblem->SemiCount == 0) {
688                return CBC_CALL_FAILED;
689        }
690        points[0] = 0.0;
691        points[1] = 0.0;
692        for (i = 0; i < pProblem->SemiCount; i++ ) {
693                semicol = pProblem->SemiIndex[i];
694                points[2] = pProblem->LowerBounds[semicol];
695                points[3] = pProblem->UpperBounds[semicol];
696                CbcObject *semiObject = new CbcLotsize(pCbc->cbc, semicol, 2, points, true);
697                pCbc->cbc->addObjects(1, &semiObject);
698                delete semiObject;
699        }
700        return CBC_CALL_SUCCESS;
701}
702
703
704
705int CbcLoadAllSolverObjects(HCBC hCbc, PPROBLEM pProblem)
706{
707        PCBC pCbc = (PCBC)hCbc;
708        int i, col;
709        int result;
710        double* storeLowerBound;
711
712        if (pProblem->SemiCount > 0) { 
713                storeLowerBound = (double *)malloc(pProblem->ColCount * sizeof(double));
714                if (!storeLowerBound) {
715                        return CBC_CALL_FAILED;
716                }
717                memcpy(storeLowerBound, pProblem->LowerBounds, pProblem->ColCount * sizeof(double));
718                for (i = 0; i < pProblem->SemiCount; i++) {
719                        col = pProblem->SemiIndex[i];
720                        pProblem->LowerBounds[col] = 0.0;
721                }
722        }
723        pCbc->clp->setOptimizationDirection(pProblem->ObjectSense);
724        pCbc->clp->loadProblem(pProblem->ColCount, pProblem->RowCount, 
725                                                        pProblem->MatrixBegin, pProblem->MatrixIndex, pProblem->MatrixValues,
726                                                        pProblem->LowerBounds, pProblem->UpperBounds, pProblem->ObjectCoeffs, 
727                                                        pProblem->RowLower, pProblem->RowUpper);
728        if (pProblem->SemiCount > 0) { 
729                memcpy(pProblem->LowerBounds, storeLowerBound, pProblem->ColCount * sizeof(double));
730                free(storeLowerBound);
731        }
732        CbcCopyNamesList(hCbc, pProblem);
733        if (pProblem->SolveAsMIP) {
734                if (!pCbc->cbc) {
735                        pCbc->cbc = new CbcModel(*pCbc->osi);
736                }
737                result = CbcSetColumnIntegers(hCbc, pProblem);
738                result = CbcAddPriorObjects(hCbc, pProblem);
739                result = CbcAddSosObjects(hCbc, pProblem);
740                result = CbcAddSemiContObjects(hCbc, pProblem);
741        }
742        return CBC_CALL_SUCCESS;
743}
744
745
746
747extern int CbcOrClpRead_mode;
748
749int CbcSolveProblem(HCBC hCbc, PPROBLEM pProblem, int Method)
750{
751        PCBC pCbc = (PCBC)hCbc;
752
753        if (!pProblem->SolveAsMIP) {
754                CbcSetClpOptions(hCbc);
755                if (CbcGetOptionChanged(COIN_INT_PRESOLVETYPE))                 
756                        pCbc->clp->initialSolve(*pCbc->clp_presolve);
757                else {
758                        pCbc->clp->initialSolve();
759                }
760                }
761        else {
762#ifdef NEW_STYLE_CBCMAIN
763                if (CbcGetIntOption(COIN_INT_MIPUSECBCMAIN)) {
764                        CbcMain0(*pCbc->cbc);
765                        CbcSetClpOptions(hCbc);
766                        CbcSetCbcOptions(hCbc);
767                        //CbcSetCglOptions(hProb);  BK: CbcMain1 will call the Cgl's automatically
768                        CbcOrClpRead_mode = 1;  // BK: Fix bug in CbcMain1, CbcOrClpRead_mode not initialized  (CpcSolver.cpp, stable 2.2)
769                        const int argc = 3;
770                        const char* argv[] = {"CoinMP", "-solve", "-quit"};
771                        CbcMain1(argc,argv,*pCbc->cbc);
772                        }
773                else 
774#endif
775                {
776                        CbcSetClpOptions(hCbc);
777                        CbcSetCbcOptions(hCbc);
778                        CbcSetCglOptions(hCbc);
779
780                        pCbc->cbc->initialSolve();
781                        pCbc->cbc->branchAndBound();
782                }
783        }
784        return CBC_CALL_SUCCESS;
785}
786
787
788int CbcRetrieveSolutionResults(HCBC hCbc, PPROBLEM pProblem, PRESULT pResult)
789{
790        PCBC pCbc = (PCBC)hCbc;
791        const double* columnPrimal;
792        const double* columnDual;
793        const double* rowPrimal;
794        const double* rowDual;
795
796        if (!pProblem->SolveAsMIP) {
797                pResult->SolutionStatus = pCbc->clp->status();
798                pResult->ObjectValue    = pCbc->clp->objectiveValue();
799                pResult->MipBestBound   = 0.0;
800                pResult->IterCount      = pCbc->clp->numberIterations();
801                pResult->MipNodeCount     = 0;
802                }
803        else {
804                pResult->SolutionStatus = pCbc->cbc->status();
805                pResult->ObjectValue    = pCbc->cbc->getObjValue();
806                pResult->MipBestBound   = pCbc->cbc->getBestPossibleObjValue();
807                pResult->IterCount      = pCbc->cbc->getIterationCount();
808                pResult->MipNodeCount   = pCbc->cbc->getNodeCount();
809        }
810
811        switch (pResult->SolutionStatus) {
812                case 0: strcpy(pResult->SolutionText, "Optimal solution found");                break;
813                case 1: strcpy(pResult->SolutionText, "Problem primal infeasible");     break;
814                case 2: strcpy(pResult->SolutionText, "Problem dual infeasible");               break;
815                case 3: strcpy(pResult->SolutionText, "Stopped on iterations");                 break;
816                case 4: strcpy(pResult->SolutionText, "Stopped due to errors");                 break;
817                case 5: strcpy(pResult->SolutionText, "Stopped by user");               break;
818                default: 
819                        sprintf(pResult->SolutionText, "Unknown CBC solution status (%d)", pResult->SolutionStatus);
820                        break;
821        }
822
823        if (!pProblem->SolveAsMIP) {
824                columnPrimal = pCbc->clp->primalColumnSolution();
825                columnDual = pCbc->clp->dualColumnSolution();
826                rowPrimal = pCbc->clp->primalRowSolution();
827                rowDual = pCbc->clp->dualRowSolution();
828                pResult->ColActivity = (double*) malloc(pProblem->ColCount * sizeof(double));
829                pResult->ReducedCost = (double*) malloc(pProblem->ColCount * sizeof(double));
830                pResult->SlackValues = (double*) malloc(pProblem->RowCount * sizeof(double));
831                pResult->ShadowPrice = (double*) malloc(pProblem->RowCount * sizeof(double));
832                if (!pResult->ColActivity ||
833                        !pResult->ReducedCost || 
834                        !pResult->SlackValues || 
835                        !pResult->ShadowPrice) {
836                        return CBC_CALL_FAILED;
837                }
838                memcpy(pResult->ColActivity, columnPrimal, pProblem->ColCount * sizeof(double));
839                memcpy(pResult->ReducedCost, columnDual, pProblem->ColCount * sizeof(double));
840                memcpy(pResult->SlackValues, rowPrimal, pProblem->RowCount * sizeof(double));
841                memcpy(pResult->ShadowPrice, rowDual, pProblem->RowCount * sizeof(double));
842                }
843        else {
844                columnPrimal = pCbc->cbc->solver()->getColSolution();
845                pResult->ColActivity = (double*) malloc(pProblem->ColCount * sizeof(double));
846                if (!pResult->ColActivity) {
847                        return CBC_CALL_FAILED;
848                }
849                memcpy(pResult->ColActivity, columnPrimal, pProblem->ColCount * sizeof(double));
850        }
851        return CBC_CALL_SUCCESS;
852}
853
854
855
856int CbcOptimizeProblem(PPROBLEM pProblem, PRESULT pResult, PSOLVER pSolver, int Method)
857{               
858        HCBC hCbc;
859        int result;
860
861        hCbc = CbcCreateSolverObject();
862        result = CbcLoadAllSolverObjects(hCbc, pProblem);
863        result = CbcSetAllCallbacks(hCbc, pSolver);
864        result = CbcSolveProblem(hCbc, pProblem, Method);
865        result = CbcRetrieveSolutionResults(hCbc, pProblem, pResult);
866        CbcClearSolverObject(hCbc);
867        return CBC_CALL_SUCCESS;
868}
869
870
871int CbcReadMpsFile(PPROBLEM pProblem, const char *ReadFilename)
872{
873        PCBC pCbc;
874        HCBC hCbc;
875
876        hCbc = CbcCreateSolverObject();
877        pCbc = (PCBC)hCbc;
878        pCbc->clp->readMps(ReadFilename, 1, 0); 
879        CbcClearSolverObject(hCbc);
880        return CBC_CALL_SUCCESS;
881}
882
883
884int CbcWriteMpsFile(PPROBLEM pProblem, const char *WriteFilename)
885{
886        int result;
887        PCBC pCbc;
888        HCBC hCbc;
889
890        hCbc = CbcCreateSolverObject();
891        pCbc = (PCBC)hCbc;
892        result = CbcLoadAllSolverObjects(hCbc, pProblem);
893        pCbc->osi->writeMps(WriteFilename); 
894        //result = CbcClearAllSolverObjects(hCbc);
895        CbcClearSolverObject(hCbc);
896        return CBC_CALL_SUCCESS;
897}
898
899
900
901/************************************************************************/
902/*  Option Table                                                        */
903/************************************************************************/
904
905#define OPTIONCOUNT    68
906
907
908SOLVOPTINFO OptionTable[OPTIONCOUNT] = {
909
910        {"SolveMethod",            "SolveMethod",  GRP_SIMPLEX,        0,        0,      0,       5,  OPT_LIST,   0,   COIN_INT_SOLVEMETHOD},
911      /*enum SolveType { useDual=0, usePrimal, usePrimalorSprint, useBarrier, useBarrierNoCross, automatic*/
912        {"PresolveType",           "Presolve",     GRP_SIMPLEX,        0,        0,      0,       2,  OPT_LIST,   0,   COIN_INT_PRESOLVETYPE},
913      /*enum PresolveType { presolveOn=0, presolveOff, presolveNumber }; */
914        {"Scaling",                "Scaling",      GRP_SIMPLEX,        3,        3,      0,       4,  OPT_LIST,   0,   COIN_INT_SCALING}, 
915      /* Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) */
916        {"Perturbation",           "Perturb",      GRP_SIMPLEX,      100,      100,      0,     100,  OPT_INT,    0,   COIN_INT_PERTURBATION}, 
917      /* 0 - Off, 50 - On, 100 - Only if clp stalls */
918        {"PrimalColPivotAlg",      "PrimPivAlg",   GRP_SIMPLEX,        1,        1,      0,       4,  OPT_LIST,   0,   COIN_INT_PRIMALPIVOTALG}, 
919      /*0 is exact devex, 1 full steepest, 2 is partial exact devex
920        3 switches between 0 and 2 depending on factorization
921        4 starts as partial dantzig/devex but then may switch between 0 and 2.*/
922        {"DualRowPivotAlg",        "DualPivAlg",   GRP_SIMPLEX,        1,        1,      0,       3,  OPT_LIST,   0,   COIN_INT_DUALPIVOTALG}, 
923      /*0 is uninitialized, 1 full, 2 is partial uninitialized,
924        3 starts as 2 but may switch to 1.*/
925        {"LogLevel",               "LogLevel",     GRP_LOGFILE,        1,        1,      0,       4,  OPT_LIST,   0,   COIN_INT_LOGLEVEL}, 
926        {"MaxIterations",          "MaxIter",      GRP_LIMITS,  99999999, 99999999,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MAXITER}, 
927        {"MaxSeconds",             "MaxSeconds",   GRP_LIMITS,      -1.0,     -1.0,   -1.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_MAXSECONDS}, 
928
929        {"CrashInd",               "CrashInd",     GRP_SIMPLEX,        0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_CRASHIND}, 
930        {"CrashPivot",             "CrashPivot",   GRP_SIMPLEX,        0,        0,     -1,       2,  OPT_LIST,   0,   COIN_INT_CRASHPIVOT}, 
931        {"CrashGap",               "CrashGap",     GRP_SIMPLEX,   1000.0,   1000.0,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_CRASHGAP}, 
932        {"PrimalObjectLimit",      "PrimalObjLim", GRP_SIMPLEX,  MAXREAL,  MAXREAL,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_PRIMALOBJLIM}, 
933        {"DualObjectLimit",        "DualObjLim",   GRP_SIMPLEX,  MAXREAL,  MAXREAL,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_DUALOBJLIM}, 
934        {"PrimalTolerance",        "PrimalTol",    GRP_SIMPLEX,     1e-7,     1e-7,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_PRIMALOBJTOL}, 
935        {"DualTolerance",          "DualTol",      GRP_SIMPLEX,     1e-7,     1e-7,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_DUALOBJTOL}, 
936
937        {"MipMaxNodes",            "MipMaxNodes",  GRP_LIMITS,   9999999,  9999999,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPMAXNODES}, 
938        {"MipMaxSolutions",        "MipMaxSol",    GRP_LIMITS,   9999999,  9999999,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPMAXSOL}, 
939        {"MipMaxSeconds",          "MipMaxSec",    GRP_LIMITS,     1e100,    1e100,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_MIPMAXSEC}, 
940
941        {"MipFathomDiscipline",    "FathomDisc",   GRP_MIPSTRAT,       0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPFATHOMDISC}, 
942        {"MipHotStart",            "HotStart",     GRP_MIPSTRAT,       0,        0,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPHOTSTART},
943//      {"MipForcePriority",       "ForcePrior",   GRP_MIPSTRAT,      -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPFORCEPRIOR},
944        {"MipMinimumDrop",         "MinimumDrop",  GRP_MIPSTRAT,    1e-4,     1e-4,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPMINIMUMDROP},
945        {"MipMaxCutPasses",        "MaxCutPass",   GRP_MIPSTRAT,       2,        2,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPMAXCUTPASS},
946        {"MipMaxCutPassAtRoot",    "MaxPassRoot",  GRP_MIPSTRAT,      50,       50,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPMAXPASSROOT},
947        {"MipStrongBranching",     "StrongBranch", GRP_MIPSTRAT,       5,        5,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPSTRONGBRANCH},
948        {"MipScanGlobalCuts",      "ScanGlobCuts", GRP_MIPSTRAT,       1,        1,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPSCANGLOBCUTS},
949
950        {"MipIntegerTolerance",    "MipIntTol",    GRP_MIPTOL,      1e-6,     1e-6,    0.0,     1.0,  OPT_REAL,   0,   COIN_REAL_MIPINTTOL}, 
951        {"MipInfeasWeight",        "MipInfWeight", GRP_MIPTOL,       0.0,      0.0,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_MIPINFWEIGHT}, 
952        {"MipCutoffIncrement",     "MipCutIncr",   GRP_MIPTOL,      1e-5,     1e-5,    0.0,     1.0,  OPT_REAL,   0,   COIN_REAL_MIPCUTOFF}, 
953        {"MipAllowableGap",        "MipAbsGap",    GRP_MIPTOL,     1e-10,    1e-10,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_MIPABSGAP}, 
954        {"MipFractionalGap",       "MipFracGap",   GRP_MIPTOL,     1e-10,    1e-10,    0.0,     1.0,  OPT_REAL,   0,   COIN_REAL_MIPFRACGAP}, 
955
956        /* Probing */
957        {"MipCutProbing",          "CutProbing",   GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_PROBING},
958        {"MipProbeFrequency",      "ProbeFreq",    GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPPROBE_FREQ},
959        {"MipProbeMode",           "ProbeMode",    GRP_MIPCUTS,        1,        1,      0,       2,  OPT_LIST,   0,   COIN_INT_MIPPROBE_MODE},
960        {"MipProbeUseObjective",   "UseObject",    GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPPROBE_USEOBJ},
961        {"MipProbeMaxPass",        "MaxPass",      GRP_MIPCUTS,        3,        3,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPPROBE_MAXPASS},
962        {"MipProbeMaxProbe",       "MaxProbe",     GRP_MIPCUTS,      100,      100,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPPROBE_MAXPROBE},
963        {"MipProbeMaxLook",        "MaxLook",      GRP_MIPCUTS,       50,       50,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPPROBE_MAXLOOK},
964        {"MipProbeRowCuts",        "RowCuts",      GRP_MIPCUTS,        3,        3,      0,       3,  OPT_LIST,   0,   COIN_INT_MIPPROBE_ROWCUTS},
965
966        /* Gomory cuts */
967        {"MipCutGomory",           "CutGomory",    GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_GOMORY},
968        {"MipGomoryFrequency",     "GomoryFreq",   GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPGOMORY_FREQ},
969        {"MipGomoryLimit",         "GomoryLimit",  GRP_MIPCUTS,       50,       50,      1,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPGOMORY_LIMIT},
970        {"MipGomoryAway",          "GomoryAway",   GRP_MIPCUTS,     0.05,     0.05, 0.0001,     0.5,  OPT_REAL,   0,   COIN_REAL_MIPGOMORY_AWAY},
971
972        /* Knapsack cuts */
973        {"MipCutKnapsack",         "CutKnapsack",  GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_KNAPSACK},
974        {"MipKnapsackFrequency",   "KrapsackFreq", GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPKNAPSACK_FREQ},
975        {"MipKnapsackMaxIn",       "KnapsackMaxIn",GRP_MIPCUTS,       50,       50,      1,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPKNAPSACK_MAXIN},
976
977        /* Oddhole cuts */
978        {"MipCutOddHole",          "CutOddHole",   GRP_MIPCUTS,        0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_ODDHOLE},
979        {"MipOddHoleFrequency",    "OddHoleFreq",  GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPODDHOLE_FREQ},
980        {"MipOddHoleMinViolation", "MinViolation", GRP_MIPCUTS,    0.001,    0.001,1.01e-8,     0.5,  OPT_REAL,   0,   COIN_REAL_MIPODDHOLE_MINVIOL},
981        {"MipOddHoleMinViolPer",   "MinViolPer",   GRP_MIPCUTS,   0.0003,   0.0003,1.01e-8,    0.25,  OPT_REAL,   0,   COIN_REAL_MIPODDHOLE_MINVIOLPER},
982        {"MipOddHoleMaxEntries",   "MaxEntries",   GRP_MIPCUTS,      100,      100,      3,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPODDHOLE_MAXENTRIES},
983
984        /* Clique cuts */
985        {"MipCutClique",           "CutClique",    GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_CLIQUE},
986        {"MipCliqueFrequency",     "CliqueFreq",   GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPCLIQUE_FREQ},
987        {"MipCliquePacking",       "CliquePacking",GRP_MIPCUTS,        0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCLIQUE_PACKING},
988        {"MipCliqueStar",          "CliqueStar",   GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCLIQUE_STAR},
989        {"MipCliqueStarMethod",    "StarMethod",   GRP_MIPCUTS,        2,        2,      0,       2,  OPT_LIST,   0,   COIN_INT_MIPCLIQUE_STARMETHOD},
990        {"MipCliqueStarMaxLen",    "StarMaxLen",   GRP_MIPCUTS,       12,       12,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPCLIQUE_STARMAXLEN},
991        {"MipCliqueStarReport",    "StarReport",   GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCLIQUE_STARREPORT},
992        {"MipCliqueRow",           "CliqueRow",    GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCLIQUE_ROW},
993        {"MipCliqueRowMaxLen",     "ClqRowMaxLen", GRP_MIPCUTS,       12,       12,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPCLIQUE_ROWMAXLEN},
994        {"MipCliqueRowReport",     "ClqRowReport", GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCLIQUE_ROWREPORT},
995        {"MipCliqueMinViolation",  "ClqMinViol",   GRP_MIPCUTS,     -1.0,     -1.0,-MAXREAL,MAXREAL,  OPT_REAL,   0,   COIN_REAL_MIPCLIQUE_MINVIOL},
996
997        /* Lift and Project */
998        {"MipCutLiftAndProject",   "CutLiftPro",   GRP_MIPCUTS,        0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_LIFTPROJECT},
999        {"MipLiftCoverFrequency",  "LiftProFreq",  GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPLIFTPRO_FREQ},
1000        {"MipLiftCoverBetaOne",    "LiftProBeta",  GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPLIFTPRO_BETAONE},
1001
1002        /* Simple Rounding */
1003        {"MipCutSimpleRounding",   "CutSimpRound", GRP_MIPCUTS,        0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_SIMPROUND},
1004        {"MipSimpleRoundFrequency","SimpRoundFreq",GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPSIMPROUND_FREQ},
1005
1006        {"MipUseCbcMain",          "UseCbcMain",   GRP_MIPSTRAT,       1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPUSECBCMAIN}
1007        };
1008
1009int CbcGetOptionCount(void)
1010{
1011        return OPTIONCOUNT;
1012}
1013
1014
1015SOLVOPTINFO *CbcGetOptionTable(void)
1016{
1017        return &OptionTable[0];
1018}
1019
1020
1021
1022int CbcGetOptionID(int OptionNr)
1023{
1024        if ((OptionNr < 0) || (OptionNr >= OPTIONCOUNT)) {
1025                return -1;
1026        }
1027        return OptionTable[OptionNr].OptionID;
1028}
1029
1030int CbcLocateOptionID(int OptionID)
1031{
1032        int i;
1033        SOLVOPTINFO *OptionTable;
1034
1035        OptionTable = CbcGetOptionTable();
1036        for (i = 0; i < CbcGetOptionCount(); i++) {
1037                if (OptionID == OptionTable[i].OptionID) {
1038                        return i;
1039                }
1040        }
1041        return -1;
1042}
1043
1044SOLVOPTINFO *CbcGetOptionEntry(int OptionID)
1045{
1046        int OptionNr;
1047        SOLVOPTINFO *OptionTable;
1048
1049        OptionTable = CbcGetOptionTable();
1050        OptionNr = CbcLocateOptionID(OptionID);
1051        if (OptionNr < 0) {
1052                return NULL;
1053        }
1054        return &OptionTable[OptionNr];
1055}
1056
1057
1058int CbcGetOptionChanged(int OptionID)
1059{
1060        SOLVOPTINFO *OptionEntry;
1061
1062        OptionEntry = CbcGetOptionEntry(OptionID);
1063        if (!OptionEntry) {
1064                return 0;
1065        }
1066        return OptionEntry->changed;
1067}
1068
1069
1070int CbcGetIntOption(int OptionID)
1071{   
1072        SOLVOPTINFO *OptionEntry;
1073
1074        OptionEntry = CbcGetOptionEntry(OptionID);
1075        if (!OptionEntry) {
1076                return 0;
1077        }
1078        if (OptionEntry->OptionType == OPT_REAL) {
1079                return 0;
1080        }
1081        return (int)OptionEntry->CurrentValue;
1082}
1083       
1084int CbcSetIntOption(int OptionID, int IntValue)
1085{
1086        SOLVOPTINFO *OptionEntry;
1087
1088        OptionEntry = CbcGetOptionEntry(OptionID);
1089        if (!OptionEntry) {
1090                return CBC_CALL_FAILED;
1091        }
1092        if (OptionEntry->OptionType == OPT_REAL) {
1093                return CBC_CALL_FAILED;
1094        }
1095        //coinWriteMsgLog("%s[%d] = %d (was %d)",OptionEntry->OptionName, OptionNr, IntValue, (int)OptionEntry->CurrentValue);
1096        OptionEntry->CurrentValue = IntValue;
1097        OptionEntry->changed = 1;
1098        return CBC_CALL_SUCCESS;
1099}
1100
1101
1102double CbcGetRealOption(int OptionID)
1103{
1104        SOLVOPTINFO *OptionEntry;
1105
1106        OptionEntry = CbcGetOptionEntry(OptionID);
1107        if (!OptionEntry) {
1108                return 0.0;
1109        }
1110        if (OptionEntry->OptionType != OPT_REAL) {
1111                return 0.0;
1112        }
1113        return OptionEntry->CurrentValue;
1114}
1115
1116
1117int CbcSetRealOption(int OptionID, double RealValue)
1118{
1119        SOLVOPTINFO *OptionEntry;
1120
1121        OptionEntry = CbcGetOptionEntry(OptionID);
1122        if (!OptionEntry) {
1123                return CBC_CALL_FAILED;
1124        }
1125        if (OptionEntry->OptionType != OPT_REAL) {
1126                return CBC_CALL_FAILED;
1127        }
1128        //coinWriteMsgLog("%s[%d] = %lg (was %lg)",OptionTable[OptionNr].OptionName, OptionNr, RealValue, OptionTable[OptionNr].CurrentValue);
1129        OptionEntry->CurrentValue = RealValue;
1130        OptionEntry->changed = 1;
1131        return CBC_CALL_SUCCESS;
1132}
1133
1134//double
1135// DualTolerance
1136// PrimalTolerance
1137// DualBound
1138// PrimalWeight (setInfeasibilityCost)
1139// MaxTime      (setMaximumSeconds)
1140// ObjScale     (setObjectiveScale)
1141// RhsScale     (setRhsScale)
1142
1143//int
1144//LogLevel      (setLogLovel/model->factorization()->messageLevel(8);)
1145//MaxFactor     (model->factorization()->maximumPivots(value);
1146//PertValue     (setPerturbation)
1147//MaxIteration  (setMaximumIterations)
1148
1149//AutoScale     off
1150//Barrier
1151//BiasLU        UU  (UX, LX, LL)
1152//Crash         off
1153//Direction     min
1154//Directory
1155//dualBound     1e-20, 1e12
1156//dualPivot     Automatic, (Dantzig, partial, Steepest)
1157//DualSimplex
1158//dualTolerance 1e-20,1e12
1159//Exit
1160//ErrorsAllowed
1161//FakeBound
1162//Help
1163//Idiot
1164//Import
1165//KeepNames
1166//LogLevel
1167//Maximize
1168//MaxFactor     1, 999999
1169//MaxIteration  0, 99999999
1170//Messages
1171//ObjScale      -1e20, 1e20
1172//PresolvePass  0, 100
1173//PertValue     -5000, 102, false
1174//Perturbation  On, off
1175//PlusMinus     -1, false
1176//Presolve      On
1177//PrimalPivot     Automatic, (Dantzig, partial, Steepest, change, sprint)
1178//PrimalSimplex
1179//PrimalTolerance 1e-20,1e12
1180//PrimalWeight    1e20, 1e20
1181//RhsScale        -1e20, 1.20
1182//Scaling         Off, Equilibrium, geometric, automatic
1183//MaxTime         0.0, 1e12
1184//SparseFactor    On, Off
1185//SprintCrash     -1, 500
1186
Note: See TracBrowser for help on using the repository browser.