source: trunk/CoinMP/src/CoinMP.cpp @ 68

Last change on this file since 68 was 68, checked in by bjarni, 11 years ago

Fixing CoinGetSolutionStatus?() for MIP problems

  • Property svn:eol-style set to native
File size: 41.3 KB
RevLine 
[44]1/************************************************************************/
2/*                                                                      */
3/*  COINMP.DLL                                        Maximal Software  */
4/*                                                                      */
5/*  File         :  'coinmp.cpp'                                        */
6/*                                                                      */
7/*  Author       :  Bjarni Kristjansson                                 */
8/*                                                                      */
9/*  Copyright (c) 2005-2006                     Bjarni Kristjansson     */
10/*                                                                      */
11/************************************************************************/
12
13
14#include <stdlib.h>
15#include <malloc.h>
16#include <string.h>
17#include <stdio.h>
18#include <stdarg.h>
19
20#include <cfloat>
21
22#include "CoinHelperFunctions.hpp"
23#include "CoinMessageHandler.hpp"
24#include "ClpSimplex.hpp"
25#include "ClpPrimalColumnSteepest.hpp"
26#include "ClpDualRowSteepest.hpp"
27#include "ClpEventHandler.hpp"
28#include "CbcEventHandler.hpp"
29#include "OsiSolverInterface.hpp"
30#include "OsiClpSolverInterface.hpp"
31#include "CbcModel.hpp"
32
33#include "CglProbing.hpp"
34#include "CglGomory.hpp"
35#include "CglKnapsackCover.hpp"
36#include "CglOddHole.hpp"
37#include "CglClique.hpp"
38#include "CglLiftAndProject.hpp"
39#include "CglSimpleRounding.hpp"
40
41
42
43#ifndef COIN_DBL_MAX
44#define COIN_DBL_MAX DBL_MAX
45#endif
46
47
48#define SOLVER_EXPORT
49#define SOLVER_LIB
50#include "CoinMP.h"
51
52
53
54/**************************************************************************/
55
56
57class CBMessageHandler : public CoinMessageHandler {
58public: 
59   void setCallback(MSGLOGCALLBACK callback);
60        virtual int print();
61private:
62        MSGLOGCALLBACK callback_;
63};
64
65
66void CBMessageHandler::setCallback(MSGLOGCALLBACK callback)
67{
68  callback_ = callback;
69}
70
71
72int CBMessageHandler::print()
73{
74        callback_((char *)messageBuffer());
75        return CoinMessageHandler::print();
76}
77
78
79
80/**************************************************************************/
81
82
83class CBIterHandler : public ClpEventHandler {
84
85public: 
86   void setIterCallback(ITERCALLBACK callback);
87   void setNodeCallback(NODECALLBACK callback);
88
89        virtual int event(Event whichEvent);
90   
91  /** Default constructor. */
92  CBIterHandler();
93  /// Constructor with pointer to model (redundant as setEventHandler does)
94  CBIterHandler(ClpSimplex * model);
95  /** Destructor */
96  virtual ~CBIterHandler();
97  /** The copy constructor. */
98  CBIterHandler(const CBIterHandler & rhs);
99  /// Assignment
100  CBIterHandler& operator=(const CBIterHandler & rhs);
101  /// Clone
102  virtual ClpEventHandler * clone() const ;
103
104
105private:
106        ITERCALLBACK iterCallback_;
107        NODECALLBACK nodeCallback_;
108};
109
110
111void CBIterHandler::setIterCallback(ITERCALLBACK callback)
112{
113  iterCallback_ = callback;
114}
115
116
117void CBIterHandler::setNodeCallback(NODECALLBACK callback)
118{
119  nodeCallback_ = callback;
120}
121
122
123int CBIterHandler::event(Event whichEvent)
124{
125        int numIter;
126        double objValue;
127        int isPrimalFeasible;
128        int isDualFeasible;
129        double sumPrimalInfeas; 
130        double sumDualInfeas;
131        int cancelAsap;
132
133        if ((whichEvent==endOfIteration)) {
134                numIter = model_->getIterationCount();
135                objValue = model_->getObjValue();
136                sumDualInfeas = model_->sumDualInfeasibilities();
137                sumPrimalInfeas = model_->sumPrimalInfeasibilities();
138                isPrimalFeasible = model_->primalFeasible();
139                isDualFeasible = model_->dualFeasible();
140                cancelAsap = iterCallback_(numIter, objValue, isPrimalFeasible&&isDualFeasible, sumPrimalInfeas);
141                if (cancelAsap) {
142                        return 5;
143                }
144        }
145        if ((whichEvent == node) ||
146                 (whichEvent == treeStatus) ||
147                 (whichEvent == solution)) {
148                numIter = model_->getIterationCount();
149                objValue = model_->getObjValue();
150                cancelAsap = nodeCallback_(numIter, 0, 0.0, objValue, 0);
151                if (cancelAsap) {
152                        return 5;
153                }
154        }
155        return -1;
156}
157
158
159// Default Constructor
160CBIterHandler::CBIterHandler () : ClpEventHandler() {}
161
162// Copy constructor
163CBIterHandler::CBIterHandler (const CBIterHandler & rhs) : ClpEventHandler(rhs) {}
164
165// Constructor with pointer to model
166CBIterHandler::CBIterHandler(ClpSimplex * model) : ClpEventHandler(model) {}
167
168// Destructor
169CBIterHandler::~CBIterHandler () {}
170
171// Assignment operator
172CBIterHandler & CBIterHandler::operator=(const CBIterHandler& rhs)
173{
174  if (this != &rhs) {
175    ClpEventHandler::operator=(rhs);
176  }
177  return *this;
178}
179
180// Clone
181ClpEventHandler * CBIterHandler::clone() const
182{
183        CBIterHandler * iterhandler;
184
185   iterhandler = new CBIterHandler(*this);
186        iterhandler->iterCallback_ = this->iterCallback_;
187        iterhandler->nodeCallback_ = this->nodeCallback_;
188        return iterhandler;
189}
190
191
192
193/**************************************************************************/
194
195
196class CBNodeHandler : public CbcEventHandler {
197
198public: 
199   void setCallback(NODECALLBACK callback);
200
201        virtual CbcAction event(CbcEvent whichEvent);
202   
203  /** Default constructor. */
204  CBNodeHandler();
205  /// Constructor with pointer to model (redundant as setEventHandler does)
206  //JPF CBNodeHandler(ClpSimplex * model);
207  CBNodeHandler(CbcModel * model);
208 
209
210  /** Destructor */
211  virtual ~CBNodeHandler();
212  /** The copy constructor. */
213  CBNodeHandler(const CBNodeHandler & rhs);
214  /// Assignment
215  CBNodeHandler& operator=(const CBNodeHandler & rhs);
216  /// Clone
217  virtual CbcEventHandler * clone() const ;
218
219
220private:
221        NODECALLBACK callback_;
222};
223
224
225void CBNodeHandler::setCallback(NODECALLBACK callback)
226{
227  callback_ = callback;
228}
229
230
231CBNodeHandler::CbcAction CBNodeHandler::event(CbcEvent whichEvent)
232{
233        int numIter;
234        double objValue;
235        int cancelAsap;
236
237        if (whichEvent==node) {
238                numIter = model_->getIterationCount();
239                objValue = model_->getObjValue();
240                cancelAsap = callback_(numIter, 0, 0.0, objValue, 0);
241                if (cancelAsap) {
242                        return stop;
243                }
244        }
245        return noAction;
246}
247
248
249// Default Constructor
250CBNodeHandler::CBNodeHandler () : CbcEventHandler() {}
251
252// Copy constructor
253CBNodeHandler::CBNodeHandler (const CBNodeHandler & rhs) : CbcEventHandler(rhs) {}
254
255// Constructor with pointer to model
256//JPF: CBNodeHandler::CBNodeHandler(ClpSimplex * model) : CbcEventHandler(model) {}
257CBNodeHandler::CBNodeHandler(CbcModel * model) : CbcEventHandler(model) {}
258
259// Destructor
260CBNodeHandler::~CBNodeHandler () {}
261
262// Assignment operator
263CBNodeHandler & CBNodeHandler::operator=(const CBNodeHandler& rhs)
264{
265  if (this != &rhs) {
266    CbcEventHandler::operator=(rhs);
267  }
268  return *this;
269}
270
271// Clone
272CbcEventHandler * CBNodeHandler::clone() const
273{
274        CBNodeHandler * nodehandler;
275
276   nodehandler = new CBNodeHandler(*this);
277        nodehandler->callback_ = this->callback_;
278        return nodehandler;
279}
280
281
282
283/**************************************************************************/
284
285typedef struct {
286                                ClpSimplex *clp;
287                                CbcModel *cbc;
288                                OsiClpSolverInterface *osi;
289
290                                CBMessageHandler *msghandler;
291                                CBIterHandler *iterhandler;
292                                CBNodeHandler *nodehandler;
293
294                                CglProbing *probing;
295                                CglGomory *gomory;
296                                CglKnapsackCover *knapsack;
297                                CglOddHole *oddhole;
298                                CglClique *clique;
299                                CglLiftAndProject *liftpro;
300                                CglSimpleRounding *rounding;
301
302                                int SolutionStatus;
303                                int RowCount, ColCount;
304                                double *RowLower;
305                                double *RowUpper;
306                                char SolutionText[100];
307                                char *IsInt;
308                                int SolveAsMIP;
309                                MSGLOGCALLBACK  MessageLogCallback;
310                                ITERCALLBACK    IterationCallback;
311                                NODECALLBACK    MipNodeCallback;
312                                } COININFO, *PCOIN;
313 
314
315
316PCOIN global_pCoin;
317
318
319
320SOLVAPI int CoinInitSolver(char *LicenseStr)
321{
322        return SOLV_SUCCESS;
323}
324
325
326SOLVAPI int CoinFreeSolver(void)
327{
328        return SOLV_SUCCESS;
329}
330
331
332
333SOLVAPI char*  CoinGetSolverName(void)
334{
335        return "CoinMP";
336}
337
338
339SOLVAPI char*  CoinGetVersionStr(void)
340{
341        return "1.0";
342}
343
344
345SOLVAPI double CoinGetVersion(void)
346{
347        return 1.0;
348}
349
350
351SOLVAPI int    CoinGetFeatures(void)
352{
353        return 0;
354}
355
356
357
358SOLVAPI double CoinGetRealMax(void)
359{
360        return COIN_DBL_MAX;
361}
362
363
364
365SOLVAPI HPROB CoinCreateProblem(char *ProblemName)
366{
367   PCOIN pCoin;
368
369   pCoin = (PCOIN) malloc(sizeof(COININFO));
370   global_pCoin = pCoin;
371   pCoin->clp = new ClpSimplex();
372        pCoin->osi = new OsiClpSolverInterface(pCoin->clp);
373        pCoin->cbc = NULL;  /* ERRORFIX 2/22/05: Crashes if not NULL when trying to set message handler */
374        pCoin->msghandler = NULL;
375        pCoin->iterhandler = NULL;
376        pCoin->nodehandler = NULL;
377        pCoin->ColCount = 0;
378        pCoin->RowCount = 0;
379        pCoin->RowLower = NULL;
380        pCoin->RowUpper = NULL;
381        pCoin->IsInt = 0;
382        pCoin->SolveAsMIP = 0;
383   return (HPROB)pCoin;
384}
385
386
387
388SOLVAPI int CoinLoadProblem(HPROB hProb, int ColCount, int RowCount, int NonZeroCount, 
389                                                                                        int RangeCount, int ObjectSense, double* ObjectCoeffs, 
390                                                                                        double* RHSValues, double* RangeValues, char* RowType, 
391                                                                                        int* MatrixBegin, int* MatrixCount, int* MatrixIndex, 
392                                                                                        double* MatrixValues, double* LowerBounds, double* UpperBounds, 
393                                                                                        double* InitValues, char** ColNames, char** RowNames)
394{
395   PCOIN pCoin = (PCOIN)hProb;
396   int i;
397
398        pCoin->ColCount = ColCount;
399        pCoin->RowCount = RowCount;
400
401        pCoin->clp->setOptimizationDirection(ObjectSense);
402
403        pCoin->RowLower = (double *)malloc(RowCount*sizeof(double));
404        pCoin->RowUpper = (double *)malloc(RowCount*sizeof(double));
405        if (!pCoin->RowLower && !pCoin->RowUpper) {
406                return SOLV_FAILED;
407        }
408   for( i = 0; i < RowCount; i++ ){
409                switch (RowType[i]) {
410                        case 'L':
411                                pCoin->RowLower[i] = -COIN_DBL_MAX;
412                                pCoin->RowUpper[i] = RHSValues[i];
413                                break;
414
415                        case 'G':
416                                pCoin->RowLower[i] = RHSValues[i];
417                                pCoin->RowUpper[i] = COIN_DBL_MAX;
418                                break;
419
420                        case 'E':
421                                pCoin->RowLower[i] = RHSValues[i];
422                                pCoin->RowUpper[i] = RHSValues[i];
423                                break;
424
425                        case 'R':
426                                if (RangeValues[i] < 0.0)
427                                        pCoin->RowLower[i] = RHSValues[i]+RangeValues[i];
428                                else {
429                                        pCoin->RowLower[i] = RHSValues[i]-RangeValues[i];
430                                }
431                                pCoin->RowUpper[i] = RHSValues[i];
432                                break;
433                }
434        }
435   pCoin->clp->loadProblem(ColCount, RowCount, MatrixBegin, MatrixIndex, MatrixValues,
436                                                        LowerBounds, UpperBounds, ObjectCoeffs, pCoin->RowLower, pCoin->RowUpper);
437
438
439        std::vector<std::string> rowNameList;
440        rowNameList.reserve(RowCount);
441        for (i = 0; i < RowCount; i++) {
442                rowNameList.push_back(RowNames[i]);
443        }
444        std::vector<std::string> colNameList;
445        colNameList.reserve(ColCount);
446        for (i = 0; i < ColCount; i++) {
447                colNameList.push_back(ColNames[i]);
448        }
449        pCoin->clp->copyNames(rowNameList, colNameList);
450
451   return SOLV_SUCCESS;
452}
453
454
455SOLVAPI int CoinLoadInteger(HPROB hProb, char* ColumnType)
456{   
457        PCOIN pCoin = (PCOIN)hProb;
458        int i;
459
460        pCoin->IsInt = (char *)malloc(pCoin->ColCount*sizeof(char));
461        if (!pCoin->IsInt) {
462                return SOLV_FAILED;
463        }
464        for (i = 0; i < pCoin->ColCount; i++ ) {
465                if ( ColumnType[i] == 'B' || ColumnType[i] == 'I' ) {
466                        pCoin->IsInt[i] = 1;
467                        pCoin->SolveAsMIP = 1;
468                        //pCoin->cbc->solver()->setInteger(i);
469                }
470                else {
471                        pCoin->IsInt[i] = 0;
472                        //pCoin->cbc->solver()->setContinuous(i);
473                }
474        }
475        if (pCoin->SolveAsMIP) {
476                //pCoin->clp->copyInIntegerInformation(pCoin->IsInt);
477                pCoin->cbc = new CbcModel(*pCoin->osi);
478                for (i = 0; i < pCoin->ColCount; i++ ) {
479                        if (pCoin->IsInt[i]) {
480                                pCoin->cbc->solver()->setInteger(i);
481                        }
482                }
483        }
484        //pCoin->cbc->solver()->copyInIntegerInformation(pCoin->IsInt);
485
486        return SOLV_SUCCESS;
487}
488
489
490
491SOLVAPI int CoinLoadPriority(HPROB hProb, int PriorCount, int *PriorIndex, 
492                                                                          int *PriorValues, int *BranchDir)
493{
494        return SOLV_FAILED;
495}
496
497
498SOLVAPI int CoinLoadSos(HPROB hProb, int SosCount, int SosNZCount, 
499                                                                char *SosType, int *SosPrior, int *SosBegin,   
500                                                                int *SosIndex, double *SosRef)
501{
502        return SOLV_FAILED;
503}
504
505
506SOLVAPI int CoinLoadQuadratic(HPROB hProb, int *QuadBegin, int *QuadCount, 
507                                                                                int *QuadIndex, double *QuadValues)
508{
509        return SOLV_FAILED;
510}
511
512
[47]513SOLVAPI int CoinLoadNonlinear(HPROB hProb, int NlpTreeCount, int NlpLineCount, 
[44]514                                                                                int *NlpBegin, int *NlpOper, int *NlpArg1, 
515                                                                                int *NlpArg2, int *NlpIndex1, int *NlpIndex2, 
516                                                                                double *NlpValue1, double *NlpValue2)
517{
518        return SOLV_FAILED;
519}
520
521
522
[47]523SOLVAPI int CoinUnloadProblem(HPROB hProb)
[44]524{
525   PCOIN pCoin = (PCOIN)hProb;
526       
527        if (pCoin) {
528                delete pCoin->clp;
529                if (pCoin->RowLower) free(pCoin->RowLower);
530                if (pCoin->RowUpper) free(pCoin->RowUpper);
531                if (pCoin->IsInt) free(pCoin->IsInt);
532        }
533        free(pCoin);
534        pCoin = NULL;
535        return SOLV_SUCCESS;
536}
537
538
539
540/****************************************************************/
541
542
543int CoinWriteMsgLog(char *FormatStr, ...)
544{
545   va_list pVa;
546   char strbuf[256];
547
548   va_start(pVa,FormatStr);
549   vsprintf(strbuf,FormatStr,pVa);
550        global_pCoin->MessageLogCallback(strbuf);
551        return SOLV_SUCCESS;
552}
553
554
555int CoinIterLogCallback(int IterCount, double ObjectValue, int IsFeasible, double InfeasValue)
556{
557        if (!global_pCoin->SolveAsMIP) {
558                if (((IterCount < 100) && ((IterCount % 10) == 0)) ||
559                         ((IterCount % 100) == 0)) {
560                        if (!IsFeasible)
561                                CoinWriteMsgLog("Iteration: %5d  %16.8lg  %16.8lg",IterCount, ObjectValue, InfeasValue);
562                        else {
563                                CoinWriteMsgLog("Iteration: %5d  %16.8lg",IterCount, ObjectValue);
564                        }
565                }
566        }
567        global_pCoin->IterationCallback(IterCount, ObjectValue, IsFeasible, InfeasValue);
568        return SOLV_SUCCESS;
569}
570
571
572int CoinNodeLogCallback(int IterCount, int NodeCount, double BestBound, double BestObject, int IsMipImproved)
573{
574        if ((NodeCount > 0) && (((NodeCount % 100) == 0) || (IsMipImproved))) {
575                CoinWriteMsgLog("Node: %5d  %s  %16.8lg  %16.8lg", 
576                                   NodeCount, (IsMipImproved) ? "*" : " ", BestBound, BestObject);
577        }
578   global_pCoin->MipNodeCallback(IterCount, NodeCount, BestBound, BestObject, IsMipImproved);
579        return SOLV_SUCCESS;
580}
581
582
583
584
585SOLVAPI int CoinSetMsgLogCallback(HPROB hProb, MSGLOGCALLBACK MsgLogCallback)
586{
587   PCOIN pCoin = (PCOIN)hProb;
588
589   pCoin->MessageLogCallback = MsgLogCallback;
590        delete pCoin->msghandler;
591        pCoin->msghandler = new CBMessageHandler();
592        pCoin->msghandler->setCallback(MsgLogCallback);
593        pCoin->msghandler->setLogLevel(CoinGetIntOption(hProb, COIN_INT_LOGLEVEL));
594        if (pCoin->clp) pCoin->clp->passInMessageHandler(pCoin->msghandler);
595        if (pCoin->cbc) pCoin->cbc->passInMessageHandler(pCoin->msghandler);
596        if (pCoin->osi) pCoin->osi->passInMessageHandler(pCoin->msghandler);
597        return SOLV_SUCCESS;
598}
599
600
601
602SOLVAPI int CoinSetIterCallback(HPROB hProb, ITERCALLBACK IterCallback)
603{
604   PCOIN pCoin = (PCOIN)hProb;
605
606   pCoin->IterationCallback = IterCallback;
607        delete pCoin->iterhandler;
608        pCoin->iterhandler = new CBIterHandler(pCoin->clp);
609        pCoin->iterhandler->setIterCallback(IterCallback);
610        if (pCoin->clp) pCoin->clp->passInEventHandler(pCoin->iterhandler);
611        return SOLV_SUCCESS;
612}
613
614
615SOLVAPI int CoinSetMipNodeCallback(HPROB hProb, NODECALLBACK NodeCallback)
616{
617   PCOIN pCoin = (PCOIN)hProb;
618
[48]619        return SOLV_FAILED;  // BK 7/26/2006: using the NodeCallback crashes CBC!
620
[44]621   pCoin->MipNodeCallback = NodeCallback;
622        delete pCoin->nodehandler;
623
624        //JPF: pCoin->nodehandler = new CBNodeHandler(pCoin->clp);
625        pCoin->nodehandler = new CBNodeHandler(pCoin->cbc);
626
627        pCoin->nodehandler->setCallback(NodeCallback);
628        //if (pCoin->iterhandler) pCoin->iterhandler->setNodeCallback(NodeCallback);
629        if (pCoin->cbc) pCoin->cbc->passInEventHandler(pCoin->nodehandler);
630        return SOLV_SUCCESS;
631}
632
633
634
635/****************************************************************/
636
637SOLVAPI int CoinOptimizeProblem(HPROB hProb, int Method)
638{               
639   PCOIN pCoin = (PCOIN)hProb;
640   ClpSolve clp_options;
641        ClpSolve::SolveType method;
642        ClpSolve::PresolveType presolve;
643
644        pCoin->clp->scaling(CoinGetIntOption(hProb,COIN_INT_SCALING));
645        pCoin->clp->setPerturbation(CoinGetIntOption(hProb, COIN_INT_PERTURBATION));
646
647        pCoin->clp->setMaximumIterations(CoinGetIntOption(hProb, COIN_INT_MAXITER));
648
649        pCoin->clp->setPrimalObjectiveLimit(CoinGetIntOption(hProb, COIN_REAL_PRIMALOBJLIM));
650        pCoin->clp->setDualObjectiveLimit(CoinGetIntOption(hProb, COIN_REAL_DUALOBJLIM));
651        pCoin->clp->setPrimalTolerance(CoinGetIntOption(hProb, COIN_REAL_PRIMALOBJTOL));
652        pCoin->clp->setDualTolerance(CoinGetIntOption(hProb, COIN_REAL_DUALOBJTOL));
653
654        /* check if it has been changed, leave alone otherwise */
655   ClpPrimalColumnSteepest primalSteepest(CoinGetIntOption(hProb, COIN_INT_PRIMALPIVOTALG));
656   pCoin->clp->setPrimalColumnPivotAlgorithm(primalSteepest);
657
658   ClpDualRowSteepest dualSteepest(CoinGetIntOption(hProb, COIN_INT_DUALPIVOTALG));
659   pCoin->clp->setDualRowPivotAlgorithm(dualSteepest);
660
661        if (CoinGetIntOption(hProb, COIN_INT_CRASHIND)) {
662                pCoin->clp->crash(CoinGetIntOption(hProb, COIN_REAL_CRASHGAP),
663                                                                CoinGetIntOption(hProb, COIN_INT_CRASHPIVOT));
664        }
665        switch (CoinGetIntOption(hProb,COIN_INT_SOLVEMETHOD)) {
666                case 0: method = ClpSolve::useDual;                              break;
667                case 1: method = ClpSolve::usePrimal;                    break;
668                case 2: method = ClpSolve::usePrimalorSprint; break;
669                case 3: method = ClpSolve::useBarrier;                   break;
670                case 4: method = ClpSolve::useBarrierNoCross; break;
671                case 5: method = ClpSolve::automatic;                    break;
672                default: method = ClpSolve::usePrimal;
673        }
674        pCoin->clp->setSolveType(method);   //ClpSolve::usePrimal
675
676        switch (CoinGetIntOption(hProb,COIN_INT_PRESOLVETYPE)) {
677                case 0: presolve = ClpSolve::presolveOn;                 break;
678                case 1: presolve = ClpSolve::presolveOff;                break;
679                case 2: presolve = ClpSolve::presolveNumber;     break;
680                default: presolve = ClpSolve::presolveOn;
681        }
682        clp_options.setPresolveType(presolve);   //ClpSolve::presolveOn
683
684        if (!pCoin->SolveAsMIP) {
685                pCoin->clp->initialSolve(clp_options);
686                pCoin->SolutionStatus = pCoin->clp->status();
687                }
688        else {
689                pCoin->cbc->setMaximumNodes(CoinGetIntOption(hProb, COIN_INT_MIPMAXNODES));
690                pCoin->cbc->setMaximumSolutions(CoinGetIntOption(hProb, COIN_INT_MIPMAXSOL));
691                pCoin->cbc->setDblParam(CbcModel::CbcMaximumSeconds,CoinGetRealOption(hProb, COIN_REAL_MIPMAXSEC));
692
693                pCoin->cbc->setIntParam(CbcModel::CbcFathomDiscipline,CoinGetIntOption(hProb, COIN_INT_MIPFATHOMDISC));
694
695                // JPF commented: pCoin->cbc->setHotstartStrategy(CoinGetIntOption(hProb, COIN_INT_MIPHOTSTART));
696                //              pCoin->cbc->setForcePriority(CoinGetIntOption(hProb, COIN_INT_MIPFORCEPRIOR));
697
698                pCoin->cbc->setMinimumDrop(CoinGetIntOption(hProb, COIN_INT_MIPMINIMUMDROP));
699                pCoin->cbc->setMaximumCutPassesAtRoot(CoinGetIntOption(hProb, COIN_INT_MIPMAXPASSROOT));
700                pCoin->cbc->setMaximumCutPasses(CoinGetIntOption(hProb, COIN_INT_MIPMAXCUTPASS));
701                pCoin->cbc->setNumberStrong(CoinGetIntOption(hProb, COIN_INT_MIPSTRONGBRANCH));
702                pCoin->cbc->setHowOftenGlobalScan(CoinGetIntOption(hProb, COIN_INT_MIPSCANGLOBCUTS));
703
704                pCoin->cbc->setIntegerTolerance(CoinGetRealOption(hProb, COIN_REAL_MIPINTTOL));
705                pCoin->cbc->setInfeasibilityWeight(CoinGetRealOption(hProb, COIN_REAL_MIPINFWEIGHT));
706                pCoin->cbc->setDblParam(CbcModel::CbcCutoffIncrement,CoinGetRealOption(hProb, COIN_REAL_MIPCUTOFF));
707                pCoin->cbc->setAllowableGap(CoinGetRealOption(hProb, COIN_REAL_MIPABSGAP));
708
709                /* see CbcModel.hpp has commments on calling cuts */
710
711                if (CoinGetIntOption(hProb, COIN_INT_MIPCUT_PROBING)) {
712                        pCoin->probing = new CglProbing();
713                        pCoin->probing->setMode(CoinGetIntOption(hProb, COIN_INT_MIPPROBE_MODE));
714                        pCoin->probing->setUsingObjective(CoinGetIntOption(hProb, COIN_INT_MIPPROBE_USEOBJ) ? true : false);
715                        pCoin->probing->setMaxPass(CoinGetIntOption(hProb, COIN_INT_MIPPROBE_MAXPASS));
716                        pCoin->probing->setMaxProbe(CoinGetIntOption(hProb, COIN_INT_MIPPROBE_MAXPROBE));
717                        pCoin->probing->setMaxLook(CoinGetIntOption(hProb, COIN_INT_MIPPROBE_MAXLOOK));
718                        pCoin->probing->setRowCuts(CoinGetIntOption(hProb, COIN_INT_MIPPROBE_ROWCUTS));
719                        pCoin->cbc->addCutGenerator(pCoin->probing,CoinGetIntOption(hProb, COIN_INT_MIPPROBE_FREQ),"Probing");
720                }
721
722                if (CoinGetIntOption(hProb, COIN_INT_MIPCUT_GOMORY)) {
723                        pCoin->gomory = new CglGomory();
724                        pCoin->gomory->setLimit(CoinGetIntOption(hProb, COIN_INT_MIPGOMORY_LIMIT));
725                        pCoin->gomory->setAway(CoinGetRealOption(hProb, COIN_REAL_MIPGOMORY_AWAY));
726                        pCoin->cbc->addCutGenerator(pCoin->gomory,CoinGetIntOption(hProb, COIN_INT_MIPGOMORY_FREQ),"Gomory");
727                }
728
729                if (CoinGetIntOption(hProb, COIN_INT_MIPCUT_KNAPSACK)) {
730                        pCoin->knapsack = new CglKnapsackCover();
731                        pCoin->knapsack->setMaxInKnapsack(CoinGetIntOption(hProb, COIN_INT_MIPKNAPSACK_MAXIN));
732                        pCoin->cbc->addCutGenerator(pCoin->knapsack,CoinGetIntOption(hProb, COIN_INT_MIPKNAPSACK_FREQ),"Knapsack");
733                }
734
735                if (CoinGetIntOption(hProb, COIN_INT_MIPCUT_ODDHOLE)) {
736                        pCoin->oddhole= new CglOddHole();
737                        pCoin->oddhole->setMinimumViolation(CoinGetRealOption(hProb, COIN_REAL_MIPODDHOLE_MINVIOL));
738                        pCoin->oddhole->setMinimumViolationPer(CoinGetRealOption(hProb, COIN_REAL_MIPODDHOLE_MINVIOLPER));
739                        pCoin->oddhole->setMaximumEntries(CoinGetIntOption(hProb, COIN_INT_MIPODDHOLE_MAXENTRIES));
740                        pCoin->cbc->addCutGenerator(pCoin->oddhole,CoinGetIntOption(hProb, COIN_INT_MIPODDHOLE_FREQ),"OddHole");
741                }
742
743                if (CoinGetIntOption(hProb, COIN_INT_MIPCUT_CLIQUE)) {
744                        pCoin->clique= new CglClique(CoinGetIntOption(hProb, COIN_INT_MIPCLIQUE_PACKING) ? true : false);
745                        pCoin->clique->setDoStarClique(CoinGetIntOption(hProb, COIN_INT_MIPCLIQUE_STAR) ? true : false);
746                        pCoin->clique->setStarCliqueNextNodeMethod((CglClique::scl_next_node_method)CoinGetIntOption(hProb, COIN_INT_MIPCLIQUE_STARMETHOD));
747                        pCoin->clique->setStarCliqueCandidateLengthThreshold(CoinGetIntOption(hProb, COIN_INT_MIPCLIQUE_STARMAXLEN));
748                        pCoin->clique->setStarCliqueReport(CoinGetIntOption(hProb, COIN_INT_MIPCLIQUE_STARREPORT) ? true : false);
749                        pCoin->clique->setDoRowClique(CoinGetIntOption(hProb, COIN_INT_MIPCLIQUE_ROW) ? true : false);
750                        pCoin->clique->setRowCliqueCandidateLengthThreshold(CoinGetIntOption(hProb, COIN_INT_MIPCLIQUE_ROWMAXLEN));
751                        pCoin->clique->setRowCliqueReport(CoinGetIntOption(hProb, COIN_INT_MIPCLIQUE_ROWREPORT) ? true : false);
752                        pCoin->clique->setMinViolation(CoinGetRealOption(hProb, COIN_REAL_MIPCLIQUE_MINVIOL));
753                        pCoin->cbc->addCutGenerator(pCoin->clique,CoinGetIntOption(hProb, COIN_INT_MIPCLIQUE_FREQ),"Clique");
754                }
755
756                if (CoinGetIntOption(hProb, COIN_INT_MIPCUT_LIFTPROJECT)) {
757                        pCoin->liftpro = new CglLiftAndProject();
758                        pCoin->liftpro->setBeta(CoinGetIntOption(hProb, COIN_INT_MIPLIFTPRO_BETAONE) ? 1 : -1);
759                        pCoin->cbc->addCutGenerator(pCoin->liftpro,CoinGetIntOption(hProb, COIN_INT_MIPLIFTPRO_FREQ),"LiftProject");
760                }
761
762                if (CoinGetIntOption(hProb, COIN_INT_MIPCUT_SIMPROUND)) {
763                        pCoin->rounding = new CglSimpleRounding();
764                        pCoin->cbc->addCutGenerator(pCoin->rounding,CoinGetIntOption(hProb, COIN_INT_MIPSIMPROUND_FREQ),"Rounding");
765                }
766
767                pCoin->cbc->initialSolve();
768                pCoin->cbc->branchAndBound();
769                pCoin->SolutionStatus = pCoin->cbc->status();
770        }
771       
772        return pCoin->SolutionStatus;
773}
774
775
776
777SOLVAPI int CoinGetSolutionStatus(HPROB hProb)
778{
779   PCOIN pCoin = (PCOIN)hProb;
780
[68]781        return pCoin->SolutionStatus;
[44]782}
783
784
785
786SOLVAPI char * CoinGetSolutionText(HPROB hProb, int SolutionStatus)
787{
788   PCOIN pCoin = (PCOIN)hProb;
789
790        switch (SolutionStatus) {
791                case 0: strcpy(pCoin->SolutionText, "Optimal solution found");          break;
792                case 1: strcpy(pCoin->SolutionText, "Problem primal infeasible");       break;
793                case 2:  strcpy(pCoin->SolutionText, "Problem dual infeasible");                break;
794                case 3:  strcpy(pCoin->SolutionText, "Stopped on iterations");                  break;
795                case 4:         strcpy(pCoin->SolutionText, "Stopped due to errors");                   break;
796                case 5:         strcpy(pCoin->SolutionText, "Stopped by user");         break;
797        }
798        return pCoin->SolutionText;
799}
800
801
802
803SOLVAPI double CoinGetObjectValue(HPROB hProb)
804{
805   PCOIN pCoin = (PCOIN)hProb;
806
807        if (!pCoin->SolveAsMIP) 
808                return pCoin->clp->objectiveValue();
809        else {
810                return pCoin->cbc->getObjValue();
811        }
812}
813
814
815SOLVAPI double CoinGetMipBestBound(HPROB hProb)
816{
817   PCOIN pCoin = (PCOIN)hProb;
818
819   return 0;
820}
821
822
823SOLVAPI int CoinGetIterCount(HPROB hProb)
824{
825   PCOIN pCoin = (PCOIN)hProb;
826
827   return pCoin->clp->numberIterations();
828}
829
830
831SOLVAPI int CoinGetNodeCount(HPROB hProb)
832{
833   PCOIN pCoin = (PCOIN)hProb;
834
835        if (!pCoin->SolveAsMIP) 
836                return 0;
837        else {
838                return pCoin->cbc->getNodeCount();
839        }
840}
841
842
843/****************************************************************/
844
845
846SOLVAPI int CoinGetSolutionValues(HPROB hProb, double* Activity, double* ReducedCost, 
847                                                                                         double* SlackValues, double* ShadowPrice)
848{
849   PCOIN pCoin = (PCOIN)hProb;
850        const double *columnPrimal;
851        const double *columnDual;
852        const double *rowPrimal;
853        const double *rowDual;
854        int i;
855
856        if (pCoin->SolveAsMIP) {
857                if (Activity) {
858                        columnPrimal = pCoin->cbc->solver()->getColSolution();
859                        for (i = 0; i < pCoin->ColCount; i++) {
860                                Activity[i] = columnPrimal[i];
861                        }
862                        return SOLV_SUCCESS;
863                }
864                return SOLV_FAILED;
865        }
866
867        if (Activity) {
868                columnPrimal = pCoin->clp->primalColumnSolution();
869                for (i = 0; i < pCoin->ColCount; i++) {
870                        Activity[i] = columnPrimal[i];
871                }
872   }
873        if (ReducedCost) {
874                columnDual = pCoin->clp->dualColumnSolution();
875                for (i = 0; i < pCoin->ColCount; i++) {
876                        ReducedCost[i] = columnDual[i];
877                }
878   }
879        if (SlackValues) {
880                rowPrimal = pCoin->clp->primalRowSolution();
881                for (i = 0; i < pCoin->RowCount; i++) {
882                        SlackValues[i] = rowPrimal[i];
883                }
884   }
885        if (ShadowPrice) {
886                rowDual = pCoin->clp->dualRowSolution();
887                for (i = 0; i < pCoin->RowCount; i++) {
888                        ShadowPrice[i] = rowDual[i];
889                }
890   }
891   return SOLV_SUCCESS;
892}
893
894
895
896SOLVAPI int CoinGetSolutionRanges(HPROB hProb, double *ObjLoRange, double *ObjUpRange,
897                                                                                         double *RhsLoRange, double *RhsUpRange)
898{
899        return SOLV_FAILED;
900}
901
902
903
904SOLVAPI int CoinGetSolutionBasis(HPROB hProb, int *ColStatus, double *RowStatus)
905{
906        return SOLV_FAILED;
907}
908
909
910
911/****************************************************************/
912
913
914SOLVAPI int CoinReadFile(HPROB hProb, int FileType, char* ReadFilename)
915{
916   PCOIN pCoin = (PCOIN)hProb;
917
918        switch (FileType) {
919                case SOLV_FILE_MPS:             pCoin->clp->readMps(ReadFilename, 1, 0);    break;
920
921                case SOLV_FILE_LP: 
922                case SOLV_FILE_BASIS: 
923                case SOLV_FILE_IIS: 
924
925                default:
926                        return SOLV_FAILED;
927        }
928        return SOLV_SUCCESS;
929}
930
931
932
933SOLVAPI int CoinWriteFile(HPROB hProb, int FileType, char* WriteFilename)
934{
935   PCOIN pCoin = (PCOIN)hProb;
936
937        switch (FileType) {
938                case SOLV_FILE_MPS:             pCoin->clp->writeMps(WriteFilename);    break;
939
940                case SOLV_FILE_LP: 
941                case SOLV_FILE_BASIS: 
942                case SOLV_FILE_IIS: 
943
944                default:
945                        return SOLV_FAILED;
946
947        }
948        return SOLV_SUCCESS;
949}
950
951
952
953SOLVAPI int CoinOpenLogFile(HPROB hProb, char* logFilename)
954{
955   PCOIN pCoin = (PCOIN)hProb;
956
957        return SOLV_SUCCESS;
958}
959
960
961SOLVAPI int CoinCloseLogFile(HPROB hProb)
962{
963   PCOIN pCoin = (PCOIN)hProb;
964
965        return SOLV_SUCCESS;
966}
967
968
969/****************************************************************/
970/****************************************************************/
971
972
973#define MAXINT          2100000000L
974#define MAXREAL         COIN_DBL_MAX
975
976#define ROUND(x)       (((x)>0)?((long)((x)+0.5)):((long)((x)-0.5)))
977
978
979#define OPT_NONE                                0
980#define OPT_ONOFF                               1
981#define OPT_LIST                                2
982#define OPT_INT                         3
983#define OPT_REAL                                4
984#define OPT_STRING                      5
985
986#define GRP_NONE           0
987#define GRP_OTHER          0
988
989#define GRP_SIMPLEX                     1
990#define GRP_PREPROC                     2
991#define GRP_LOGFILE                     3
992#define GRP_LIMITS                      4
993#define GRP_MIPSTRAT                    5
994#define GRP_MIPCUTS        6
995#define GRP_MIPTOL                      7
996#define GRP_BARRIER                     8
997#define GRP_NETWORK                     9
998
999
1000
1001
1002typedef int    OPTINT;
1003typedef double OPTVAL;
1004
1005typedef struct {
1006           char   OptionName[32];
1007                          char   ShortName[32];
1008                          int    GroupType;
1009           OPTVAL DefaultValue;
1010           OPTVAL CurrentValue;
1011           OPTVAL MinValue;
1012           OPTVAL MaxValue;
1013                          int           OptionType;
1014           int    changed;
1015           int    OptionID;
1016        } SOLVOPTINFO, *PSOLVOPT;
1017
1018
1019#define OPTIONCOUNT    66
1020
1021
1022
1023SOLVOPTINFO OptionTable[OPTIONCOUNT] = {
1024
1025          "SolveMethod",                            "SolveMethod",  GRP_SIMPLEX,        0,        0,      0,       5,  OPT_LIST,   0,   COIN_INT_SOLVEMETHOD,
1026      /*enum SolveType { useDual=0, usePrimal, usePrimalorSprint, useBarrier, useBarrierNoCross, automatic*/
1027          "PresolveType",                   "Presolve",     GRP_SIMPLEX,        0,        0,      0,       2,  OPT_LIST,   0,   COIN_INT_PRESOLVETYPE,
1028                /*enum PresolveType { presolveOn=0, presolveOff, presolveNumber }; */
1029          "Scaling",                             "Scaling",      GRP_SIMPLEX,        3,        3,      0,       4,  OPT_LIST,   0,   COIN_INT_SCALING, 
1030      /* Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) */
1031     "Perturbation",                     "Perturb",      GRP_SIMPLEX,      100,      100,      0,     100,  OPT_INT,    0,   COIN_INT_PERTURBATION, 
1032                /* 0 - Off, 50 - On, 100 - Only if clp stalls */
1033          "PrimalColPivotAlg",           "PrimPivAlg",   GRP_SIMPLEX,        1,        1,      0,       4,  OPT_LIST,   0,   COIN_INT_PRIMALPIVOTALG, 
1034      /*0 is exact devex, 1 full steepest, 2 is partial exact devex
1035      3 switches between 0 and 2 depending on factorization
1036      4 starts as partial dantzig/devex but then may switch between 0 and 2.*/
1037          "DualRowPivotAlg",             "DualPivAlg",   GRP_SIMPLEX,        1,        1,      0,       3,  OPT_LIST,   0,   COIN_INT_DUALPIVOTALG, 
1038      /*0 is uninitialized, 1 full, 2 is partial uninitialized,
1039      3 starts as 2 but may switch to 1.*/
1040          "LogLevel",               "LogLevel",     GRP_LOGFILE,        1,        1,      0,       4,  OPT_LIST,   0,   COIN_INT_LOGLEVEL, 
1041          "MaxIterations",                       "MaxIter",      GRP_LIMITS,  99999999, 99999999,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MAXITER, 
1042     "MaxSeconds",                       "MaxSeconds",   GRP_LIMITS,      -1.0,     -1.0,   -1.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_MAXSECONDS, 
1043
1044     "CrashInd",                         "CrashInd",     GRP_SIMPLEX,        0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_CRASHIND, 
1045     "CrashPivot",                       "CrashPivot",   GRP_SIMPLEX,        0,        0,     -1,       2,  OPT_LIST,   0,   COIN_INT_CRASHPIVOT, 
1046     "CrashGap",                         "CrashGap",     GRP_SIMPLEX,   1000.0,   1000.0,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_CRASHGAP, 
1047     "PrimalObjectLimit",                "PrimalObjLim", GRP_SIMPLEX,  MAXREAL,  MAXREAL,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_PRIMALOBJLIM, 
1048     "DualObjectLimit",                  "DualObjLim",   GRP_SIMPLEX,  MAXREAL,  MAXREAL,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_DUALOBJLIM, 
1049     "PrimalTolerance",        "PrimalTol",    GRP_SIMPLEX,     1e-7,     1e-7,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_PRIMALOBJTOL, 
1050     "DualTolerance",          "DualTol",      GRP_SIMPLEX,     1e-7,     1e-7,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_DUALOBJTOL, 
1051
1052     "MipMaxNodes",            "MipMaxNodes",  GRP_LIMITS,   9999999,  9999999,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPMAXNODES, 
1053          "MipMaxSolutions",        "MipMaxSol",    GRP_LIMITS,   9999999,  9999999,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPMAXSOL, 
1054          "MipMaxSeconds",          "MipMaxSec",    GRP_LIMITS,     1e100,    1e100,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_MIPMAXSEC, 
1055
1056          "MipFathomDiscipline",    "FathomDisc",   GRP_MIPSTRAT,       0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPFATHOMDISC, 
1057          "MipHotStart",            "HotStart",     GRP_MIPSTRAT,       0,        0,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPHOTSTART,
1058//        "MipForcePriority",       "ForcePrior",   GRP_MIPSTRAT,      -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPFORCEPRIOR,
1059          "MipMinimumDrop",         "MinimumDrop",  GRP_MIPSTRAT,    1e-4,     1e-4,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPMINIMUMDROP,
1060          "MipMaxCutPasses",        "MaxCutPass",   GRP_MIPSTRAT,       2,        2,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPMAXCUTPASS,
1061          "MipMaxCutPassAtRoot",    "MaxPassRoot",  GRP_MIPSTRAT,      50,       50,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPMAXPASSROOT,
1062          "MipStrongBranching",     "StrongBranch", GRP_MIPSTRAT,       5,        5,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPSTRONGBRANCH,
1063          "MipScanGlobalCuts",      "ScanGlobCuts", GRP_MIPSTRAT,       1,        1,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPSCANGLOBCUTS,
1064
1065          "MipIntegerTolerance",    "MipIntTol",    GRP_MIPTOL,      1e-6,     1e-6,    0.0,     1.0,  OPT_REAL,   0,   COIN_REAL_MIPINTTOL, 
1066          "MipInfeasWeight",        "MipInfWeight", GRP_MIPTOL,       0.0,      0.0,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_MIPINFWEIGHT, 
1067          "MipCutoffIncrement",     "MipCutIncr",   GRP_MIPTOL,      1e-5,     1e-5,    0.0,     1.0,  OPT_REAL,   0,   COIN_REAL_MIPCUTOFF, 
1068          "MipAllowableGap",        "MipAbsGap",    GRP_MIPTOL,     1e-10,    1e-10,    0.0, MAXREAL,  OPT_REAL,   0,   COIN_REAL_MIPABSGAP, 
1069
1070          /* Probing */
1071          "MipCutProbing",          "CutProbing",   GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_PROBING,
1072          "MipProbeFrequency",      "ProbeFreq",    GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPPROBE_FREQ,
1073          "MipProbeMode",           "ProbeMode",    GRP_MIPCUTS,        1,        1,      0,       2,  OPT_LIST,   0,   COIN_INT_MIPPROBE_MODE,
1074          "MipProbeUseObjective",   "UseObject",    GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPPROBE_USEOBJ,
1075          "MipProbeMaxPass",        "MaxPass",      GRP_MIPCUTS,        3,        3,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPPROBE_MAXPASS,
1076          "MipProbeMaxProbe",       "MaxProbe",     GRP_MIPCUTS,      100,      100,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPPROBE_MAXPROBE,
1077          "MipProbeMaxLook",        "MaxLook",      GRP_MIPCUTS,       50,       50,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPPROBE_MAXLOOK,
1078          "MipProbeRowCuts",        "RowCuts",      GRP_MIPCUTS,        3,        3,      0,       3,  OPT_LIST,   0,   COIN_INT_MIPPROBE_ROWCUTS,
1079
1080          /* Gomory cuts */
1081          "MipCutGomory",           "CutGomory",    GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_GOMORY,
1082          "MipGomoryFrequency",     "GomoryFreq",   GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPGOMORY_FREQ,
1083          "MipGomoryLimit",         "GomoryLimit",  GRP_MIPCUTS,       50,       50,      1,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPGOMORY_LIMIT,
1084          "MipGomoryAway",          "GomoryAway",   GRP_MIPCUTS,     0.05,     0.05, 0.0001,     0.5,  OPT_REAL,   0,   COIN_REAL_MIPGOMORY_AWAY,
1085
1086          /* Knapsack cuts */
1087          "MipCutKnapsack",         "CutKnapsack",  GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_KNAPSACK,
1088          "MipKnapsackFrequency",   "KrapsackFreq", GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPKNAPSACK_FREQ,
1089          "MipKnapsackMaxIn",       "KnapsackMaxIn",GRP_MIPCUTS,       50,       50,      1,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPKNAPSACK_MAXIN,
1090
1091          /* Oddhole cuts */
1092          "MipCutOddHole",          "CutOddHole",   GRP_MIPCUTS,        0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_ODDHOLE,
1093          "MipOddHoleFrequency",    "OddHoleFreq",  GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPODDHOLE_FREQ,
1094          "MipOddHoleMinViolation", "MinViolation", GRP_MIPCUTS,    0.001,    0.001,1.01e-8,     0.5,  OPT_REAL,   0,   COIN_REAL_MIPODDHOLE_MINVIOL,
1095          "MipOddHoleMinViolPer",   "MinViolPer",   GRP_MIPCUTS,   0.0003,   0.0003,1.01e-8,    0.25,  OPT_REAL,   0,   COIN_REAL_MIPODDHOLE_MINVIOLPER,
1096          "MipOddHoleMaxEntries",   "MaxEntries",   GRP_MIPCUTS,      100,      100,      3,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPODDHOLE_MAXENTRIES,
1097
1098          /* Clique cuts */
1099          "MipCutClique",           "CutClique",    GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_CLIQUE,
1100          "MipCliqueFrequency",     "CliqueFreq",   GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPCLIQUE_FREQ,
1101          "MipCliquePacking",       "CliquePacking",GRP_MIPCUTS,        0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCLIQUE_PACKING,
1102          "MipCliqueStar",          "CliqueStar",   GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCLIQUE_STAR,
1103          "MipCliqueStarMethod",    "StarMethod",   GRP_MIPCUTS,        2,        2,      0,       2,  OPT_LIST,   0,   COIN_INT_MIPCLIQUE_STARMETHOD,
1104          "MipCliqueStarMaxLen",    "StarMaxLen",   GRP_MIPCUTS,       12,       12,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPCLIQUE_STARMAXLEN,
1105          "MipCliqueStarReport",    "StarReport",   GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCLIQUE_STARREPORT,
1106          "MipCliqueRow",           "CliqueRow",    GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCLIQUE_ROW,
1107          "MipCliqueRowMaxLen",     "ClqRowMaxLen", GRP_MIPCUTS,       12,       12,      0,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPCLIQUE_ROWMAXLEN,
1108          "MipCliqueRowReport",     "ClqRowReport", GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCLIQUE_ROWREPORT,
1109          "MipCliqueMinViolation",  "ClqMinViol",   GRP_MIPCUTS,     -1.0,     -1.0,-MAXREAL,MAXREAL,  OPT_REAL,   0,   COIN_REAL_MIPCLIQUE_MINVIOL,
1110
1111          /* Lift and Project */
1112          "MipCutLiftAndProject",   "CutLiftPro",   GRP_MIPCUTS,        0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_LIFTPROJECT,
1113          "MipLiftCoverFrequency",  "LiftProFreq",  GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPLIFTPRO_FREQ,
1114          "MipLiftCoverBetaOne",    "LiftProBeta",  GRP_MIPCUTS,        1,        1,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPLIFTPRO_BETAONE,
1115
1116          /* Simple Rounding */
1117          "MipCutSimpleRounding",   "CutSimpRound", GRP_MIPCUTS,        0,        0,      0,       1,  OPT_ONOFF,  0,   COIN_INT_MIPCUT_SIMPROUND,
1118          "MipSimpleRoundFrequency","SimpRoundFreq",GRP_MIPCUTS,       -1,       -1,-MAXINT,  MAXINT,  OPT_INT,    0,   COIN_INT_MIPSIMPROUND_FREQ,
1119
1120        };
1121
1122
1123
1124
1125SOLVAPI int CoinGetOptionCount(HPROB hProb)
1126{
1127        return OPTIONCOUNT;
1128}
1129
1130
1131SOLVAPI int CoinGetOptionInfo(HPROB hProb, int OptionNr, int *OptionID, int *GroupType,
1132                                                                                int *OptionType, char *OptionName, char *ShortName)
1133{
1134        if ((OptionNr < 0) && (OptionNr >= OPTIONCOUNT)) {
1135                return SOLV_FAILED;
1136        }
1137        if (OptionID)   *OptionID = OptionTable[OptionNr].OptionID;
1138        if (OptionType) *OptionType = OptionTable[OptionNr].OptionType;
1139        if (OptionName) strcpy(OptionName, OptionTable[OptionNr].OptionName);
1140        if (ShortName)  strcpy(ShortName, OptionTable[OptionNr].ShortName);
1141        return SOLV_SUCCESS;
1142}
1143
1144
1145SOLVAPI int CoinGetIntOptionMinMax(HPROB hProb, int OptionNr, int *MinValue, int *MaxValue)
1146{
1147        if ((OptionNr < 0) && (OptionNr >= OPTIONCOUNT)) {
1148                return SOLV_FAILED;
1149        }
1150        if (MinValue)   *MinValue = ROUND(OptionTable[OptionNr].MinValue);
1151        if (MaxValue)   *MaxValue = ROUND(OptionTable[OptionNr].MaxValue);
1152        return SOLV_SUCCESS;
1153}
1154
1155
1156SOLVAPI int CoinGetRealOptionMinMax(HPROB hProb, int OptionNr, double *MinValue, double *MaxValue)
1157{
1158        if ((OptionNr < 0) && (OptionNr >= OPTIONCOUNT)) {
1159                return SOLV_FAILED;
1160        }
1161        if (MinValue)   *MinValue = OptionTable[OptionNr].MinValue;
1162        if (MaxValue)   *MaxValue = OptionTable[OptionNr].MaxValue;
1163        return SOLV_SUCCESS;
1164}
1165
1166
1167
1168
1169/****************************************************************/
1170
1171
1172
1173int LocateOptionID(int OptionID)
1174{
1175        int i;
1176
1177        for (i = 0; i < OPTIONCOUNT; i++) {
1178                if (OptionID == OptionTable[i].OptionID) {
1179                        return i;
1180                }
1181        }
1182        return -1;
1183}
1184
1185
1186
1187SOLVAPI int CoinGetIntOption(HPROB hProb,int OptionID)
1188{   
1189        PCOIN pCoin = (PCOIN)hProb;
1190        int OptionNr;
1191
1192        OptionNr = LocateOptionID(OptionID);
1193        if (OptionNr < 0) {
1194                return 0;
1195        }
1196        if (OptionTable[OptionNr].OptionType != OPT_REAL)
1197                return OptionTable[OptionNr].CurrentValue;
1198        else {
1199                return 0;
1200        }
1201}
1202       
1203
1204
1205SOLVAPI int CoinSetIntOption(HPROB hProb,int OptionID, int IntValue)
1206{
1207   PCOIN pCoin = (PCOIN)hProb;
1208        int OptionNr;
1209
1210        OptionNr = LocateOptionID(OptionID);
1211        if (OptionNr < 0) {
1212                return SOLV_FAILED;
1213        }
1214        if (OptionTable[OptionNr].OptionType != OPT_REAL) {
1215                OptionTable[OptionNr].CurrentValue = IntValue;
1216           return SOLV_SUCCESS;
1217        }
1218        return SOLV_FAILED;
1219}
1220
1221
1222
1223SOLVAPI double CoinGetRealOption(HPROB hProb,int OptionID)
1224{
1225   PCOIN pCoin = (PCOIN)hProb;
1226        int OptionNr;
1227
1228        OptionNr = LocateOptionID(OptionID);
1229        if (OptionNr < 0) {
1230                return 0.0;
1231        }
1232        if (OptionTable[OptionNr].OptionType == OPT_REAL) {
1233                return OptionTable[OptionNr].CurrentValue;
1234        }
1235        return 0.0;
1236}
1237
1238
1239
1240SOLVAPI int CoinSetRealOption(HPROB hProb,int OptionID, double RealValue)
1241{
1242   PCOIN pCoin = (PCOIN)hProb;
1243        int OptionNr;
1244
1245        OptionNr = LocateOptionID(OptionID);
1246        if (OptionNr < 0) {
1247                return SOLV_FAILED;
1248        }
1249        if (OptionTable[OptionNr].OptionType == OPT_REAL) {
1250                OptionTable[OptionNr].CurrentValue = RealValue;
1251           return SOLV_SUCCESS;
1252        }
1253        return SOLV_FAILED;
1254}
1255
1256
1257SOLVAPI char*  CoinGetStringOption(HPROB hProb, int OptionID)
1258{
1259   PCOIN pCoin = (PCOIN)hProb;
1260
1261   return NULL;
1262}
1263
1264
1265SOLVAPI int    CoinSetStringOption(HPROB hProb, int OptionID, char *StringValue)
1266{
1267   PCOIN pCoin = (PCOIN)hProb;
1268
1269   return SOLV_FAILED;
1270}
1271
1272
1273/****************************************************************/
1274
1275
1276#if defined(_MSC_VER)
1277#define WIN32_LEAN_AND_MEAN
1278#include <windows.h>
1279
1280
1281static HINSTANCE g_hInstance;
1282
1283
1284BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
1285{
1286   switch (dwReason) {
1287
1288      case DLL_PROCESS_ATTACH:
1289         g_hInstance = hInstance;
1290                   break;
1291
1292      case DLL_PROCESS_DETACH:
1293              break;
1294   }
1295   return 1;
1296}
1297#endif
1298
1299
1300
1301//double
1302// DualTolerance
1303// PrimalTolerance
1304// DualBound
1305// PrimalWeight (setInfeasibilityCost)
1306// MaxTime      (setMaximumSeconds)
1307// ObjScale     (setObjectiveScale)
1308// RhsScale     (setRhsScale)
1309
1310//int
1311//LogLevel      (setLogLovel/model->factorization()->messageLevel(8);)
1312//MaxFactor     (model->factorization()->maximumPivots(value);
1313//PertValue     (setPerturbation)
1314//MaxIteration  (setMaximumIterations)
1315
1316//AutoScale     off
1317//Barrier
1318//BiasLU        UU  (UX, LX, LL)
1319//Crash         off
1320//Direction     min
1321//Directory
1322//dualBound     1e-20, 1e12
1323//dualPivot     Automatic, (Dantzig, partial, Steepest)
1324//DualSimplex
1325//dualTolerance 1e-20,1e12
1326//Exit
1327//ErrorsAllowed
1328//FakeBound
1329//Help
1330//Idiot
1331//Import
1332//KeepNames
1333//LogLevel
1334//Maximize
1335//MaxFactor     1, 999999
1336//MaxIteration  0, 99999999
1337//Messages
1338//ObjScale      -1e20, 1e20
1339//PresolvePass  0, 100
1340//PertValue     -5000, 102, false
1341//Perturbation  On, off
1342//PlusMinus     -1, false
1343//Presolve      On
1344//PrimalPivot     Automatic, (Dantzig, partial, Steepest, change, sprint)
1345//PrimalSimplex
1346//PrimalTolerance 1e-20,1e12
1347//PrimalWeight    1e20, 1e20
1348//RhsScale        -1e20, 1.20
1349//Scaling         Off, Equilibrium, geometric, automatic
1350//MaxTime         0.0, 1e12
1351//SparseFactor    On, Off
1352//SprintCrash     -1, 500
1353
Note: See TracBrowser for help on using the repository browser.