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

Last change on this file since 2572 was 2572, checked in by unxusr, 6 months ago

new functions in C API: Cbc_deleteRows and Cbc_deleteCols

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