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

Last change on this file since 2494 was 2494, checked in by unxusr, 3 months ago

more functions to Cbc_C_interface

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