source: trunk/Cbc/src/Cbc_C_Interface.cpp

Last change on this file was 2574, checked in by unxusr, 11 days ago

Cbc_clone init

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 57.2 KB
Line 
1// $Id: Cbc_C_Interface.cpp 2574 2019-05-15 11:47:18Z forrest $
2// Copyright (C) 2004, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#include <cmath>
7#include <cfloat>
8#include <cctype>
9#include <map>
10#include <string>
11
12#include "CoinPragma.hpp"
13//#include "CoinHelperFunctions.hpp"
14//#include "CoinPackedMatrix.hpp"
15#include "CoinTime.hpp"
16
17#include "CbcModel.hpp"
18#include "CbcSolver.hpp"
19#include "CbcBranchActual.hpp"
20
21#include "CoinMessageHandler.hpp"
22#include "OsiClpSolverInterface.hpp"
23#include "CglCutGenerator.hpp"
24
25//  bobe including extras.h to get strdup()
26#if defined(__MWERKS__)
27// #include <extras.h>  // bobe 06-02-14
28#endif
29
30// Get C stuff but with extern C
31#define CBC_EXTERN_C
32#include "Coin_C_defines.h"
33
34#define CbcGetProperty(T, prop) \
35  COINLIBAPI T COINLINKAGE      \
36    Cbc_##prop(Cbc_Model *m)    \
37  {                             \
38    return m->model_->prop();   \
39  }
40
41#define CbcSetSolverProperty(T, prop)          \
42  COINLIBAPI void COINLINKAGE                  \
43    Cbc_##prop(Cbc_Model *m, int index, T val) \
44  {                                            \
45    m->model_->solver()->prop(index, val);     \
46  }
47
48const int VERBOSE = 0;
49
50typedef std::map< std::string, int > NameIndex;
51
52// cut generator to accept callbacks in CBC
53//
54class CglCallback : public CglCutGenerator
55{
56    public:
57        CglCallback();
58       
59        cbc_cut_callback cut_callback_;
60        void *appdata;
61        //CbcModel *model;
62
63        /// Copy constructor
64        CglCallback(const CglCallback& rhs);
65
66        /// Clone
67        virtual CglCutGenerator * clone() const;
68
69        virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
70                const CglTreeInfo info = CglTreeInfo() );
71
72        virtual ~CglCallback();
73    private:
74};
75
76CglCallback::CglCallback()
77    : cut_callback_(NULL),
78    appdata(NULL)
79{
80}
81
82CglCallback::CglCallback(const CglCallback& rhs)
83{
84    this->cut_callback_ = rhs.cut_callback_;
85    this->appdata = rhs.appdata;
86}
87
88CglCutGenerator* CglCallback::clone() const
89{
90    CglCallback *cglcb = new CglCallback();
91    cglcb->cut_callback_ = this->cut_callback_;
92    cglcb->appdata = this->appdata;
93
94    return static_cast<CglCutGenerator*>(cglcb);
95}
96
97void CglCallback::generateCuts( const OsiSolverInterface &si, OsiCuts &cs, const CglTreeInfo info )
98{
99  this->cut_callback_( (OsiSolverInterface *) &si, &cs, this->appdata );
100}
101
102CglCallback::~CglCallback()
103{
104
105}
106
107class SolHandler : public CbcEventHandler {
108public:
109  virtual CbcAction event(CbcEvent whichEvent);
110  SolHandler();
111  SolHandler(CbcModel *model);
112  virtual ~SolHandler();
113  SolHandler(const SolHandler &rhs);
114  SolHandler &operator=(const SolHandler &rhs);
115  virtual CbcEventHandler *clone() const;
116
117  double bestCost;
118  cbc_incumbent_callback inc_callback;
119  void *appData;
120};
121
122SolHandler::SolHandler()
123  : CbcEventHandler()
124  , bestCost(COIN_DBL_MAX),
125  inc_callback(NULL),
126  appData(NULL)
127{
128}
129
130SolHandler::SolHandler(const SolHandler &rhs)
131  : CbcEventHandler(rhs)
132  , bestCost(rhs.bestCost)
133  , inc_callback(rhs.inc_callback)
134  , appData(rhs.appData)
135{
136}
137
138SolHandler::SolHandler(CbcModel *model)
139  : CbcEventHandler(model)
140  , bestCost(COIN_DBL_MAX)
141  , inc_callback(NULL)
142  , appData(NULL)
143{
144}
145
146SolHandler::~SolHandler()
147{
148}
149
150SolHandler &SolHandler::operator=(const SolHandler &rhs)
151{
152  if (this != &rhs) {
153    CbcEventHandler::operator=(rhs);
154    this->bestCost = rhs.bestCost;
155    this->inc_callback = rhs.inc_callback;
156    this->appData = rhs.appData;
157  }
158  return *this;
159}
160
161CbcEventHandler *SolHandler::clone() const
162{
163  return new SolHandler(*this);
164}
165
166CbcEventHandler::CbcAction SolHandler::event(CbcEvent whichEvent)
167{
168  if (this->inc_callback == NULL)
169    return noAction;
170  // If in sub tree carry on
171  if ((model_->specialOptions() & 2048) == 0) {
172    if ((whichEvent == solution || whichEvent == heuristicSolution)) {
173      OsiSolverInterface *origSolver = model_->solver();
174      const OsiSolverInterface *pps = model_->postProcessedSolver(1);
175
176      const OsiSolverInterface *solver = pps ? pps : origSolver;
177
178      if (bestCost >= solver->getObjValue() + 1e-10) {
179        bestCost = solver->getObjValue();
180       
181        int charSize = 0, nNZ = 0;
182        const double *x = solver->getColSolution();
183        for (int i = 0; (i < solver->getNumCols()); ++i) 
184        {
185          if (fabs(x[i]) <= 1e-7)
186            continue;
187          charSize += solver->getColName(i).size()+1;
188          ++nNZ;
189        } // checking non zero cols
190        char **cnames = new char*[nNZ];
191        double *xv = new double[nNZ];
192        cnames[0] = new char[charSize];
193
194        int cnz = 0;
195        for (int i = 0; (i < solver->getNumCols()); ++i) 
196        {
197          if (fabs(x[i]) <= 1e-7)
198            continue;
199          if (cnz>=1)
200            cnames[cnz] = cnames[cnz-1] + solver->getColName(i).size()+1;
201          cnz++;
202        }
203 
204        cnz = 0;
205        for (int i = 0; (i < solver->getNumCols()); ++i) 
206        {
207          if (fabs(x[i]) <= 1e-7)
208            continue;
209           strcpy(cnames[cnz], solver->getColName(i).c_str());
210           xv[cnz] = x[i];
211
212           cnz++;
213        }
214
215        this->inc_callback(model_, bestCost, nNZ, cnames, xv, this->appData);
216
217        delete[] xv;
218        delete[] cnames[0];
219        delete[] cnames;
220      } // improved cost
221    } // solution found
222  } // not in subtree
223
224  return noAction;
225}
226
227// To allow call backs
228class Cbc_MessageHandler
229  : public CoinMessageHandler {
230
231public:
232  /**@name Overrides */
233  //@{
234  virtual int print();
235  //@}
236  /**@name set and get */
237  //@{
238  /// Model
239  const Cbc_Model *model() const;
240  void setModel(Cbc_Model *model);
241  /// Call back
242  void setCallBack(cbc_callback callback);
243  //@}
244
245  /**@name Constructors, destructor */
246  //@{
247  /** Default constructor. */
248  Cbc_MessageHandler();
249  /// Constructor with pointer to model
250  Cbc_MessageHandler(Cbc_Model *model,
251    FILE *userPointer = NULL);
252  /** Destructor */
253  virtual ~Cbc_MessageHandler();
254  //@}
255
256  /**@name Copy method */
257  //@{
258  /** The copy constructor. */
259  Cbc_MessageHandler(const Cbc_MessageHandler &);
260  /** The copy constructor from an CoinSimplexMessageHandler. */
261  Cbc_MessageHandler(const CoinMessageHandler &);
262
263  Cbc_MessageHandler &operator=(const Cbc_MessageHandler &);
264  /// Clone
265  virtual CoinMessageHandler *clone() const;
266  //@}
267
268protected:
269  /**@name Data members
270       The data members are protected to allow access for derived classes. */
271  //@{
272  /// Pointer back to model
273  Cbc_Model *model_;
274  /// call back
275  cbc_callback callback_;
276  //@}
277};
278
279//-------------------------------------------------------------------
280// Default Constructor
281//-------------------------------------------------------------------
282Cbc_MessageHandler::Cbc_MessageHandler()
283  : CoinMessageHandler()
284  , model_(NULL)
285  , callback_(NULL)
286{
287}
288
289//-------------------------------------------------------------------
290// Copy constructor
291//-------------------------------------------------------------------
292Cbc_MessageHandler::Cbc_MessageHandler(const Cbc_MessageHandler &rhs)
293  : CoinMessageHandler(rhs)
294  , model_(rhs.model_)
295  , callback_(rhs.callback_)
296{
297}
298
299Cbc_MessageHandler::Cbc_MessageHandler(const CoinMessageHandler &rhs)
300  : CoinMessageHandler(rhs)
301  , model_(NULL)
302  , callback_(NULL)
303{
304}
305
306// Constructor with pointer to model
307Cbc_MessageHandler::Cbc_MessageHandler(Cbc_Model *model,
308  FILE * /*userPointer*/)
309  : CoinMessageHandler()
310  , model_(model)
311  , callback_(NULL)
312{
313}
314
315//-------------------------------------------------------------------
316// Destructor
317//-------------------------------------------------------------------
318Cbc_MessageHandler::~Cbc_MessageHandler()
319{
320}
321
322//----------------------------------------------------------------
323// Assignment operator
324//-------------------------------------------------------------------
325Cbc_MessageHandler &
326Cbc_MessageHandler::operator=(const Cbc_MessageHandler &rhs)
327{
328  if (this != &rhs) {
329    CoinMessageHandler::operator=(rhs);
330    model_ = rhs.model_;
331    callback_ = rhs.callback_;
332  }
333  return *this;
334}
335//-------------------------------------------------------------------
336// Clone
337//-------------------------------------------------------------------
338CoinMessageHandler *Cbc_MessageHandler::clone() const
339{
340  return new Cbc_MessageHandler(*this);
341}
342int Cbc_MessageHandler::print()
343{
344  if (callback_) {
345    int messageNumber = currentMessage().externalNumber();
346    if (currentSource() != "Cbc")
347      messageNumber += 1000000;
348    int i;
349    int nDouble = numberDoubleFields();
350    assert(nDouble <= 200);
351    double vDouble[200];
352    for (i = 0; i < nDouble; i++)
353      vDouble[i] = doubleValue(i);
354    int nInt = numberIntFields();
355    assert(nInt <= 200);
356    int vInt[200];
357    for (i = 0; i < nInt; i++)
358      vInt[i] = intValue(i);
359    int nString = numberStringFields();
360    assert(nString <= 200);
361    char *vString[200];
362    for (i = 0; i < nString; i++) {
363      std::string value = stringValue(i);
364      vString[i] = CoinStrdup(value.c_str());
365    }
366    callback_(model_, messageNumber,
367      nDouble, vDouble,
368      nInt, vInt,
369      nString, vString);
370    for (i = 0; i < nString; i++)
371      free(vString[i]);
372  }
373  return CoinMessageHandler::print();
374  return 0;
375}
376const Cbc_Model *
377Cbc_MessageHandler::model() const
378{
379  return model_;
380}
381void Cbc_MessageHandler::setModel(Cbc_Model *model)
382{
383  model_ = model;
384}
385// Call back
386void Cbc_MessageHandler::setCallBack(cbc_callback callback)
387{
388  callback_ = callback;
389}
390/**
391  *
392  *  C Interface Routines
393  *
394  */
395#include "Cbc_C_Interface.h"
396#include <string>
397#include <stdio.h>
398#include <iostream>
399
400#if defined(__MWERKS__)
401#pragma export on
402#endif
403
404/* Version */
405COINLIBAPI const char *COINLINKAGE Cbc_getVersion()
406{
407  return CBC_VERSION;
408}
409
410// flushes buffers of new variables
411static void Cbc_flush( Cbc_Model *model )
412{
413  if (model->nCols)
414  {
415    OsiSolverInterface *solver = model->model_->solver();
416
417    int *starts = new int[model->nCols+1];
418    for ( int i=0 ; (i<model->nCols+1) ; ++i )
419      starts[i] = 0;
420
421    int idx = 0; double coef = 0.0;
422
423    int colsBefore = solver->getNumCols();
424   
425    solver->addCols( model->nCols, starts, &idx, &coef, model->cLB, model->cUB, model->cObj );
426
427    for ( int i=0 ; i<model->nCols; ++i )
428      if (model->cInt[i])
429        solver->setInteger( colsBefore+i );
430
431    for ( int i=0 ; i<model->nCols; ++i )
432      solver->setColName( colsBefore+i, std::string(model->cNames+model->cNameStart[i]) );
433
434    model->nCols = 0;
435
436    delete[] starts;
437  }
438}
439
440static void Cbc_checkSpaceColBuffer( Cbc_Model *model, int additionlNameSpace )
441{
442  // initialize buffer
443  if ( model->colSpace == 0 )
444  {
445    // initial buffer allocation
446    model->colSpace = 8192;
447    int c = model->colSpace;
448    model->nCols = 0;
449    model->cNameSpace = 16384;
450
451    model->cNameStart = (int *) malloc( sizeof(int)*c );
452    assert( model->cNameStart );
453    model->cNameStart[0] = 0;
454
455    model->cInt = (char *) malloc( sizeof(char)*c );
456    assert( model->cInt );
457
458    model->cNames = (char *) malloc( sizeof(char)*model->cNameSpace );
459    assert( model->cNames );
460
461    model->cLB = (double *) malloc( sizeof(double)*c );
462    assert( model->cLB );
463
464    model->cUB = (double *)malloc( sizeof(double)*c );
465    assert( model->cUB );
466
467    model->cObj = (double *)malloc( sizeof(double)*c );
468    assert( model->cObj );
469  }
470  else
471  {
472    // check buffer space
473    if (model->nCols+2 >= model->colSpace)
474    {
475      model->colSpace *= 2;
476      int c = model->colSpace;
477
478      model->cNameStart = (int *) realloc( model->cNameStart, sizeof(int)*c );
479      assert( model->cNameStart );
480
481      model->cInt = (char *) realloc( model->cInt, sizeof(char)*c );
482      assert( model->cInt );
483
484      model->cLB = (double *) realloc( model->cLB, sizeof(double)*c );
485      assert( model->cLB );
486
487      model->cUB = (double *) realloc( model->cUB, sizeof(double)*c );
488      assert( model->cUB );
489
490      model->cObj = (double *) realloc( model->cObj, sizeof(double)*c );
491      assert( model->cObj );
492    }
493    // check string buffer space
494    int slen = additionlNameSpace + 1;
495    int reqsize = slen + model->cNameStart[model->nCols]+1;
496    if (reqsize>model->cNameSpace)
497    {
498      model->cNameSpace *= 2;
499      model->cNames = (char *) realloc( model->cNames, sizeof(char)*model->cNameSpace );
500    }
501  }
502}
503
504static void Cbc_addColBuffer( Cbc_Model *model, 
505    const char *name, double lb, double ub, double obj, 
506    char isInteger )
507{
508  Cbc_checkSpaceColBuffer( model, 512 );
509  int p = model->nCols;
510  model->cInt[p] = isInteger;
511  model->cLB[p] = lb;
512  model->cUB[p] = ub;
513  model->cObj[p] = obj;
514 
515  int ps = model->cNameStart[p];
516  strcpy( model->cNames+ps, name );
517  int len = strlen(name);
518
519  model->nCols++;
520  model->cNameStart[model->nCols] = ps + len + 1;
521}
522
523static void Cbc_deleteColBuffer( Cbc_Model *model )
524{
525  if ( model->colSpace > 0 )
526  {
527    free(model->cNameStart);
528    free(model->cInt);
529    free(model->cNames);
530    free(model->cLB);
531    free(model->cUB);
532    free(model->cObj);
533  }
534}
535
536
537/* Default Cbc_Model constructor */
538COINLIBAPI Cbc_Model *COINLINKAGE
539Cbc_newModel()
540{
541  const char prefix[] = "Cbc_C_Interface::Cbc_newModel(): ";
542  //  const int  VERBOSE = 1;
543  if (VERBOSE > 0)
544    printf("%s begin\n", prefix);
545
546  Cbc_Model *model = new Cbc_Model();
547  OsiClpSolverInterface solver1; // will be release at the end of the scope, CbcModel clones it
548  model->model_ = new CbcModel(solver1);
549  model->solver_ = dynamic_cast< OsiClpSolverInterface * >(model->model_->solver());
550  model->cbcData = new CbcSolverUsefulData();
551  CbcMain0(*model->model_, *model->cbcData);
552  model->handler_ = NULL;
553  model->cbcData->noPrinting_ = false;
554  model->relax_ = 0;
555  model->inc_callback = NULL;
556  model->colNameIndex = NULL;
557  model->rowNameIndex = NULL;
558
559  // initialize columns buffer
560  model->colSpace = 0;
561  model->nCols = 0;
562  model->cNameSpace = 0;
563  model->cNameStart = NULL;
564  model->cInt = NULL;
565  model->cNames= NULL;
566  model->cLB = NULL;
567  model->cUB = NULL;
568  model->cObj = NULL;
569
570  if (VERBOSE > 0)
571    printf("%s return\n", prefix);
572  return model;
573}
574/* Cbc_Model Destructor */
575COINLIBAPI void COINLINKAGE
576Cbc_deleteModel(Cbc_Model *model)
577{
578  const char prefix[] = "Cbc_C_Interface::Cbc_deleteModel(): ";
579  //  const int  VERBOSE = 1;
580  if (VERBOSE > 0)
581    printf("%s begin\n", prefix);
582  fflush(stdout);
583
584  Cbc_deleteColBuffer(model);
585
586  if (model->colNameIndex)
587  {
588    NameIndex *m = (NameIndex *)model->colNameIndex;
589    delete m;
590    m = (NameIndex *)model->rowNameIndex;
591    assert( m != NULL );
592    delete m;
593  }
594
595  if (VERBOSE > 1)
596    printf("%s delete model->model_\n", prefix);
597  fflush(stdout);
598  delete model->model_;
599
600  if (VERBOSE > 1)
601    printf("%s delete model->handler_\n", prefix);
602  fflush(stdout);
603  delete model->handler_;
604
605  delete model->cbcData;
606
607  if (VERBOSE > 1)
608    printf("%s delete model\n", prefix);
609  fflush(stdout);
610  delete model;
611
612  if (VERBOSE > 0)
613    printf("%s return\n", prefix);
614  fflush(stdout);
615}
616
617/* Loads a problem (the constraints on the
618    rows are given by lower and upper bounds). If a pointer is NULL then the
619    following values are the default:
620    <ul>
621    <li> <code>colub</code>: all columns have upper bound infinity
622    <li> <code>collb</code>: all columns have lower bound 0
623    <li> <code>rowub</code>: all rows have upper bound infinity
624    <li> <code>rowlb</code>: all rows have lower bound -infinity
625    <li> <code>obj</code>: all variables have 0 objective coefficient
626    </ul>
627
628   Just like the other loadProblem() method except that the matrix is
629   given in a standard column major ordered format (without gaps).
630*/
631COINLIBAPI void COINLINKAGE
632Cbc_loadProblem(Cbc_Model *model, const int numcols, const int numrows,
633  const CoinBigIndex *start, const int *index,
634  const double *value,
635  const double *collb, const double *colub,
636  const double *obj,
637  const double *rowlb, const double *rowub)
638{
639  const char prefix[] = "Cbc_C_Interface::Cbc_loadProblem(): ";
640  //  const int  VERBOSE = 2;
641  if (VERBOSE > 0)
642    printf("%s begin\n", prefix);
643
644  OsiSolverInterface *solver = model->model_->solver();
645
646  if (VERBOSE > 1) {
647    printf("%s numcols = %i, numrows = %i\n",
648      prefix, numcols, numrows);
649    printf("%s model = %p, start = %p, index = %p, value = %p\n",
650      prefix, static_cast< void * >(model), static_cast< const void * >(start),
651      static_cast< const void * >(index), static_cast< const void * >(value));
652    printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
653      prefix, static_cast< const void * >(collb),
654      static_cast< const void * >(colub), static_cast< const void * >(obj),
655      static_cast< const void * >(rowlb), static_cast< const void * >(rowub));
656  }
657
658  if (VERBOSE > 1)
659    printf("%s Calling solver->loadProblem()\n", prefix);
660  fflush(stdout);
661
662  solver->loadProblem(numcols, numrows, start, index, value,
663    collb, colub, obj, rowlb, rowub);
664  if (VERBOSE > 1)
665    printf("%s Finished solver->loadProblem()\n", prefix);
666  fflush(stdout);
667
668  if (VERBOSE > 0)
669    printf("%s return\n", prefix);
670} //  Cbc_loadProblem()
671
672/* should be called after reading a new problem */
673static void fillAllNameIndexes(Cbc_Model *model)
674{
675  if (!model->colNameIndex)
676    return;
677
678  OsiSolverInterface *solver = model->model_->solver();
679  NameIndex &colNameIndex = *((NameIndex  *)model->colNameIndex);
680  colNameIndex.clear();
681  NameIndex &rowNameIndex = *((NameIndex  *)model->rowNameIndex);
682  rowNameIndex.clear();
683
684  for ( int i=0 ; (i<solver->getNumCols()) ; ++i )
685    colNameIndex[solver->getColName(i)] = i;
686
687  for ( int i=0 ; (i<solver->getNumRows()) ; ++i )
688    rowNameIndex[solver->getRowName(i)] = i;
689}
690
691/* Read an mps file from the given filename */
692COINLIBAPI int COINLINKAGE
693Cbc_readMps(Cbc_Model *model, const char *filename)
694{
695  const char prefix[] = "Cbc_C_Interface::Cbc_readMps(): ";
696  //  const int  VERBOSE = 2;
697  if (VERBOSE > 0)
698    printf("%s begin\n", prefix);
699  if (VERBOSE > 1)
700    printf("%s filename = '%s'\n", prefix, filename);
701
702  int result = 1;
703  OsiSolverInterface *solver = model->model_->solver();
704  result = solver->readMps(filename);
705  assert(result == 0);
706
707  fillAllNameIndexes(model);
708
709  if (VERBOSE > 0)
710    printf("%s return %i\n", prefix, result);
711  return result;
712}
713/* Write an mps file from the given filename */
714COINLIBAPI void COINLINKAGE
715Cbc_writeMps(Cbc_Model *model, const char *filename)
716{
717  Cbc_flush(model);
718
719  const char prefix[] = "Cbc_C_Interface::Cbc_writeMps(): ";
720  //  const int  VERBOSE = 2;
721  if (VERBOSE > 0)
722    printf("%s begin\n", prefix);
723  if (VERBOSE > 1)
724    printf("%s filename = '%s'\n", prefix, filename);
725
726  model->model_->solver()->writeMps(filename, "mps", Cbc_getObjSense(model));
727
728  if (VERBOSE > 0)
729    printf("%s return\n", prefix);
730  return;
731}
732
733/* Write an mps file from the given filename */
734COINLIBAPI void COINLINKAGE
735Cbc_writeLp(Cbc_Model *model, const char *filename)
736{
737  Cbc_flush(model);
738
739  const char prefix[] = "Cbc_C_Interface::Cbc_writeLp(): ";
740  //  const int  VERBOSE = 2;
741  if (VERBOSE > 0)
742    printf("%s begin\n", prefix);
743  if (VERBOSE > 1)
744    printf("%s filename = '%s'\n", prefix, filename);
745
746  char outFile[512];
747  strncpy(outFile, filename, 511);
748
749  char *s = NULL;
750  if ((s = strstr(outFile, ".lp"))) {
751    if (s != outFile) // not at the start
752      *s = '\0';
753  }
754
755  model->model_->solver()->writeLp(outFile);
756
757  if (VERBOSE > 0)
758    printf("%s return\n", prefix);
759  return;
760}
761
762/* Read an lp file from the given filename */
763COINLIBAPI int COINLINKAGE
764Cbc_readLp(Cbc_Model *model, const char *filename)
765{
766  const char prefix[] = "Cbc_C_Interface::Cbc_readLp(): ";
767  //  const int  VERBOSE = 2;
768  if (VERBOSE > 0)
769    printf("%s begin\n", prefix);
770  if (VERBOSE > 1)
771    printf("%s filename = '%s'\n", prefix, filename);
772  int result = 1;
773  OsiSolverInterface *solver = model->model_->solver();
774  result = solver->readLp(filename);
775  assert(result == 0);
776
777  fillAllNameIndexes(model);
778
779  if (VERBOSE > 0)
780    printf("%s return %i\n", prefix, result);
781  return result;
782}
783
784COINLIBAPI void COINLINKAGE
785Cbc_setInitialSolution(Cbc_Model *model, const double *sol)
786{
787  Cbc_flush(model); 
788  int n = Cbc_getNumCols(model);
789  // We need to manually compute the objective here for some reason
790  const double *objvec = Cbc_getObjCoefficients(model);
791  double objval = 0;
792  for (int i = 0; i < n; i++) {
793    objval += objvec[i] * sol[i];
794  }
795  model->model_->setBestSolution(sol, n, objval, true);
796}
797
798COINLIBAPI void COINLINKAGE
799Cbc_setParameter(Cbc_Model *model, const char *name, const char *value)
800{
801  // checking if parameter is not included with another value
802  // if this is the case just replacing this value
803  std::string argname=std::string("-")+name;
804  for ( int i=0 ; (i<((int)model->cmdargs_.size())-1) ; ++i )
805  {
806    if (argname==model->cmdargs_[i])
807    {
808      model->cmdargs_[i+1] = std::string(value);
809      return;
810    }
811  }
812 
813  model->cmdargs_.push_back(argname);
814  model->cmdargs_.push_back(value);
815}
816
817/* Fills in array with problem name  */
818COINLIBAPI void COINLINKAGE
819Cbc_problemName(Cbc_Model *model, int maxNumberCharacters, char *array)
820{
821  std::string name;
822  model->model_->solver()->getStrParam(OsiProbName, name);
823  strncpy(array, name.c_str(), maxNumberCharacters);
824}
825/* Sets problem name.  Must have \0 at end.  */
826COINLIBAPI int COINLINKAGE
827Cbc_setProblemName(Cbc_Model *model, const char *array)
828{
829  bool result = false;
830  result = model->model_->solver()->setStrParam(OsiProbName, array);
831
832  return (result) ? 1 : 0;
833}
834
835CbcGetProperty(int, status)
836
837  CbcGetProperty(int, secondaryStatus)
838
839  /* Number of elements in matrix */
840  COINLIBAPI int COINLINKAGE
841  Cbc_getNumElements(Cbc_Model *model)
842{
843  const char prefix[] = "Cbc_C_Interface::Cbc_getNumElements(): ";
844  //  const int  VERBOSE = 1;
845  if (VERBOSE > 0)
846    printf("%s begin\n", prefix);
847
848  int result = 0;
849  result = model->model_->getNumElements();
850
851  if (VERBOSE > 0)
852    printf("%s return %i\n", prefix, result);
853  return result;
854}
855
856COINLIBAPI int COINLINKAGE
857Cbc_getNumIntegers(Cbc_Model *model)
858{
859  Cbc_flush(model); 
860  return model->model_->solver()->getNumIntegers();
861}
862
863// Column starts in matrix
864COINLIBAPI const CoinBigIndex *COINLINKAGE
865Cbc_getVectorStarts(Cbc_Model *model)
866{
867  const CoinPackedMatrix *matrix = NULL;
868  matrix = model->model_->solver()->getMatrixByCol();
869  return (matrix == NULL) ? NULL : matrix->getVectorStarts();
870}
871// Row indices in matrix
872COINLIBAPI const int *COINLINKAGE
873Cbc_getIndices(Cbc_Model *model)
874{
875  const char prefix[] = "Cbc_C_Interface::Cbc_getIndices(): ";
876  //  const int  VERBOSE = 1;
877  if (VERBOSE > 0)
878    printf("%s begin\n", prefix);
879
880  const int *result = NULL;
881  const CoinPackedMatrix *matrix = NULL;
882  matrix = model->model_->solver()->getMatrixByCol();
883  result = (matrix == NULL) ? NULL : matrix->getIndices();
884
885  if (VERBOSE > 0)
886    printf("%s return %p\n", prefix, static_cast< const void * >(result));
887  return result;
888}
889
890// Element values in matrix
891COINLIBAPI const double *COINLINKAGE
892Cbc_getElements(Cbc_Model *model)
893{
894  const char prefix[] = "Cbc_C_Interface::Cbc_getElements(): ";
895  //  const int  VERBOSE = 1;
896  if (VERBOSE > 0)
897    printf("%s begin\n", prefix);
898
899  const double *result = NULL;
900  const CoinPackedMatrix *matrix = NULL;
901  matrix = model->model_->solver()->getMatrixByCol();
902  result = (matrix == NULL) ? NULL : matrix->getElements();
903
904  if (VERBOSE > 0)
905    printf("%s return %p\n", prefix, static_cast< const void * >(result));
906  return result;
907}
908// ======================================================================
909
910/* Pass in Callback function */
911COINLIBAPI void COINLINKAGE
912Cbc_registerCallBack(Cbc_Model *model,
913  cbc_callback userCallBack)
914{
915  const char prefix[] = "Cbc_C_Interface::Cbc_registerCallBack(): ";
916  //  const int  VERBOSE = 1;
917  if (VERBOSE > 0)
918    printf("%s begin\n", prefix);
919
920  // Will be copy of users one
921  delete model->handler_;
922  model->handler_ = new Cbc_MessageHandler(*(model->model_->messageHandler()));
923  model->handler_->setCallBack(userCallBack);
924  model->handler_->setModel(model);
925  model->model_->passInMessageHandler(model->handler_);
926
927  if (VERBOSE > 0)
928    printf("%s return\n", prefix);
929}
930/* Unset Callback function */
931COINLIBAPI void COINLINKAGE
932Cbc_clearCallBack(Cbc_Model *model)
933{
934  const char prefix[] = "Cbc_C_Interface::Cbc_clearCallBack(): ";
935  //  const int  VERBOSE = 1;
936  if (VERBOSE > 0)
937    printf("%s begin\n", prefix);
938
939  delete model->handler_;
940  model->handler_ = NULL;
941
942  if (VERBOSE > 0)
943    printf("%s return\n", prefix);
944}
945/* length of names (0 means no names0 */
946COINLIBAPI size_t COINLINKAGE
947Cbc_maxNameLength(Cbc_Model *model)
948{
949  size_t result = 0;
950  OsiSolverInterface::OsiNameVec const &rownames = model->model_->solver()->getRowNames();
951  for (size_t i = 0; i < rownames.size(); i++) {
952    if (rownames[i].length() > result)
953      result = rownames[i].length();
954  }
955  OsiSolverInterface::OsiNameVec const &colnames = model->model_->solver()->getColNames();
956  for (size_t i = 0; i < colnames.size(); i++) {
957    if (colnames[i].length() > result)
958      result = colnames[i].length();
959  }
960  return result;
961}
962COINLIBAPI void COINLINKAGE
963Cbc_getRowName(Cbc_Model *model, int iRow, char *name, size_t maxLength)
964{
965  std::string rowname = model->model_->solver()->getRowName(iRow);
966  strncpy(name, rowname.c_str(), maxLength);
967  name[maxLength - 1] = '\0';
968}
969
970COINLIBAPI void COINLINKAGE
971Cbc_getColName(Cbc_Model *model, int iColumn, char *name, size_t maxLength)
972{
973  assert( iColumn >= 0 );
974  assert( iColumn < Cbc_getNumCols(model) );
975
976  Cbc_flush(model);
977
978  std::string colname = model->model_->solver()->getColName(iColumn);
979  strncpy(name, colname.c_str(), maxLength);
980  name[maxLength - 1] = '\0';
981}
982
983COINLIBAPI void COINLINKAGE
984Cbc_setColName(Cbc_Model *model, int iColumn, const char *name)
985{
986  Cbc_flush(model);
987  OsiSolverInterface *solver = model->model_->solver();
988  std::string previousName = solver->getColName(iColumn);
989  solver->setColName(iColumn, name);
990
991  if (!model->colNameIndex)
992    return;
993  NameIndex &colNameIndex = *((NameIndex  *)model->colNameIndex);
994  NameIndex::iterator it = colNameIndex.find(previousName);
995  if (it!=colNameIndex.end())
996    colNameIndex.erase(it);
997  colNameIndex[name] = iColumn;
998}
999
1000COINLIBAPI void COINLINKAGE
1001Cbc_setRowName(Cbc_Model *model, int iRow, const char *name)
1002{
1003  OsiSolverInterface *solver = model->model_->solver();
1004  std::string previousName = solver->getRowName(iRow);
1005  solver->setRowName(iRow, name);
1006
1007  if (!model->rowNameIndex)
1008    return;
1009  NameIndex &rowNameIndex = *((NameIndex  *)model->rowNameIndex);
1010  NameIndex::iterator it = rowNameIndex.find(std::string(previousName));
1011  if (it!=rowNameIndex.end())
1012    rowNameIndex.erase(it);
1013  rowNameIndex[name] = iRow;
1014}
1015
1016COINLIBAPI void COINLINKAGE
1017Cbc_setSolveRelax(Cbc_Model *model, char solveOnlyRelax)
1018{
1019  model->relax_ = solveOnlyRelax;
1020}
1021
1022COINLIBAPI int COINLINKAGE
1023Cbc_solve(Cbc_Model *model)
1024{
1025  Cbc_flush( model );
1026
1027  OsiSolverInterface *solver = model->solver_;
1028  if (solver->getNumIntegers() == 0 || model->relax_ == 1) {
1029    if (solver->basisIsAvailable()) {
1030      solver->resolve();
1031    } else {
1032      solver->initialSolve();
1033    }
1034
1035    if (solver->isProvenOptimal())
1036      return 0;
1037
1038    return 1;
1039  }
1040
1041  const char prefix[] = "Cbc_C_Interface::Cbc_solve(): ";
1042  int result = 0;
1043  std::vector< const char * > argv;
1044  argv.push_back("Cbc_C_Interface");
1045  for (size_t i = 0; i < model->cmdargs_.size(); i++) {
1046    argv.push_back(model->cmdargs_[i].c_str());
1047  }
1048  argv.push_back("-solve");
1049  argv.push_back("-quit");
1050  try {
1051
1052    SolHandler *sh = NULL;
1053    if (model->inc_callback!=NULL)
1054    {
1055      sh = new SolHandler(model->model_);
1056      sh->inc_callback = model->inc_callback;
1057      sh->appData = model->icAppData;
1058      model->model_->passInEventHandler(sh);
1059    }
1060
1061    CbcMain1((int)argv.size(), &argv[0], *model->model_, NULL, *model->cbcData);
1062
1063    if (sh)
1064      delete sh;
1065  } catch (CoinError e) {
1066    printf("%s ERROR: %s::%s, %s\n", prefix,
1067      e.className().c_str(), e.methodName().c_str(), e.message().c_str());
1068  }
1069  result = model->model_->status();
1070
1071
1072  return result;
1073}
1074
1075COINLIBAPI void COINLINKAGE Cbc_addIncCallback(
1076    Cbc_Model *model, cbc_incumbent_callback inccb, 
1077    void *appData )
1078{
1079  model->inc_callback = inccb;
1080  model->icAppData = appData;
1081}
1082
1083COINLIBAPI void COINLINKAGE Cbc_addCutCallback( 
1084    Cbc_Model *model, cbc_cut_callback cutcb, 
1085    const char *name, void *appData )
1086{
1087  assert( model != NULL );
1088  assert( model->model_ != NULL );
1089
1090  CbcModel *cbcModel = model->model_;
1091  cbcModel->setKeepNamesPreproc(true);
1092
1093  CglCallback cglCb;
1094  cglCb.appdata = appData;
1095  cglCb.cut_callback_ = cutcb;
1096
1097  cbcModel->addCutGenerator( &cglCb, 1, name );
1098}
1099
1100/* Sum of primal infeasibilities */
1101COINLIBAPI double COINLINKAGE
1102Cbc_sumPrimalInfeasibilities(Cbc_Model * /*model*/)
1103{
1104  const char prefix[] = "Cbc_C_Interface::Cbc_sumPrimalInfeasibilities(): ";
1105  //  const int  VERBOSE = 1;
1106  if (VERBOSE > 0)
1107    printf("%s begin\n", prefix);
1108
1109  double result = 0;
1110  // cannot find names in Cbc, Osi, or OsiClp
1111  //tbd result = model->model_->sumPrimalInfeasibilities();
1112  if (VERBOSE > 0)
1113    printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
1114
1115  if (VERBOSE > 0)
1116    printf("%s return %g\n", prefix, result);
1117  return result;
1118}
1119/* Number of primal infeasibilities */
1120COINLIBAPI int COINLINKAGE
1121Cbc_numberPrimalInfeasibilities(Cbc_Model * /*model*/)
1122{
1123  const char prefix[] = "Cbc_C_Interface::Cbc_numberPrimalInfeasibilities(): ";
1124  //  const int  VERBOSE = 1;
1125  if (VERBOSE > 0)
1126    printf("%s begin\n", prefix);
1127
1128  int result = 0;
1129  //tbd  result = model->model_->getContinuousInfeasibilities();
1130  if (VERBOSE > 0)
1131    printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
1132
1133  if (VERBOSE > 0)
1134    printf("%s return %i\n", prefix, result);
1135  return result;
1136}
1137
1138/** Call this to really test if a valid solution can be feasible
1139    Solution is number columns in size.
1140    If fixVariables true then bounds of continuous solver updated.
1141    Returns objective value (worse than cutoff if not feasible)
1142*/
1143COINLIBAPI void COINLINKAGE
1144Cbc_checkSolution(Cbc_Model * /*model*/)
1145{
1146  const char prefix[] = "Cbc_C_Interface::Cbc_checkSolution(): ";
1147  //  const int  VERBOSE = 1;
1148  if (VERBOSE > 0)
1149    printf("%s begin\n", prefix);
1150
1151  // see CbcModel::checkSolution(double cutoff, const double * solution,
1152  //           bool fixVariables);
1153  //  model->model_->checkSolution();
1154
1155  if (VERBOSE > 0)
1156    printf("%s return\n", prefix);
1157  return;
1158}
1159
1160COINLIBAPI int COINLINKAGE
1161Cbc_getNumCols(Cbc_Model *model)
1162{
1163  return model->model_->solver()->getNumCols() + model->nCols;
1164}
1165
1166CbcGetProperty(int, getNumRows)
1167CbcGetProperty(int, getIterationCount)
1168
1169  /** Number of non-zero entries in a row */
1170  COINLIBAPI int COINLINKAGE
1171  Cbc_getRowNz(Cbc_Model *model, int row)
1172{
1173  const CoinPackedMatrix *cpmRow = model->model_->solver()->getMatrixByRow();
1174  return cpmRow->getVectorLengths()[row];
1175}
1176
1177/** Indices of variables that appear on this row */
1178COINLIBAPI const int *COINLINKAGE
1179Cbc_getRowIndices(Cbc_Model *model, int row)
1180{
1181  const CoinPackedMatrix *cpmRow = model->model_->solver()->getMatrixByRow();
1182  const CoinBigIndex *starts = cpmRow->getVectorStarts();
1183  const int *ridx = cpmRow->getIndices() + starts[row];
1184  return ridx;
1185}
1186
1187/** Coefficients of variables that appear on this row */
1188COINLIBAPI const double *COINLINKAGE
1189Cbc_getRowCoeffs(Cbc_Model *model, int row)
1190{
1191  const CoinPackedMatrix *cpmRow = model->model_->solver()->getMatrixByRow();
1192  const CoinBigIndex *starts = cpmRow->getVectorStarts();
1193  const double *rcoef = cpmRow->getElements() + starts[row];
1194  return rcoef;
1195}
1196
1197/** Number of non-zero entries in a column */
1198COINLIBAPI int COINLINKAGE
1199Cbc_getColNz(Cbc_Model *model, int col)
1200{
1201  const CoinPackedMatrix *cpmCol = model->model_->solver()->getMatrixByCol();
1202  return cpmCol->getVectorLengths()[col];
1203}
1204
1205/** Indices of rows that a column appears */
1206COINLIBAPI const int *COINLINKAGE
1207Cbc_getColIndices(Cbc_Model *model, int col)
1208{
1209  const CoinPackedMatrix *cpmCol = model->model_->solver()->getMatrixByCol();
1210  const CoinBigIndex *starts = cpmCol->getVectorStarts();
1211  const int *cidx = cpmCol->getIndices() + starts[col];
1212  return cidx;
1213}
1214
1215/** Coefficients that a column appear in rows */
1216COINLIBAPI const double *COINLINKAGE
1217Cbc_getColCoeffs(Cbc_Model *model, int col)
1218{
1219  const CoinPackedMatrix *cpmCol = model->model_->solver()->getMatrixByCol();
1220  const CoinBigIndex *starts = cpmCol->getVectorStarts();
1221  const double *rcoef = cpmCol->getElements() + starts[col];
1222  return rcoef;
1223}
1224
1225/** Right hand side of a row */
1226COINLIBAPI double COINLINKAGE
1227Cbc_getRowRHS(Cbc_Model *model, int row)
1228{
1229  return model->model_->solver()->getRightHandSide()[row];
1230}
1231
1232/** Sense a row */
1233COINLIBAPI char COINLINKAGE
1234Cbc_getRowSense(Cbc_Model *model, int row)
1235{
1236  return model->model_->solver()->getRowSense()[row];
1237}
1238
1239/** Are there a numerical difficulties? */
1240COINLIBAPI int COINLINKAGE
1241Cbc_isAbandoned(Cbc_Model *model)
1242{
1243  if (Cbc_getNumIntegers(model) == 0 || model->relax_ == 1)
1244    return model->solver_->isAbandoned();
1245  else
1246    return model->model_->isAbandoned();
1247}
1248
1249/** Is optimality proven? */
1250COINLIBAPI int COINLINKAGE
1251Cbc_isProvenOptimal(Cbc_Model *model)
1252{
1253  if (Cbc_getNumIntegers(model) == 0 || model->relax_ == 1)
1254    return model->solver_->isProvenOptimal();
1255  else
1256    return model->model_->isProvenOptimal();
1257}
1258
1259COINLIBAPI int COINLINKAGE
1260Cbc_isProvenInfeasible(Cbc_Model *model)
1261{
1262  if (Cbc_getNumIntegers(model) == 0 || model->relax_ == 1)
1263    return (model->solver_->isProvenDualInfeasible() || model->solver_->isProvenPrimalInfeasible());
1264  else
1265    return model->model_->isProvenInfeasible();
1266}
1267
1268COINLIBAPI double COINLINKAGE
1269Cbc_getObjValue(Cbc_Model *model)
1270{
1271  if (Cbc_getNumIntegers(model) == 0 || model->relax_ == 1)
1272    return (model->solver_->getObjValue());
1273
1274  return model->model_->getObjValue();
1275}
1276
1277COINLIBAPI const double *COINLINKAGE
1278Cbc_getReducedCost(Cbc_Model *model)
1279{
1280  if (Cbc_getNumIntegers(model) == 0 || model->relax_ == 1)
1281    return (model->solver_->getReducedCost());
1282
1283  return model->model_->getReducedCost();
1284}
1285
1286COINLIBAPI int COINLINKAGE
1287Cbc_numberSavedSolutions(Cbc_Model *model)
1288{
1289  return model->model_->numberSavedSolutions();
1290}
1291
1292COINLIBAPI const double *COINLINKAGE
1293Cbc_savedSolution(Cbc_Model *model, int whichSol)
1294{
1295  return model->model_->savedSolution(whichSol);
1296}
1297
1298COINLIBAPI double COINLINKAGE
1299Cbc_savedSolutionObj(Cbc_Model *model, int whichSol)
1300{
1301  return model->model_->savedSolutionObjective(whichSol);
1302}
1303
1304COINLIBAPI const double *COINLINKAGE
1305Cbc_getColSolution(Cbc_Model *model)
1306{
1307  if (Cbc_getNumIntegers(model) == 0 || model->relax_ == 1)
1308    return (model->solver_->getColSolution());
1309
1310  return model->model_->getColSolution();
1311}
1312
1313CbcGetProperty(int, isContinuousUnbounded)
1314  CbcGetProperty(int, isNodeLimitReached)
1315    CbcGetProperty(int, isSecondsLimitReached)
1316      CbcGetProperty(int, isSolutionLimitReached)
1317        CbcGetProperty(int, isInitialSolveAbandoned)
1318          CbcGetProperty(int, isInitialSolveProvenOptimal)
1319            CbcGetProperty(int, isInitialSolveProvenPrimalInfeasible)
1320
1321              CbcGetProperty(double, getObjSense)
1322
1323                COINLIBAPI void COINLINKAGE
1324  Cbc_setObjSense(Cbc_Model *model, double sense)
1325{
1326  Cbc_flush(model);
1327  model->model_->setObjSense(sense);
1328}
1329
1330CbcGetProperty(const double *, getRowActivity)
1331
1332CbcGetProperty(const double *, getRowLower)
1333CbcSetSolverProperty(double, setRowLower)
1334CbcGetProperty(const double *, getRowUpper)
1335CbcSetSolverProperty(double, setRowUpper)
1336
1337COINLIBAPI const double *COINLINKAGE
1338Cbc_getColLower(Cbc_Model *model)
1339{
1340  Cbc_flush(model); 
1341  return model->model_->solver()->getColLower();
1342}
1343
1344COINLIBAPI const double *COINLINKAGE
1345Cbc_getColUpper(Cbc_Model *model)
1346{
1347  Cbc_flush(model); 
1348  return model->model_->solver()->getColUpper();
1349}
1350
1351CbcGetProperty(double, getBestPossibleObjValue)
1352
1353COINLIBAPI const double *COINLINKAGE
1354Cbc_getObjCoefficients(Cbc_Model *model)
1355{
1356  Cbc_flush(model); 
1357  return model->model_->solver()->getObjCoefficients();
1358}
1359
1360COINLIBAPI void COINLINKAGE
1361Cbc_setObjCoeff(Cbc_Model *model, int index, double value)
1362{
1363  Cbc_flush( model );
1364  model->model_->solver()->setObjCoeff( index, value );
1365}
1366
1367COINLIBAPI void COINLINKAGE
1368Cbc_setColLower(Cbc_Model *model, int index, double value)
1369{
1370  Cbc_flush(model);
1371  model->model_->solver()->setColLower( index, value );
1372}
1373
1374COINLIBAPI void COINLINKAGE
1375Cbc_setColUpper(Cbc_Model *model, int index, double value)
1376{
1377  Cbc_flush(model);
1378  model->model_->solver()->setColUpper( index, value );
1379}
1380
1381
1382COINLIBAPI double *COINLINKAGE
1383Cbc_bestSolution(Cbc_Model *model)
1384{
1385  return model->model_->bestSolution();
1386}
1387
1388/* Print model */
1389COINLIBAPI void COINLINKAGE
1390Cbc_printModel(Cbc_Model *model, const char *argPrefix)
1391{
1392  const char prefix[] = "Cbc_C_Interface::Cbc_printModel(): ";
1393  const int VERBOSE = 4;
1394  if (VERBOSE > 0)
1395    printf("%s begin\n", prefix);
1396
1397  CbcModel *cbc_model = model->model_;
1398  int numrows = cbc_model->getNumRows();
1399  int numcols = cbc_model->getNumCols();
1400  int numelem = cbc_model->getNumElements();
1401  const CoinPackedMatrix *matrix = cbc_model->solver()->getMatrixByCol();
1402  const CoinBigIndex *start = matrix->getVectorStarts();
1403  const int *index = matrix->getIndices();
1404  const double *value = matrix->getElements();
1405  const double *collb = cbc_model->getColLower();
1406  const double *colub = cbc_model->getColUpper();
1407  const double *obj = cbc_model->getObjCoefficients();
1408  const double *rowlb = cbc_model->getRowLower();
1409  const double *rowub = cbc_model->getRowUpper();
1410
1411  printf("%s numcols = %i, numrows = %i, numelem = %i\n",
1412    argPrefix, numcols, numrows, numelem);
1413  printf("%s model = %p, start = %p, index = %p, value = %p\n",
1414    argPrefix, static_cast< void * >(model), static_cast< const void * >(start),
1415    static_cast< const void * >(index), static_cast< const void * >(value));
1416  matrix->dumpMatrix(NULL);
1417  {
1418    int i;
1419    for (i = 0; i <= numcols; i++)
1420      printf("%s start[%i] = %i\n", argPrefix, i, start[i]);
1421    for (i = 0; i < numelem; i++)
1422      printf("%s index[%i] = %i, value[%i] = %g\n",
1423        argPrefix, i, index[i], i, value[i]);
1424  }
1425
1426  printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
1427    argPrefix, static_cast< const void * >(collb),
1428    static_cast< const void * >(colub), static_cast< const void * >(obj),
1429    static_cast< const void * >(rowlb), static_cast< const void * >(rowub));
1430  printf("%s optimization direction = %g\n", argPrefix, Cbc_getObjSense(model));
1431  printf("  (1 - minimize, -1 - maximize, 0 - ignore)\n");
1432  {
1433    int i;
1434    for (i = 0; i < numcols; i++)
1435      printf("%s collb[%i] = %g, colub[%i] = %g, obj[%i] = %g\n",
1436        argPrefix, i, collb[i], i, colub[i], i, obj[i]);
1437    for (i = 0; i < numrows; i++)
1438      printf("%s rowlb[%i] = %g, rowub[%i] = %g\n",
1439        argPrefix, i, rowlb[i], i, rowub[i]);
1440  }
1441
1442  if (VERBOSE > 0)
1443    printf("%s return\n", prefix);
1444} // Cbc_printModel()
1445
1446COINLIBAPI int COINLINKAGE
1447Cbc_isInteger(Cbc_Model *model, int i)
1448{
1449  const char prefix[] = "Cbc_C_Interface::Cbc_isInteger(): ";
1450  //  const int  VERBOSE = 1;
1451  if (VERBOSE > 0)
1452    printf("%s begin\n", prefix);
1453
1454  Cbc_flush(model); 
1455
1456  bool result = false;
1457  result = model->model_->isInteger(i);
1458
1459  if (VERBOSE > 0)
1460    printf("%s return %i\n", prefix, result);
1461  return (result) ? 1 : 0;
1462}
1463
1464CbcGetProperty(int, getNodeCount)
1465
1466/** Return a copy of this model */
1467COINLIBAPI Cbc_Model *COINLINKAGE
1468Cbc_clone(Cbc_Model *model)
1469{
1470  const char prefix[] = "Cbc_C_Interface::Cbc_clone(): ";
1471  //  const int  VERBOSE = 1;
1472  if (VERBOSE > 0)
1473    printf("%s begin\n", prefix);
1474
1475  Cbc_flush(model); 
1476  Cbc_Model *result = new Cbc_Model();
1477  result->model_ = new CbcModel(*(model->model_));
1478  result->solver_ = dynamic_cast< OsiClpSolverInterface * >(result->model_->solver());
1479  result->cbcData = new CbcSolverUsefulData();
1480  result->handler_ = NULL;
1481  result->cmdargs_ = model->cmdargs_;
1482  result->relax_ = model->relax_;
1483  result->cbcData->noPrinting_ = model->cbcData->noPrinting_;
1484  result->inc_callback = model->inc_callback;
1485  if (model->colNameIndex)
1486    Cbc_storeNameIndexes(result, 1);
1487
1488  result->colSpace = 0;
1489  result->nCols = 0;
1490  result->cNameSpace = 0;
1491  result->cNameStart = NULL;
1492  result->cInt = NULL;
1493  result->cNames= NULL;
1494  result->cLB = NULL;
1495  result->cUB = NULL;
1496  result->cObj = NULL;
1497
1498  if (VERBOSE > 0)
1499    printf("%s return\n", prefix);
1500  return result;
1501}
1502/** Set this the variable to be continuous */
1503COINLIBAPI void COINLINKAGE
1504Cbc_setContinuous(Cbc_Model *model, int iColumn)
1505{
1506  const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
1507  //  const int  VERBOSE = 1;
1508  if (VERBOSE > 0)
1509    printf("%s begin\n", prefix);
1510
1511  Cbc_flush(model);
1512
1513  model->model_->solver()->setContinuous(iColumn);
1514
1515  if (VERBOSE > 0)
1516    printf("%s return\n", prefix);
1517}
1518/** Set this the variable to be integer */
1519COINLIBAPI void COINLINKAGE
1520Cbc_setInteger(Cbc_Model *model, int iColumn)
1521{
1522  const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
1523  //  const int  VERBOSE = 1;
1524  if (VERBOSE > 0)
1525    printf("%s begin\n", prefix);
1526
1527  Cbc_flush(model);
1528
1529  model->model_->solver()->setInteger(iColumn);
1530
1531  if (VERBOSE > 0)
1532    printf("%s return\n", prefix);
1533}
1534
1535/** Adds a new column */
1536COINLIBAPI void COINLINKAGE
1537Cbc_addCol(Cbc_Model *model, const char *name, double lb,
1538  double ub, double obj, char isInteger,
1539  int nz, int *rows, double *coefs)
1540{
1541  OsiSolverInterface *solver = model->model_->solver();
1542
1543  if ( nz==0 )
1544  {
1545    Cbc_addColBuffer( model, name, lb, ub, obj, isInteger ); 
1546  }
1547  else
1548  {
1549    solver->addCol(nz, rows, coefs, lb, ub, obj, std::string(name));
1550    if (isInteger)
1551      solver->setInteger(solver->getNumCols() - 1);
1552  }
1553
1554  if (model->colNameIndex)
1555  {
1556    NameIndex &colNameIndex = *((NameIndex  *)model->colNameIndex);
1557    colNameIndex[std::string(name)] = Cbc_getNumCols(model)-1;
1558  }
1559}
1560
1561/** Adds a new row */
1562COINLIBAPI void COINLINKAGE
1563Cbc_addRow(Cbc_Model *model, const char *name, int nz,
1564  const int *cols, const double *coefs, char sense, double rhs)
1565{
1566  Cbc_flush(model);
1567  OsiSolverInterface *solver = model->model_->solver();
1568  double rowLB = -DBL_MAX, rowUB = DBL_MAX;
1569  switch (toupper(sense)) {
1570  case '=':
1571    rowLB = rowUB = rhs;
1572    break;
1573  case 'E':
1574    rowLB = rowUB = rhs;
1575    break;
1576  case '<':
1577    rowUB = rhs;
1578    break;
1579  case 'L':
1580    rowUB = rhs;
1581    break;
1582  case '>':
1583    rowLB = rhs;
1584    break;
1585  case 'G':
1586    rowLB = rhs;
1587    break;
1588  default:
1589    fprintf(stderr, "unknow row sense %c.", toupper(sense));
1590    abort();
1591  }
1592  solver->addRow(nz, cols, coefs, rowLB, rowUB);
1593  solver->setRowName(solver->getNumRows() - 1, std::string(name));
1594
1595  if (model->rowNameIndex)
1596  {
1597    NameIndex &rowNameIndex = *((NameIndex  *)model->rowNameIndex);
1598    rowNameIndex[std::string(name)] = Cbc_getNumRows(model)-1;
1599  }
1600}
1601
1602COINLIBAPI void COINLINKAGE
1603Cbc_deleteRows(Cbc_Model *model, int numRows, const int rows[])
1604{
1605  Cbc_flush(model);
1606  OsiSolverInterface *solver = model->model_->solver();
1607
1608  if (model->rowNameIndex)
1609  {
1610    NameIndex &rowNameIndex = *((NameIndex  *)model->rowNameIndex);
1611    for ( int i=0 ; i<numRows; ++i )
1612      rowNameIndex.erase(solver->getRowName(rows[i]));
1613  }
1614
1615  solver->deleteRows(numRows, rows);
1616}
1617
1618COINLIBAPI void COINLINKAGE
1619Cbc_deleteCols(Cbc_Model *model, int numCols, const int cols[])
1620{
1621  Cbc_flush(model);
1622  OsiSolverInterface *solver = model->model_->solver();
1623
1624  if (model->colNameIndex)
1625  {
1626    NameIndex &colNameIndex = *((NameIndex  *)model->colNameIndex);
1627    for ( int i=0 ; i<numCols; ++i )
1628      colNameIndex.erase(solver->getColName(cols[i]));
1629  }
1630
1631  solver->deleteCols(numCols, cols);
1632}
1633
1634/** Add SOS constraints to the model using row-order matrix */
1635
1636COINLIBAPI void COINLINKAGE
1637Cbc_addSOS(Cbc_Model *model, int numRows, const int *rowStarts,
1638  const int *colIndices, const double *weights, const int type)
1639{
1640  Cbc_flush(model);
1641  const char prefix[] = "Cbc_C_Interface::Cbc_addSOS(): ";
1642  //const int  VERBOSE = 4;
1643  if (VERBOSE > 0)
1644    printf("%sbegin\n", prefix);
1645
1646  if (VERBOSE > 0)
1647    printf("%s numRows = %i\n", prefix, numRows);
1648
1649  int row, i;
1650  const int *colIndex;
1651  const double *colWeight;
1652
1653  // loop on rows and count number of objects according to numWeights>0
1654  int numObjects = 0;
1655  for (row = 0; row < numRows; row++) {
1656    if (VERBOSE > 2) {
1657      printf("%s row = %i\n", prefix, row);
1658      printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
1659      printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row + 1]);
1660      fflush(stdout);
1661    }
1662    const int numWeights = rowStarts[row + 1] - rowStarts[row];
1663    if (VERBOSE > 2)
1664      printf("%s  numWeights = %i\n", prefix, numWeights);
1665    if (numWeights > 0)
1666      numObjects++;
1667  }
1668
1669  // make objects
1670  CbcObject **objects = new CbcObject *[numObjects];
1671  //  if (VERBOSE>1) printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
1672
1673  // loop on rows and make an object when numWeights>0
1674  int objNum = 0;
1675  for (row = 0; row < numRows; row++) {
1676    if (VERBOSE > 2) {
1677      printf("%s row = %i\n", prefix, row);
1678      printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
1679      printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row + 1]);
1680    }
1681    const int numWeights = rowStarts[row + 1] - rowStarts[row];
1682    if (VERBOSE > 2)
1683      printf("%s  numWeights = %i\n", prefix, numWeights);
1684    colIndex = colIndices + rowStarts[row];
1685    colWeight = weights + rowStarts[row];
1686    if (numWeights > 0) {
1687      // Make a CbcSOS and assign it to objects
1688      if (VERBOSE > 3) {
1689        for (i = 0; i < numWeights; i++) {
1690          printf("%s  colIndex [%i] = %i\n", prefix, i, colIndex[i]);
1691          printf("%s  colWeight[%i] = %f\n", prefix, i, colWeight[i]);
1692        }
1693        fflush(stdout);
1694      }
1695      objects[objNum] = new CbcSOS(model->model_, (int)(numWeights),
1696        (const int *)colIndex, (const double *)colWeight, (int)objNum, (int)type);
1697      //      if (VERBOSE>2) printf("%s objects[%i] = %X\n",prefix,objNum,objects[objNum]);
1698      if (objects[objNum] == NULL) {
1699        printf("%s ERROR: objects[%i] == NULL\n", prefix, objNum);
1700        fflush(stdout);
1701        assert(objects[objNum] != NULL);
1702      }
1703      objNum++;
1704    }
1705  }
1706  if (VERBOSE > 2) {
1707    printf("%s calling addObjects()\n", prefix);
1708
1709    //    printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
1710    //    for (row=0; row<numObjects; row++)
1711    //      printf("%s  objects[%i] = %X\n",prefix,row,objects[row]);
1712  }
1713  fflush(stdout);
1714  model->model_->addObjects(numObjects, objects);
1715  if (VERBOSE > 1)
1716    printf("%s finished addObjects()\n", prefix);
1717
1718  for (objNum = 0; objNum < numObjects; objNum++)
1719    delete objects[objNum];
1720  delete[] objects;
1721
1722  if (VERBOSE > 0)
1723    printf("%sreturn\n", prefix);
1724  return;
1725}
1726
1727COINLIBAPI void COINLINKAGE
1728Cbc_setMIPStart(Cbc_Model *model, int count, const char **colNames, const double colValues[])
1729{
1730  Cbc_flush(model); 
1731  model->model_->setMIPStart(count, colNames, colValues);
1732}
1733
1734COINLIBAPI void COINLINKAGE
1735Cbc_setMIPStartI(Cbc_Model *model, int count, const int colIdxs[], const double colValues[])
1736{
1737  Cbc_flush(model); 
1738  CbcModel *cbcModel = model->model_;
1739  OsiSolverInterface *solver = cbcModel->solver();
1740
1741  int charSpace = count;
1742  for (int i = 0; (i < count); ++i)
1743    charSpace += solver->getColName(colIdxs[i]).size();
1744
1745  char *allChars = new char[charSpace];
1746  char *s = allChars;
1747  char **names = new char *[count];
1748  for (int i = 0; (i < count); ++i) {
1749    names[i] = s;
1750    strcpy(s, solver->getColName(colIdxs[i]).c_str());
1751    s += solver->getColName(colIdxs[i]).size() + 1;
1752  }
1753
1754  cbcModel->setMIPStart(count, (const char **)names, colValues);
1755
1756  delete[] names;
1757  delete[] allChars;
1758}
1759
1760/** Print the solution */
1761COINLIBAPI void COINLINKAGE
1762Cbc_printSolution(Cbc_Model *model)
1763{
1764  {
1765    //
1766    //  Now to print out row solution.  The methods used return const
1767    //  pointers - which is of course much more virtuous.
1768    //
1769    //  This version just does non-zero columns
1770    //
1771
1772    // * Rows
1773
1774    int numberRows = Cbc_getNumRows(model);
1775    int iRow;
1776
1777    const double *rowPrimal = Cbc_getRowActivity(model);
1778    const double *rowLower = Cbc_getRowLower(model);
1779    const double *rowUpper = Cbc_getRowUpper(model);
1780    printf("--------------------------------------\n");
1781
1782    // * If we have not kept names (parameter to readMps) this will be 0
1783    //    assert(Cbc_lengthNames(model));
1784
1785    printf("                       Primal          Lower         Upper\n");
1786    for (iRow = 0; iRow < numberRows; iRow++) {
1787      double value;
1788      value = rowPrimal[iRow];
1789      if (value > 1.0e-8 || value < -1.0e-8) {
1790        char name[20];
1791        //              Cbc_columnName(model,iColumn,name);
1792        sprintf(name, "ROW%5i", iRow);
1793        printf("%6d %8s", iRow, name);
1794        printf(" %13g", rowPrimal[iRow]);
1795        printf(" %13g", rowLower[iRow]);
1796        printf(" %13g", rowUpper[iRow]);
1797        printf("\n");
1798      }
1799    }
1800    printf("--------------------------------------\n");
1801  }
1802  {
1803    //
1804    //  Now to print out column solution.  The methods used return const
1805    //  pointers - which is of course much more virtuous.
1806    //
1807    //  This version just does non-zero columns
1808    //
1809    //
1810
1811    // * Columns
1812
1813    int numberColumns = Cbc_getNumCols(model);
1814    int iColumn;
1815
1816    const double *columnPrimal = Cbc_getColSolution(model);
1817    const double *columnLower = Cbc_getColLower(model);
1818    const double *columnUpper = Cbc_getColUpper(model);
1819    const double *columnObjective = Cbc_getObjCoefficients(model);
1820
1821    printf("--------------------------------------\n");
1822
1823    // * If we have not kept names (parameter to readMps) this will be 0
1824    //    assert(Cbc_lengthNames(model));
1825
1826    printf("                       Primal          Lower         Upper          Cost     isInteger\n");
1827    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1828      double value;
1829      value = columnPrimal[iColumn];
1830      if (value > 1.0e-8 || value < -1.0e-8) {
1831        char name[20];
1832        //              Cbc_columnName(model,iColumn,name);
1833        sprintf(name, "COL%5i", iColumn);
1834        printf("%6d %8s", iColumn, name);
1835        printf(" %13g", columnPrimal[iColumn]);
1836        printf(" %13g", columnLower[iColumn]);
1837        printf(" %13g", columnUpper[iColumn]);
1838        printf(" %13g", columnObjective[iColumn]);
1839        printf(" %13i", Cbc_isInteger(model, iColumn));
1840        printf("\n");
1841      }
1842    }
1843    printf("--------------------------------------\n");
1844  }
1845  if (0)
1846    Cbc_printModel(model, "cbc::main(): ");
1847  return;
1848}
1849
1850COINLIBAPI int COINLINKAGE
1851Osi_getNumCols( void *osi )
1852{
1853  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1854  return osiSolver->getNumCols();
1855}
1856
1857/** @brief Returns column name in OsiSolverInterface object */
1858COINLIBAPI void COINLINKAGE
1859Osi_getColName( void *osi, int i, char *name, int maxLen )
1860{
1861  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1862  strncpy( name, osiSolver->getColName(i).c_str(), maxLen );
1863}
1864
1865/** @brief Returns column lower bounds in OsiSolverInterface object */
1866COINLIBAPI const double * COINLINKAGE
1867Osi_getColLower( void *osi )
1868{
1869  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1870  return osiSolver->getColLower();
1871}
1872
1873/** @brief Returns column upper bounds in OsiSolverInterface object */
1874COINLIBAPI const double * COINLINKAGE
1875Osi_getColUpper( void *osi )
1876{
1877  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1878  return osiSolver->getColUpper();
1879}
1880
1881/** @brief Returns integrality information for columns in OsiSolverInterface object */
1882COINLIBAPI int COINLINKAGE
1883Osi_isInteger( void *osi, int col )
1884{
1885  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1886  return osiSolver->isInteger(col);
1887}
1888
1889/** @brief Returns number of rows in OsiSolverInterface object */
1890COINLIBAPI int COINLINKAGE
1891Osi_getNumRows( void *osi )
1892{
1893  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1894  return osiSolver->getNumRows();
1895}
1896
1897COINLIBAPI int COINLINKAGE
1898Osi_getRowNz(void *osi, int row)
1899{
1900  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1901
1902  const CoinPackedMatrix *cpmRow = osiSolver->getMatrixByRow();
1903  return cpmRow->getVectorLengths()[row];
1904}
1905
1906/** @brief Indices of variables that appear on a row */
1907COINLIBAPI const int *COINLINKAGE
1908Osi_getRowIndices(void *osi, int row)
1909{
1910  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1911
1912  const CoinPackedMatrix *cpmRow = osiSolver->getMatrixByRow();
1913  const CoinBigIndex *starts = cpmRow->getVectorStarts();
1914  const int *ridx = cpmRow->getIndices() + starts[row];
1915  return ridx;
1916}
1917
1918/** @brief Coefficients of variables that appear on this row  */
1919COINLIBAPI const double *COINLINKAGE
1920Osi_getRowCoeffs(void *osi, int row)
1921{
1922  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1923
1924  const CoinPackedMatrix *cpmRow = osiSolver->getMatrixByRow();
1925  const CoinBigIndex *starts = cpmRow->getVectorStarts();
1926  const double *rcoef = cpmRow->getElements() + starts[row];
1927  return rcoef;
1928}
1929
1930/** @brief Right hand side of a row  */
1931COINLIBAPI double COINLINKAGE
1932Osi_getRowRHS(void *osi, int row)
1933{
1934  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1935  return osiSolver->getRightHandSide()[row];
1936}
1937
1938/** @brief Sense a row
1939     * @param model problem object
1940     * @param row row index
1941     * @return row sense: E for =, L for <=, G for >= and R for ranged row
1942     **/
1943COINLIBAPI char COINLINKAGE
1944Osi_getRowSense(void *osi, int row)
1945{
1946  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1947
1948  return osiSolver->getRowSense()[row];
1949}
1950
1951COINLIBAPI void COINLINKAGE
1952OsiCuts_addRowCut( void *osiCuts, int nz, const int *idx, const double *coef, char sense, double rhs )
1953{
1954  sense = toupper(sense);
1955  OsiCuts *oc = (OsiCuts *) osiCuts;
1956
1957  OsiRowCut orc;
1958  orc.setRow( nz, idx, coef );
1959
1960
1961  orc.setLb(-DBL_MAX);
1962  orc.setUb(DBL_MAX);
1963
1964  switch (toupper(sense)) {
1965  case '=':
1966    orc.setLb(rhs);
1967    orc.setUb(rhs);
1968    break;
1969  case 'E':
1970    orc.setLb(rhs);
1971    orc.setUb(rhs);
1972    break;
1973  case '<':
1974    orc.setUb(rhs);
1975    break;
1976  case 'L':
1977    orc.setUb(rhs);
1978    break;
1979  case '>':
1980    orc.setLb(rhs);
1981    break;
1982  case 'G':
1983    orc.setLb(rhs);
1984    break;
1985  default:
1986    fprintf(stderr, "unknow row sense %c.", toupper(sense));
1987    abort();
1988  }
1989
1990  oc->insert(orc);
1991}
1992
1993
1994
1995/** @brief Returns solution vector in OsiSolverInterface object */
1996COINLIBAPI const double * COINLINKAGE
1997Osi_getColSolution( void *osi )
1998{
1999  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
2000
2001  return osiSolver->getColSolution();
2002}
2003
2004COINLIBAPI double COINLINKAGE
2005Cbc_getAllowableGap(Cbc_Model* model)
2006{
2007  return model->model_->getAllowableGap();
2008}
2009
2010COINLIBAPI void COINLINKAGE
2011Cbc_setAllowableGap(Cbc_Model* model, double allowedGap)
2012{
2013  model->model_->setAllowableGap(allowedGap);
2014}
2015
2016COINLIBAPI double COINLINKAGE
2017Cbc_getAllowableFractionGap(Cbc_Model* model)
2018{
2019  return model->model_->getAllowableFractionGap();
2020}
2021
2022COINLIBAPI void COINLINKAGE
2023Cbc_setAllowableFractionGap(Cbc_Model* model, double allowedFracionGap)
2024{
2025  model->model_->setAllowableFractionGap(allowedFracionGap);
2026}
2027
2028/** returns the maximum number of nodes that can be explored in the search tree
2029 */
2030COINLIBAPI int COINLINKAGE
2031Cbc_getMaximumNodes(Cbc_Model *model)
2032{
2033  return model->model_->getMaximumNodes();
2034}
2035
2036/** sets the maximum number of nodes that can be explored in the search tree
2037 */
2038COINLIBAPI void COINLINKAGE
2039Cbc_setMaximumNodes(Cbc_Model *model, int maxNodes)
2040{
2041  model->model_->setMaximumNodes(maxNodes);
2042}
2043
2044/** returns solution limit for the search process
2045 */
2046COINLIBAPI int COINLINKAGE
2047Cbc_getMaximumSolutions(Cbc_Model *model)
2048{
2049  return model->model_->getMaximumSolutions();
2050}
2051
2052/** sets a solution limit as a stopping criterion
2053 */
2054COINLIBAPI void COINLINKAGE
2055Cbc_setMaximumSolutions(Cbc_Model *model, int maxSolutions)
2056{
2057  model->model_->setMaximumSolutions(maxSolutions);
2058}
2059
2060/** returns the current log leven
2061 */
2062COINLIBAPI int COINLINKAGE
2063Cbc_getLogLevel(Cbc_Model *model)
2064{
2065  return model->model_->logLevel();
2066}
2067
2068/** sets the log level
2069 */
2070COINLIBAPI void COINLINKAGE
2071Cbc_setLogLevel(Cbc_Model *model, int logLevel)
2072{
2073  model->model_->setLogLevel(logLevel);
2074}
2075
2076
2077
2078COINLIBAPI double COINLINKAGE
2079Cbc_getCutoff(Cbc_Model* model)
2080{
2081  return model->model_->getCutoff();
2082}
2083
2084COINLIBAPI void COINLINKAGE
2085Cbc_setCutoff(Cbc_Model* model, double cutoff)
2086{
2087  model->model_->setCutoff(cutoff);
2088}
2089
2090COINLIBAPI double COINLINKAGE
2091Cbc_getAllowablePercentageGap(Cbc_Model* model)
2092{
2093  return model->model_->getAllowablePercentageGap();
2094}
2095
2096COINLIBAPI void COINLINKAGE
2097Cbc_setAllowablePercentageGap(Cbc_Model* model,
2098    double allowedPercentageGap)
2099{
2100  model->model_->setAllowablePercentageGap(allowedPercentageGap);
2101}
2102
2103COINLIBAPI double COINLINKAGE
2104Cbc_getMaximumSeconds(Cbc_Model *model)
2105{
2106  return model->model_->getMaximumSeconds();
2107}
2108
2109COINLIBAPI void COINLINKAGE
2110Cbc_setMaximumSeconds(Cbc_Model *model, double maxSeconds)
2111{
2112  model->model_->setMaximumSeconds(maxSeconds);
2113}
2114
2115COINLIBAPI void COINLINKAGE
2116Cbc_storeNameIndexes(Cbc_Model *model, char _store)
2117{
2118  if (_store)
2119  {
2120    if (model->colNameIndex==NULL)
2121    {
2122      assert(model->rowNameIndex==NULL);
2123      model->colNameIndex = new NameIndex();
2124      model->rowNameIndex = new NameIndex();
2125    }
2126  }
2127  else
2128  {
2129    if (model->colNameIndex!=NULL)
2130    {
2131      NameIndex *m = (NameIndex *)model->colNameIndex;
2132      delete m;
2133      m = (NameIndex *)model->rowNameIndex;
2134      assert( m != NULL );
2135      delete m;
2136
2137      model->colNameIndex = model->rowNameIndex = NULL;
2138    }
2139  }
2140}
2141
2142COINLIBAPI int COINLINKAGE
2143Cbc_getColNameIndex(Cbc_Model *model, const char *name)
2144{
2145  if (!model->colNameIndex)
2146  {
2147    fprintf(stderr, "Call Cbc_storeNameIndex to enable name index search.");
2148    abort();
2149  }
2150
2151  OsiSolverInterface *solver = model->model_->solver();
2152  NameIndex &colNameIndex = *((NameIndex  *)model->colNameIndex);
2153  NameIndex::iterator it = colNameIndex.find(std::string(name));
2154  if (it == colNameIndex.end())
2155    return -1;
2156
2157  return it->second;
2158}
2159
2160COINLIBAPI int COINLINKAGE
2161Cbc_getRowNameIndex(Cbc_Model *model, const char *name)
2162{
2163  if (!model->rowNameIndex)
2164  {
2165    fprintf(stderr, "Call Cbc_storeNameIndex to enable name index search.");
2166    abort();
2167  }
2168
2169  OsiSolverInterface *solver = model->model_->solver();
2170  NameIndex &rowNameIndex = *((NameIndex  *)model->rowNameIndex);
2171  NameIndex::iterator it = rowNameIndex.find(std::string(name));
2172  if (it == rowNameIndex.end())
2173    return -1;
2174
2175  return it->second;
2176}
2177
2178
2179#if defined(__MWERKS__)
2180#pragma export off
2181#endif
2182
2183/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
2184*/
Note: See TracBrowser for help on using the repository browser.