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

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

Supports now CbcMain0/1 calls, CBNodeHandler, and CoinGetOptionChanged?

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