source: trunk/Cbc/src/Cbc_C_Interface.cpp @ 2573

Last change on this file since 2573 was 2573, checked in by unxusr, 5 months ago

option to store maps for fast search of column/row names in C API

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 56.8 KB
Line 
1// $Id: Cbc_C_Interface.cpp 2573 2019-05-08 10:35:04Z unxusr $
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
1471  const char prefix[] = "Cbc_C_Interface::Cbc_clone(): ";
1472  //  const int  VERBOSE = 1;
1473  if (VERBOSE > 0)
1474    printf("%s begin\n", prefix);
1475
1476  Cbc_flush(model); 
1477  Cbc_Model *result = new Cbc_Model();
1478  result->model_ = new CbcModel(*(model->model_));
1479  result->solver_ = dynamic_cast< OsiClpSolverInterface * >(result->model_->solver());
1480  result->handler_ = NULL;
1481  result->cmdargs_ = model->cmdargs_;
1482  result->relax_ = model->relax_;
1483
1484  if (VERBOSE > 0)
1485    printf("%s return\n", prefix);
1486  return result;
1487}
1488/** Set this the variable to be continuous */
1489COINLIBAPI void COINLINKAGE
1490Cbc_setContinuous(Cbc_Model *model, int iColumn)
1491{
1492  const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
1493  //  const int  VERBOSE = 1;
1494  if (VERBOSE > 0)
1495    printf("%s begin\n", prefix);
1496
1497  Cbc_flush(model);
1498
1499  model->model_->solver()->setContinuous(iColumn);
1500
1501  if (VERBOSE > 0)
1502    printf("%s return\n", prefix);
1503}
1504/** Set this the variable to be integer */
1505COINLIBAPI void COINLINKAGE
1506Cbc_setInteger(Cbc_Model *model, int iColumn)
1507{
1508  const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
1509  //  const int  VERBOSE = 1;
1510  if (VERBOSE > 0)
1511    printf("%s begin\n", prefix);
1512
1513  Cbc_flush(model);
1514
1515  model->model_->solver()->setInteger(iColumn);
1516
1517  if (VERBOSE > 0)
1518    printf("%s return\n", prefix);
1519}
1520
1521/** Adds a new column */
1522COINLIBAPI void COINLINKAGE
1523Cbc_addCol(Cbc_Model *model, const char *name, double lb,
1524  double ub, double obj, char isInteger,
1525  int nz, int *rows, double *coefs)
1526{
1527  OsiSolverInterface *solver = model->model_->solver();
1528
1529  if ( nz==0 )
1530  {
1531    Cbc_addColBuffer( model, name, lb, ub, obj, isInteger ); 
1532  }
1533  else
1534  {
1535    solver->addCol(nz, rows, coefs, lb, ub, obj, std::string(name));
1536    if (isInteger)
1537      solver->setInteger(solver->getNumCols() - 1);
1538  }
1539
1540  if (model->colNameIndex)
1541  {
1542    NameIndex &colNameIndex = *((NameIndex  *)model->colNameIndex);
1543    colNameIndex[std::string(name)] = Cbc_getNumCols(model)-1;
1544  }
1545}
1546
1547/** Adds a new row */
1548COINLIBAPI void COINLINKAGE
1549Cbc_addRow(Cbc_Model *model, const char *name, int nz,
1550  const int *cols, const double *coefs, char sense, double rhs)
1551{
1552  Cbc_flush(model);
1553  OsiSolverInterface *solver = model->model_->solver();
1554  double rowLB = -DBL_MAX, rowUB = DBL_MAX;
1555  switch (toupper(sense)) {
1556  case '=':
1557    rowLB = rowUB = rhs;
1558    break;
1559  case 'E':
1560    rowLB = rowUB = rhs;
1561    break;
1562  case '<':
1563    rowUB = rhs;
1564    break;
1565  case 'L':
1566    rowUB = rhs;
1567    break;
1568  case '>':
1569    rowLB = rhs;
1570    break;
1571  case 'G':
1572    rowLB = rhs;
1573    break;
1574  default:
1575    fprintf(stderr, "unknow row sense %c.", toupper(sense));
1576    abort();
1577  }
1578  solver->addRow(nz, cols, coefs, rowLB, rowUB);
1579  solver->setRowName(solver->getNumRows() - 1, std::string(name));
1580
1581  if (model->rowNameIndex)
1582  {
1583    NameIndex &rowNameIndex = *((NameIndex  *)model->rowNameIndex);
1584    rowNameIndex[std::string(name)] = Cbc_getNumRows(model)-1;
1585  }
1586}
1587
1588COINLIBAPI void COINLINKAGE
1589Cbc_deleteRows(Cbc_Model *model, int numRows, const int rows[])
1590{
1591  Cbc_flush(model);
1592  OsiSolverInterface *solver = model->model_->solver();
1593
1594  if (model->rowNameIndex)
1595  {
1596    NameIndex &rowNameIndex = *((NameIndex  *)model->rowNameIndex);
1597    for ( int i=0 ; i<numRows; ++i )
1598      rowNameIndex.erase(solver->getRowName(rows[i]));
1599  }
1600
1601  solver->deleteRows(numRows, rows);
1602}
1603
1604COINLIBAPI void COINLINKAGE
1605Cbc_deleteCols(Cbc_Model *model, int numCols, const int cols[])
1606{
1607  Cbc_flush(model);
1608  OsiSolverInterface *solver = model->model_->solver();
1609
1610  if (model->colNameIndex)
1611  {
1612    NameIndex &colNameIndex = *((NameIndex  *)model->colNameIndex);
1613    for ( int i=0 ; i<numCols; ++i )
1614      colNameIndex.erase(solver->getColName(cols[i]));
1615  }
1616
1617  solver->deleteCols(numCols, cols);
1618}
1619
1620/** Add SOS constraints to the model using row-order matrix */
1621
1622COINLIBAPI void COINLINKAGE
1623Cbc_addSOS(Cbc_Model *model, int numRows, const int *rowStarts,
1624  const int *colIndices, const double *weights, const int type)
1625{
1626  Cbc_flush(model);
1627  const char prefix[] = "Cbc_C_Interface::Cbc_addSOS(): ";
1628  //const int  VERBOSE = 4;
1629  if (VERBOSE > 0)
1630    printf("%sbegin\n", prefix);
1631
1632  if (VERBOSE > 0)
1633    printf("%s numRows = %i\n", prefix, numRows);
1634
1635  int row, i;
1636  const int *colIndex;
1637  const double *colWeight;
1638
1639  // loop on rows and count number of objects according to numWeights>0
1640  int numObjects = 0;
1641  for (row = 0; row < numRows; row++) {
1642    if (VERBOSE > 2) {
1643      printf("%s row = %i\n", prefix, row);
1644      printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
1645      printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row + 1]);
1646      fflush(stdout);
1647    }
1648    const int numWeights = rowStarts[row + 1] - rowStarts[row];
1649    if (VERBOSE > 2)
1650      printf("%s  numWeights = %i\n", prefix, numWeights);
1651    if (numWeights > 0)
1652      numObjects++;
1653  }
1654
1655  // make objects
1656  CbcObject **objects = new CbcObject *[numObjects];
1657  //  if (VERBOSE>1) printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
1658
1659  // loop on rows and make an object when numWeights>0
1660  int objNum = 0;
1661  for (row = 0; row < numRows; row++) {
1662    if (VERBOSE > 2) {
1663      printf("%s row = %i\n", prefix, row);
1664      printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
1665      printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row + 1]);
1666    }
1667    const int numWeights = rowStarts[row + 1] - rowStarts[row];
1668    if (VERBOSE > 2)
1669      printf("%s  numWeights = %i\n", prefix, numWeights);
1670    colIndex = colIndices + rowStarts[row];
1671    colWeight = weights + rowStarts[row];
1672    if (numWeights > 0) {
1673      // Make a CbcSOS and assign it to objects
1674      if (VERBOSE > 3) {
1675        for (i = 0; i < numWeights; i++) {
1676          printf("%s  colIndex [%i] = %i\n", prefix, i, colIndex[i]);
1677          printf("%s  colWeight[%i] = %f\n", prefix, i, colWeight[i]);
1678        }
1679        fflush(stdout);
1680      }
1681      objects[objNum] = new CbcSOS(model->model_, (int)(numWeights),
1682        (const int *)colIndex, (const double *)colWeight, (int)objNum, (int)type);
1683      //      if (VERBOSE>2) printf("%s objects[%i] = %X\n",prefix,objNum,objects[objNum]);
1684      if (objects[objNum] == NULL) {
1685        printf("%s ERROR: objects[%i] == NULL\n", prefix, objNum);
1686        fflush(stdout);
1687        assert(objects[objNum] != NULL);
1688      }
1689      objNum++;
1690    }
1691  }
1692  if (VERBOSE > 2) {
1693    printf("%s calling addObjects()\n", prefix);
1694
1695    //    printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
1696    //    for (row=0; row<numObjects; row++)
1697    //      printf("%s  objects[%i] = %X\n",prefix,row,objects[row]);
1698  }
1699  fflush(stdout);
1700  model->model_->addObjects(numObjects, objects);
1701  if (VERBOSE > 1)
1702    printf("%s finished addObjects()\n", prefix);
1703
1704  for (objNum = 0; objNum < numObjects; objNum++)
1705    delete objects[objNum];
1706  delete[] objects;
1707
1708  if (VERBOSE > 0)
1709    printf("%sreturn\n", prefix);
1710  return;
1711}
1712
1713COINLIBAPI void COINLINKAGE
1714Cbc_setMIPStart(Cbc_Model *model, int count, const char **colNames, const double colValues[])
1715{
1716  Cbc_flush(model); 
1717  model->model_->setMIPStart(count, colNames, colValues);
1718}
1719
1720COINLIBAPI void COINLINKAGE
1721Cbc_setMIPStartI(Cbc_Model *model, int count, const int colIdxs[], const double colValues[])
1722{
1723  Cbc_flush(model); 
1724  CbcModel *cbcModel = model->model_;
1725  OsiSolverInterface *solver = cbcModel->solver();
1726
1727  int charSpace = count;
1728  for (int i = 0; (i < count); ++i)
1729    charSpace += solver->getColName(colIdxs[i]).size();
1730
1731  char *allChars = new char[charSpace];
1732  char *s = allChars;
1733  char **names = new char *[count];
1734  for (int i = 0; (i < count); ++i) {
1735    names[i] = s;
1736    strcpy(s, solver->getColName(colIdxs[i]).c_str());
1737    s += solver->getColName(colIdxs[i]).size() + 1;
1738  }
1739
1740  cbcModel->setMIPStart(count, (const char **)names, colValues);
1741
1742  delete[] names;
1743  delete[] allChars;
1744}
1745
1746/** Print the solution */
1747COINLIBAPI void COINLINKAGE
1748Cbc_printSolution(Cbc_Model *model)
1749{
1750  {
1751    //
1752    //  Now to print out row solution.  The methods used return const
1753    //  pointers - which is of course much more virtuous.
1754    //
1755    //  This version just does non-zero columns
1756    //
1757
1758    // * Rows
1759
1760    int numberRows = Cbc_getNumRows(model);
1761    int iRow;
1762
1763    const double *rowPrimal = Cbc_getRowActivity(model);
1764    const double *rowLower = Cbc_getRowLower(model);
1765    const double *rowUpper = Cbc_getRowUpper(model);
1766    printf("--------------------------------------\n");
1767
1768    // * If we have not kept names (parameter to readMps) this will be 0
1769    //    assert(Cbc_lengthNames(model));
1770
1771    printf("                       Primal          Lower         Upper\n");
1772    for (iRow = 0; iRow < numberRows; iRow++) {
1773      double value;
1774      value = rowPrimal[iRow];
1775      if (value > 1.0e-8 || value < -1.0e-8) {
1776        char name[20];
1777        //              Cbc_columnName(model,iColumn,name);
1778        sprintf(name, "ROW%5i", iRow);
1779        printf("%6d %8s", iRow, name);
1780        printf(" %13g", rowPrimal[iRow]);
1781        printf(" %13g", rowLower[iRow]);
1782        printf(" %13g", rowUpper[iRow]);
1783        printf("\n");
1784      }
1785    }
1786    printf("--------------------------------------\n");
1787  }
1788  {
1789    //
1790    //  Now to print out column solution.  The methods used return const
1791    //  pointers - which is of course much more virtuous.
1792    //
1793    //  This version just does non-zero columns
1794    //
1795    //
1796
1797    // * Columns
1798
1799    int numberColumns = Cbc_getNumCols(model);
1800    int iColumn;
1801
1802    const double *columnPrimal = Cbc_getColSolution(model);
1803    const double *columnLower = Cbc_getColLower(model);
1804    const double *columnUpper = Cbc_getColUpper(model);
1805    const double *columnObjective = Cbc_getObjCoefficients(model);
1806
1807    printf("--------------------------------------\n");
1808
1809    // * If we have not kept names (parameter to readMps) this will be 0
1810    //    assert(Cbc_lengthNames(model));
1811
1812    printf("                       Primal          Lower         Upper          Cost     isInteger\n");
1813    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1814      double value;
1815      value = columnPrimal[iColumn];
1816      if (value > 1.0e-8 || value < -1.0e-8) {
1817        char name[20];
1818        //              Cbc_columnName(model,iColumn,name);
1819        sprintf(name, "COL%5i", iColumn);
1820        printf("%6d %8s", iColumn, name);
1821        printf(" %13g", columnPrimal[iColumn]);
1822        printf(" %13g", columnLower[iColumn]);
1823        printf(" %13g", columnUpper[iColumn]);
1824        printf(" %13g", columnObjective[iColumn]);
1825        printf(" %13i", Cbc_isInteger(model, iColumn));
1826        printf("\n");
1827      }
1828    }
1829    printf("--------------------------------------\n");
1830  }
1831  if (0)
1832    Cbc_printModel(model, "cbc::main(): ");
1833  return;
1834}
1835
1836COINLIBAPI int COINLINKAGE
1837Osi_getNumCols( void *osi )
1838{
1839  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1840  return osiSolver->getNumCols();
1841}
1842
1843/** @brief Returns column name in OsiSolverInterface object */
1844COINLIBAPI void COINLINKAGE
1845Osi_getColName( void *osi, int i, char *name, int maxLen )
1846{
1847  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1848  strncpy( name, osiSolver->getColName(i).c_str(), maxLen );
1849}
1850
1851/** @brief Returns column lower bounds in OsiSolverInterface object */
1852COINLIBAPI const double * COINLINKAGE
1853Osi_getColLower( void *osi )
1854{
1855  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1856  return osiSolver->getColLower();
1857}
1858
1859/** @brief Returns column upper bounds in OsiSolverInterface object */
1860COINLIBAPI const double * COINLINKAGE
1861Osi_getColUpper( void *osi )
1862{
1863  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1864  return osiSolver->getColUpper();
1865}
1866
1867/** @brief Returns integrality information for columns in OsiSolverInterface object */
1868COINLIBAPI int COINLINKAGE
1869Osi_isInteger( void *osi, int col )
1870{
1871  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1872  return osiSolver->isInteger(col);
1873}
1874
1875/** @brief Returns number of rows in OsiSolverInterface object */
1876COINLIBAPI int COINLINKAGE
1877Osi_getNumRows( void *osi )
1878{
1879  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1880  return osiSolver->getNumRows();
1881}
1882
1883COINLIBAPI int COINLINKAGE
1884Osi_getRowNz(void *osi, int row)
1885{
1886  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1887
1888  const CoinPackedMatrix *cpmRow = osiSolver->getMatrixByRow();
1889  return cpmRow->getVectorLengths()[row];
1890}
1891
1892/** @brief Indices of variables that appear on a row */
1893COINLIBAPI const int *COINLINKAGE
1894Osi_getRowIndices(void *osi, int row)
1895{
1896  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1897
1898  const CoinPackedMatrix *cpmRow = osiSolver->getMatrixByRow();
1899  const CoinBigIndex *starts = cpmRow->getVectorStarts();
1900  const int *ridx = cpmRow->getIndices() + starts[row];
1901  return ridx;
1902}
1903
1904/** @brief Coefficients of variables that appear on this row  */
1905COINLIBAPI const double *COINLINKAGE
1906Osi_getRowCoeffs(void *osi, int row)
1907{
1908  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1909
1910  const CoinPackedMatrix *cpmRow = osiSolver->getMatrixByRow();
1911  const CoinBigIndex *starts = cpmRow->getVectorStarts();
1912  const double *rcoef = cpmRow->getElements() + starts[row];
1913  return rcoef;
1914}
1915
1916/** @brief Right hand side of a row  */
1917COINLIBAPI double COINLINKAGE
1918Osi_getRowRHS(void *osi, int row)
1919{
1920  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1921  return osiSolver->getRightHandSide()[row];
1922}
1923
1924/** @brief Sense a row
1925     * @param model problem object
1926     * @param row row index
1927     * @return row sense: E for =, L for <=, G for >= and R for ranged row
1928     **/
1929COINLIBAPI char COINLINKAGE
1930Osi_getRowSense(void *osi, int row)
1931{
1932  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1933
1934  return osiSolver->getRowSense()[row];
1935}
1936
1937COINLIBAPI void COINLINKAGE
1938OsiCuts_addRowCut( void *osiCuts, int nz, const int *idx, const double *coef, char sense, double rhs )
1939{
1940  sense = toupper(sense);
1941  OsiCuts *oc = (OsiCuts *) osiCuts;
1942
1943  OsiRowCut orc;
1944  orc.setRow( nz, idx, coef );
1945
1946
1947  orc.setLb(-DBL_MAX);
1948  orc.setUb(DBL_MAX);
1949
1950  switch (toupper(sense)) {
1951  case '=':
1952    orc.setLb(rhs);
1953    orc.setUb(rhs);
1954    break;
1955  case 'E':
1956    orc.setLb(rhs);
1957    orc.setUb(rhs);
1958    break;
1959  case '<':
1960    orc.setUb(rhs);
1961    break;
1962  case 'L':
1963    orc.setUb(rhs);
1964    break;
1965  case '>':
1966    orc.setLb(rhs);
1967    break;
1968  case 'G':
1969    orc.setLb(rhs);
1970    break;
1971  default:
1972    fprintf(stderr, "unknow row sense %c.", toupper(sense));
1973    abort();
1974  }
1975
1976  oc->insert(orc);
1977}
1978
1979
1980
1981/** @brief Returns solution vector in OsiSolverInterface object */
1982COINLIBAPI const double * COINLINKAGE
1983Osi_getColSolution( void *osi )
1984{
1985  OsiSolverInterface *osiSolver = (OsiSolverInterface *) osi;
1986
1987  return osiSolver->getColSolution();
1988}
1989
1990COINLIBAPI double COINLINKAGE
1991Cbc_getAllowableGap(Cbc_Model* model)
1992{
1993  return model->model_->getAllowableGap();
1994}
1995
1996COINLIBAPI void COINLINKAGE
1997Cbc_setAllowableGap(Cbc_Model* model, double allowedGap)
1998{
1999  model->model_->setAllowableGap(allowedGap);
2000}
2001
2002COINLIBAPI double COINLINKAGE
2003Cbc_getAllowableFractionGap(Cbc_Model* model)
2004{
2005  return model->model_->getAllowableFractionGap();
2006}
2007
2008COINLIBAPI void COINLINKAGE
2009Cbc_setAllowableFractionGap(Cbc_Model* model, double allowedFracionGap)
2010{
2011  model->model_->setAllowableFractionGap(allowedFracionGap);
2012}
2013
2014/** returns the maximum number of nodes that can be explored in the search tree
2015 */
2016COINLIBAPI int COINLINKAGE
2017Cbc_getMaximumNodes(Cbc_Model *model)
2018{
2019  return model->model_->getMaximumNodes();
2020}
2021
2022/** sets the maximum number of nodes that can be explored in the search tree
2023 */
2024COINLIBAPI void COINLINKAGE
2025Cbc_setMaximumNodes(Cbc_Model *model, int maxNodes)
2026{
2027  model->model_->setMaximumNodes(maxNodes);
2028}
2029
2030/** returns solution limit for the search process
2031 */
2032COINLIBAPI int COINLINKAGE
2033Cbc_getMaximumSolutions(Cbc_Model *model)
2034{
2035  return model->model_->getMaximumSolutions();
2036}
2037
2038/** sets a solution limit as a stopping criterion
2039 */
2040COINLIBAPI void COINLINKAGE
2041Cbc_setMaximumSolutions(Cbc_Model *model, int maxSolutions)
2042{
2043  model->model_->setMaximumSolutions(maxSolutions);
2044}
2045
2046/** returns the current log leven
2047 */
2048COINLIBAPI int COINLINKAGE
2049Cbc_getLogLevel(Cbc_Model *model)
2050{
2051  return model->model_->logLevel();
2052}
2053
2054/** sets the log level
2055 */
2056COINLIBAPI void COINLINKAGE
2057Cbc_setLogLevel(Cbc_Model *model, int logLevel)
2058{
2059  model->model_->setLogLevel(logLevel);
2060}
2061
2062
2063
2064COINLIBAPI double COINLINKAGE
2065Cbc_getCutoff(Cbc_Model* model)
2066{
2067  return model->model_->getCutoff();
2068}
2069
2070COINLIBAPI void COINLINKAGE
2071Cbc_setCutoff(Cbc_Model* model, double cutoff)
2072{
2073  model->model_->setCutoff(cutoff);
2074}
2075
2076COINLIBAPI double COINLINKAGE
2077Cbc_getAllowablePercentageGap(Cbc_Model* model)
2078{
2079  return model->model_->getAllowablePercentageGap();
2080}
2081
2082COINLIBAPI void COINLINKAGE
2083Cbc_setAllowablePercentageGap(Cbc_Model* model,
2084    double allowedPercentageGap)
2085{
2086  model->model_->setAllowablePercentageGap(allowedPercentageGap);
2087}
2088
2089COINLIBAPI double COINLINKAGE
2090Cbc_getMaximumSeconds(Cbc_Model *model)
2091{
2092  return model->model_->getMaximumSeconds();
2093}
2094
2095COINLIBAPI void COINLINKAGE
2096Cbc_setMaximumSeconds(Cbc_Model *model, double maxSeconds)
2097{
2098  model->model_->setMaximumSeconds(maxSeconds);
2099}
2100
2101COINLIBAPI void COINLINKAGE
2102Cbc_storeNameIndexes(Cbc_Model *model, char _store)
2103{
2104  if (_store)
2105  {
2106    if (model->colNameIndex==NULL)
2107    {
2108      assert(model->rowNameIndex==NULL);
2109      model->colNameIndex = new NameIndex();
2110      model->rowNameIndex = new NameIndex();
2111    }
2112  }
2113  else
2114  {
2115    if (model->colNameIndex!=NULL)
2116    {
2117      NameIndex *m = (NameIndex *)model->colNameIndex;
2118      delete m;
2119      m = (NameIndex *)model->rowNameIndex;
2120      assert( m != NULL );
2121      delete m;
2122
2123      model->colNameIndex = model->rowNameIndex = NULL;
2124    }
2125  }
2126}
2127
2128COINLIBAPI int COINLINKAGE
2129Cbc_getColNameIndex(Cbc_Model *model, const char *name)
2130{
2131  if (!model->colNameIndex)
2132  {
2133    fprintf(stderr, "Call Cbc_storeNameIndex to enable name index search.");
2134    abort();
2135  }
2136
2137  OsiSolverInterface *solver = model->model_->solver();
2138  NameIndex &colNameIndex = *((NameIndex  *)model->colNameIndex);
2139  NameIndex::iterator it = colNameIndex.find(std::string(name));
2140  if (it == colNameIndex.end())
2141    return -1;
2142
2143  return it->second;
2144}
2145
2146COINLIBAPI int COINLINKAGE
2147Cbc_getRowNameIndex(Cbc_Model *model, const char *name)
2148{
2149  if (!model->rowNameIndex)
2150  {
2151    fprintf(stderr, "Call Cbc_storeNameIndex to enable name index search.");
2152    abort();
2153  }
2154
2155  OsiSolverInterface *solver = model->model_->solver();
2156  NameIndex &rowNameIndex = *((NameIndex  *)model->rowNameIndex);
2157  NameIndex::iterator it = rowNameIndex.find(std::string(name));
2158  if (it == rowNameIndex.end())
2159    return -1;
2160
2161  return it->second;
2162}
2163
2164
2165#if defined(__MWERKS__)
2166#pragma export off
2167#endif
2168
2169/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
2170*/
Note: See TracBrowser for help on using the repository browser.