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

Last change on this file since 2019 was 2019, checked in by mlubin, 5 years ago

Major cleaning of C interface, more to come

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 38.9 KB
Line 
1// $Id: Cbc_C_Interface.cpp 2019 2014-03-11 21:10:15Z mlubin $
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 <math.h>
7#include <cfloat>
8
9#include "CoinPragma.hpp"
10//#include "CoinHelperFunctions.hpp"
11//#include "CoinPackedMatrix.hpp"
12#include "CoinTime.hpp"
13
14#include "CbcModel.hpp"
15#include "CbcBranchActual.hpp"
16
17#include "CoinMessageHandler.hpp"
18#include "OsiClpSolverInterface.hpp"
19
20//  bobe including extras.h to get strdup()
21#if defined(__MWERKS__)
22// #include <extras.h>  // bobe 06-02-14
23#endif
24
25// Get C stuff but with extern C
26#define CBC_EXTERN_C
27#include "Coin_C_defines.h"
28
29#define CbcGetProperty(T,prop) \
30COINLIBAPI T COINLINKAGE \
31Cbc_ ## prop (Cbc_Model *m) \
32{ \
33    return m->model_->prop(); \
34}
35
36const int  VERBOSE = 0;
37
38// To allow call backs
39class Cbc_MessageHandler
40            : public CoinMessageHandler {
41
42public:
43    /**@name Overrides */
44    //@{
45    virtual int print();
46    //@}
47    /**@name set and get */
48    //@{
49    /// Model
50    const Cbc_Model * model() const;
51    void setModel(Cbc_Model * model);
52    /// Call back
53    void setCallBack(cbc_callback callback);
54    //@}
55
56    /**@name Constructors, destructor */
57    //@{
58    /** Default constructor. */
59    Cbc_MessageHandler();
60    /// Constructor with pointer to model
61    Cbc_MessageHandler(Cbc_Model * model,
62                       FILE * userPointer = NULL);
63    /** Destructor */
64    virtual ~Cbc_MessageHandler();
65    //@}
66
67    /**@name Copy method */
68    //@{
69    /** The copy constructor. */
70    Cbc_MessageHandler(const Cbc_MessageHandler&);
71    /** The copy constructor from an CoinSimplexMessageHandler. */
72    Cbc_MessageHandler(const CoinMessageHandler&);
73
74    Cbc_MessageHandler& operator=(const Cbc_MessageHandler&);
75    /// Clone
76    virtual CoinMessageHandler * clone() const ;
77    //@}
78
79
80protected:
81    /**@name Data members
82       The data members are protected to allow access for derived classes. */
83    //@{
84    /// Pointer back to model
85    Cbc_Model * model_;
86    /// call back
87    cbc_callback callback_;
88    //@}
89};
90
91
92//-------------------------------------------------------------------
93// Default Constructor
94//-------------------------------------------------------------------
95Cbc_MessageHandler::Cbc_MessageHandler ()
96        : CoinMessageHandler(),
97        model_(NULL),
98        callback_(NULL)
99{
100}
101
102//-------------------------------------------------------------------
103// Copy constructor
104//-------------------------------------------------------------------
105Cbc_MessageHandler::Cbc_MessageHandler (const Cbc_MessageHandler & rhs)
106        : CoinMessageHandler(rhs),
107        model_(rhs.model_),
108        callback_(rhs.callback_)
109{
110}
111
112Cbc_MessageHandler::Cbc_MessageHandler (const CoinMessageHandler & rhs)
113        : CoinMessageHandler(rhs),
114        model_(NULL),
115        callback_(NULL)
116{
117}
118
119// Constructor with pointer to model
120Cbc_MessageHandler::Cbc_MessageHandler(Cbc_Model * model,
121                                       FILE * /*userPointer*/)
122        : CoinMessageHandler(),
123        model_(model),
124        callback_(NULL)
125{
126}
127
128//-------------------------------------------------------------------
129// Destructor
130//-------------------------------------------------------------------
131Cbc_MessageHandler::~Cbc_MessageHandler ()
132{
133}
134
135//----------------------------------------------------------------
136// Assignment operator
137//-------------------------------------------------------------------
138Cbc_MessageHandler &
139Cbc_MessageHandler::operator=(const Cbc_MessageHandler & rhs)
140{
141    if (this != &rhs) {
142        CoinMessageHandler::operator=(rhs);
143        model_ = rhs.model_;
144        callback_ = rhs.callback_;
145    }
146    return *this;
147}
148//-------------------------------------------------------------------
149// Clone
150//-------------------------------------------------------------------
151CoinMessageHandler * Cbc_MessageHandler::clone() const
152{
153    return new Cbc_MessageHandler(*this);
154}
155int
156Cbc_MessageHandler::print()
157{
158    if (callback_) {
159        int messageNumber = currentMessage().externalNumber();
160        if (currentSource() != "Cbc")
161            messageNumber += 1000000;
162        int i;
163        int nDouble = numberDoubleFields();
164        assert (nDouble <= 200);
165        double vDouble[200];
166        for (i = 0; i < nDouble; i++)
167            vDouble[i] = doubleValue(i);
168        int nInt = numberIntFields();
169        assert (nInt <= 200);
170        int vInt[200];
171        for (i = 0; i < nInt; i++)
172            vInt[i] = intValue(i);
173        int nString = numberStringFields();
174        assert (nString <= 200);
175        char * vString[200];
176        for (i = 0; i < nString; i++) {
177            std::string value = stringValue(i);
178            vString[i] = CoinStrdup(value.c_str());
179        }
180        callback_(model_, messageNumber,
181                  nDouble, vDouble,
182                  nInt, vInt,
183                  nString, vString);
184        for (i = 0; i < nString; i++)
185            free(vString[i]);
186
187    }
188    return CoinMessageHandler::print();
189    return 0;
190}
191const Cbc_Model *
192Cbc_MessageHandler::model() const
193{
194    return model_;
195}
196void
197Cbc_MessageHandler::setModel(Cbc_Model * model)
198{
199    model_ = model;
200}
201// Call back
202void
203Cbc_MessageHandler::setCallBack(cbc_callback callback)
204{
205    callback_ = callback;
206}
207/**
208  *
209  *  C Interface Routines
210  *
211  */
212#include "Cbc_C_Interface.h"
213#include <string>
214#include <stdio.h>
215#include <iostream>
216
217#if defined(__MWERKS__)
218#pragma export on
219#endif
220
221/* Version */
222COINLIBAPI double COINLINKAGE Cbc_getVersion()
223{
224    double v = 1.0;
225    return v;
226}
227
228/* Default Cbc_Model constructor */
229COINLIBAPI Cbc_Model *  COINLINKAGE
230Cbc_newModel()
231{
232    const char prefix[] = "Cbc_C_Interface::Cbc_newModel(): ";
233//  const int  VERBOSE = 1;
234    if (VERBOSE > 0) printf("%s begin\n", prefix);
235
236    Cbc_Model * model = new Cbc_Model();
237    OsiClpSolverInterface solver1;
238    model->solver_    = &solver1;
239    model->solver_->OsiClpSolverInterface::setHintParam(OsiDoReducePrint, true, OsiHintTry);
240    model->model_     = new CbcModel(solver1);
241    CbcMain0(*model->model_);
242    model->handler_   = NULL;
243
244    if (VERBOSE > 0) printf("%s return\n", prefix);
245    return model;
246}
247/* Cbc_Model Destructor */
248COINLIBAPI void COINLINKAGE
249Cbc_deleteModel(Cbc_Model * model)
250{
251    const char prefix[] = "Cbc_C_Interface::Cbc_deleteModel(): ";
252//  const int  VERBOSE = 1;
253    if (VERBOSE > 0) printf("%s begin\n", prefix);
254    fflush(stdout);
255
256    if (VERBOSE > 1) printf("%s delete model->model_\n", prefix);
257    fflush(stdout);
258    delete model->model_;
259
260    if (VERBOSE > 1) printf("%s delete model->handler_\n", prefix);
261    fflush(stdout);
262    delete model->handler_;
263
264    if (VERBOSE > 1) printf("%s delete model\n", prefix);
265    fflush(stdout);
266    delete model;
267
268    if (VERBOSE > 0) printf("%s return\n", prefix);
269    fflush(stdout);
270}
271
272/* Loads a problem (the constraints on the
273    rows are given by lower and upper bounds). If a pointer is NULL then the
274    following values are the default:
275    <ul>
276    <li> <code>colub</code>: all columns have upper bound infinity
277    <li> <code>collb</code>: all columns have lower bound 0
278    <li> <code>rowub</code>: all rows have upper bound infinity
279    <li> <code>rowlb</code>: all rows have lower bound -infinity
280    <li> <code>obj</code>: all variables have 0 objective coefficient
281    </ul>
282
283   Just like the other loadProblem() method except that the matrix is
284   given in a standard column major ordered format (without gaps).
285*/
286COINLIBAPI void COINLINKAGE
287Cbc_loadProblem (Cbc_Model * model,  const int numcols, const int numrows,
288                 const CoinBigIndex * start, const int* index,
289                 const double* value,
290                 const double* collb, const double* colub,
291                 const double* obj,
292                 const double* rowlb, const double* rowub)
293{
294    const char prefix[] = "Cbc_C_Interface::Cbc_loadProblem(): ";
295//  const int  VERBOSE = 2;
296    if (VERBOSE > 0) printf("%s begin\n", prefix);
297
298    OsiSolverInterface * solver = model->model_->solver();
299
300    if (VERBOSE > 1) {
301        printf("%s numcols = %i, numrows = %i\n",
302               prefix, numcols, numrows);
303        printf("%s model = %p, start = %p, index = %p, value = %p\n",
304               prefix, static_cast<void*>(model), static_cast<const void*>(start),
305               static_cast<const void*>(index), static_cast<const void*>(value));
306        printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
307               prefix, static_cast<const void*>(collb),
308               static_cast<const void*>(colub), static_cast<const void*>(obj),
309               static_cast<const void*>(rowlb), static_cast<const void*>(rowub));
310    }
311
312    if (VERBOSE > 1) printf("%s Calling solver->loadProblem()\n", prefix);
313    fflush(stdout);
314
315    solver->loadProblem(numcols, numrows, start, index, value,
316                        collb, colub, obj, rowlb, rowub);
317    if (VERBOSE > 1) printf("%s Finished solver->loadProblem()\n", prefix);
318    fflush(stdout);
319
320    if (VERBOSE > 0) printf("%s return\n", prefix);
321} //  Cbc_loadProblem()
322
323/* Read an mps file from the given filename */
324COINLIBAPI int COINLINKAGE
325Cbc_readMps(Cbc_Model * model, const char *filename)
326{
327    const char prefix[] = "Cbc_C_Interface::Cbc_readMps(): ";
328//  const int  VERBOSE = 2;
329    if (VERBOSE > 0) printf("%s begin\n", prefix);
330    if (VERBOSE > 1) printf("%s filename = '%s'\n", prefix, filename);
331
332    int result = 1;
333    result = model->model_->solver()->readMps(filename);
334    assert(result == 0);
335
336    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
337    return result;
338}
339/* Write an mps file from the given filename */
340COINLIBAPI void COINLINKAGE
341Cbc_writeMps(Cbc_Model * model, const char *filename)
342{
343    const char prefix[] = "Cbc_C_Interface::Cbc_writeMps(): ";
344//  const int  VERBOSE = 2;
345    if (VERBOSE > 0) printf("%s begin\n", prefix);
346    if (VERBOSE > 1) printf("%s filename = '%s'\n", prefix, filename);
347
348    model->model_->solver()->writeMps(filename, "mps", Cbc_getObjSense(model));
349
350    if (VERBOSE > 0) printf("%s return\n", prefix);
351    return;
352}
353
354/* Deletes rows */
355COINLIBAPI void COINLINKAGE
356Cbc_deleteRows(Cbc_Model * model, int number, const int * which)
357{
358    const char prefix[] = "Cbc_C_Interface::Cbc_deleteRows(): ";
359    if (VERBOSE > 0) printf("%s begin\n", prefix);
360
361    OsiSolverInterface * solver = model->model_->solver();
362    solver->deleteRows(number, which);
363
364    if (VERBOSE > 0) printf("%s return\n", prefix);
365}
366/* Add rows */
367COINLIBAPI void COINLINKAGE
368Cbc_addRows(Cbc_Model * /*model*/, const int /*number*/,
369            const double * /*rowLower*/,
370            const double * /*rowUpper*/,
371            const int * /*rowStarts*/, const int * /*columns*/,
372            const double * /*elements*/)
373{
374    const char prefix[] = "Cbc_C_Interface::Cbc_addRows(): ";
375    if (VERBOSE > 0) printf("%s begin\n", prefix);
376
377// available through OsiClp
378//tbd  model->model_->addRows(number,rowLower,rowUpper,rowStarts,columns,elements);
379    if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);
380
381    if (VERBOSE > 0) printf("%s return\n", prefix);
382}
383
384/* Deletes columns */
385COINLIBAPI void COINLINKAGE
386Cbc_deleteColumns(Cbc_Model * model, int number, const int * which)
387{
388    const char prefix[] = "Cbc_C_Interface::Cbc_deleteColumns(): ";
389//  const int  VERBOSE = 1;
390    if (VERBOSE > 0) printf("%s begin\n", prefix);
391
392    OsiSolverInterface * solver = model->model_->solver();
393    solver->deleteCols(number, which);
394
395    if (VERBOSE > 0) printf("%s return\n", prefix);
396}
397/* Add columns */
398COINLIBAPI void COINLINKAGE
399Cbc_addColumns(Cbc_Model * /*model*/, int /*number*/,
400               const double * /*columnLower*/,
401               const double * /*columnUpper*/,
402               const double * /*objective*/,
403               const int * /*columnStarts*/, const int * /*rows*/,
404               const double * /*elements*/)
405{
406    const char prefix[] = "Cbc_C_Interface::Cbc_addColumns(): ";
407//  const int  VERBOSE = 1;
408    if (VERBOSE > 0) printf("%s begin\n", prefix);
409
410// available through OsiClp
411//tbd  model->model_->addColumns(number,columnLower,columnUpper,objective,
412//tbd                       columnStarts,rows,elements);
413    if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);
414
415    if (VERBOSE > 0) printf("%s return\n", prefix);
416}
417/* Drops names - makes lengthnames 0 and names empty */
418COINLIBAPI void COINLINKAGE
419Cbc_dropNames(Cbc_Model * /*model*/)
420{
421    const char prefix[] = "Cbc_C_Interface::Cbc_dropNames(): ";
422//  const int  VERBOSE = 1;
423    if (VERBOSE > 0) printf("%s begin\n", prefix);
424
425// cannot find names in Cbc, Osi, or OsiClp
426//tbd  model->model_->dropNames();
427    if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);
428
429    if (VERBOSE > 0) printf("%s return\n", prefix);
430}
431/* Copies in names */
432COINLIBAPI void COINLINKAGE
433Cbc_copyNames(Cbc_Model * /*model*/, const char * const * /*rowNamesIn*/,
434              const char * const * /*columnNamesIn*/)
435{
436    const char prefix[] = "Cbc_C_Interface::Cbc_copyNames(): ";
437//  const int  VERBOSE = 1;
438    if (VERBOSE > 0) printf("%s begin\n", prefix);
439
440// cannot find names in Cbc, Osi, or OsiClp
441    /*clean
442      int iRow;
443      std::vector<std::string> rowNames;
444      int numberRows = model->model_->getNumRows();
445      rowNames.reserve(numberRows);
446      for (iRow=0;iRow<numberRows;iRow++) {
447        rowNames.push_back(rowNamesIn[iRow]);
448      }
449
450      int iColumn;
451      std::vector<std::string> columnNames;
452      int numberColumns = model->model_->getNumCols();
453      columnNames.reserve(numberColumns);
454      for (iColumn=0;iColumn<numberColumns;iColumn++) {
455        columnNames.push_back(columnNamesIn[iColumn]);
456      }
457      model->model_->copyNames(rowNames,columnNames);
458    */
459
460    if (VERBOSE > 0) printf("%s return\n", prefix);
461}
462
463/* Objective offset */
464COINLIBAPI double COINLINKAGE
465Cbc_objectiveOffset(Cbc_Model * /*model*/)
466{
467    const char prefix[] = "Cbc_C_Interface::Cbc_objectiveOffset(): ";
468//  const int  VERBOSE = 1;
469    if (VERBOSE > 0) printf("%s begin\n", prefix);
470
471    double result = 0.0;
472// cannot find names in Cbc, Osi, or OsiClp
473//tbd  return model->model_->objectiveOffset();
474    if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);
475
476    if (VERBOSE > 0) printf("%s return %g\n", prefix, result);
477    return result;
478}
479COINLIBAPI void COINLINKAGE
480Cbc_setObjectiveOffset(Cbc_Model * /*model*/, double /*value*/)
481{
482    const char prefix[] = "Cbc_C_Interface::Cbc_setObjectiveOffset(): ";
483//  const int  VERBOSE = 1;
484    if (VERBOSE > 0) printf("%s begin\n", prefix);
485
486// cannot find names in Cbc, Osi, or OsiClp
487//tbd  model->model_->solver()->setObjectiveOffset(value);
488    if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);
489
490    if (VERBOSE > 0) printf("%s return\n", prefix);
491}
492/* Fills in array with problem name  */
493COINLIBAPI void COINLINKAGE
494Cbc_problemName(Cbc_Model * model, int maxNumberCharacters, char * array)
495{
496    const char prefix[] = "Cbc_C_Interface::Cbc_problemName(): ";
497//  const int  VERBOSE = 1;
498    if (VERBOSE > 0) printf("%s begin\n", prefix);
499
500    std::string name;
501    model->model_->solver()->getStrParam(OsiProbName, name);
502    maxNumberCharacters = CoinMin(maxNumberCharacters, (int)strlen(name.c_str()));
503    strncpy(array, name.c_str(), maxNumberCharacters - 1);
504    array[maxNumberCharacters-1] = '\0';
505
506    if (VERBOSE > 0) printf("%s return\n", prefix);
507}
508/* Sets problem name.  Must have \0 at end.  */
509COINLIBAPI int COINLINKAGE
510Cbc_setProblemName(Cbc_Model * model, int /*maxNumberCharacters*/, char * array)
511{
512    const char prefix[] = "Cbc_C_Interface::Cbc_setProblemName(): ";
513//  const int  VERBOSE = 1;
514    if (VERBOSE > 0) printf("%s begin\n", prefix);
515
516    bool result = false;
517    result = model->model_->solver()->setStrParam(OsiProbName, array);
518
519    if (VERBOSE > 0) printf("%s return\n", prefix);
520    return (result) ? 1 : 0;
521}
522/* Status of problem:
523   0 - optimal
524   1 - primal infeasible
525   2 - dual infeasible
526   3 - stopped on iterations etc
527   4 - stopped due to errors
528*/
529CbcGetProperty(int, status)
530
531/* Secondary status of problem - may get extended
532   0 - none
533   1 - primal infeasible because dual limit reached
534   2 - scaled problem optimal - unscaled has primal infeasibilities
535   3 - scaled problem optimal - unscaled has dual infeasibilities
536   4 - scaled problem optimal - unscaled has both dual and primal infeasibilities
537*/
538CbcGetProperty(int, secondaryStatus)
539
540COINLIBAPI void COINLINKAGE
541Cbc_setSecondaryStatus(Cbc_Model * /*model*/, int /*status*/)
542{
543    const char prefix[] = "Cbc_C_Interface::Cbc_setSecondaryStatus(): ";
544//  const int  VERBOSE = 1;
545    if (VERBOSE > 0) printf("%s begin\n", prefix);
546
547// cannot find this in Cbc, Osi, or OsiClp
548//tbd  model->model_->setSecondaryStatus(status);
549    if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);
550
551    if (VERBOSE > 0) printf("%s return\n", prefix);
552}
553
554/* Number of elements in matrix */
555COINLIBAPI int COINLINKAGE
556Cbc_getNumElements(Cbc_Model * model)
557{
558    const char prefix[] = "Cbc_C_Interface::Cbc_getNumElements(): ";
559//  const int  VERBOSE = 1;
560    if (VERBOSE > 0) printf("%s begin\n", prefix);
561
562    int result = 0;
563    result = model->model_->getNumElements();
564
565    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
566    return result;
567}
568
569// Column starts in matrix
570COINLIBAPI const CoinBigIndex * COINLINKAGE
571Cbc_getVectorStarts(Cbc_Model * model)
572{
573    const CoinPackedMatrix * matrix = NULL;
574    matrix = model->model_->solver()->getMatrixByCol();
575    return (matrix == NULL) ? NULL : matrix->getVectorStarts();
576}
577// Row indices in matrix
578COINLIBAPI const int * COINLINKAGE
579Cbc_getIndices(Cbc_Model * model)
580{
581    const char prefix[] = "Cbc_C_Interface::Cbc_getIndices(): ";
582//  const int  VERBOSE = 1;
583    if (VERBOSE > 0) printf("%s begin\n", prefix);
584
585    const int * result = NULL;
586    const CoinPackedMatrix * matrix = NULL;
587    matrix = model->model_->solver()->getMatrixByCol();
588    result = (matrix == NULL) ? NULL : matrix->getIndices();
589
590    if (VERBOSE > 0)
591        printf("%s return %p\n", prefix, static_cast<const void*>(result));
592    return result;
593}
594
595// Column vector lengths in matrix
596COINLIBAPI const int * COINLINKAGE
597Cbc_getVectorLengths(Cbc_Model * model)
598{
599    const char prefix[] = "Cbc_C_Interface::Cbc_getVectorLengths(): ";
600//  const int  VERBOSE = 1;
601    if (VERBOSE > 0) printf("%s begin\n", prefix);
602
603    const int * result = NULL;
604    const CoinPackedMatrix * matrix = NULL;
605    matrix = model->model_->solver()->getMatrixByCol();
606    result = (matrix == NULL) ? NULL : matrix->getVectorLengths();
607
608    if (VERBOSE > 0)
609        printf("%s return %p\n", prefix, static_cast<const void*>(result));
610    return result;
611}
612
613// Element values in matrix
614COINLIBAPI const double * COINLINKAGE
615Cbc_getElements(Cbc_Model * model)
616{
617    const char prefix[] = "Cbc_C_Interface::Cbc_getElements(): ";
618//  const int  VERBOSE = 1;
619    if (VERBOSE > 0) printf("%s begin\n", prefix);
620
621    const double * result = NULL;
622    const CoinPackedMatrix * matrix = NULL;
623    matrix = model->model_->solver()->getMatrixByCol();
624    result = (matrix == NULL) ? NULL : matrix->getElements();
625
626    if (VERBOSE > 0)
627        printf("%s return %p\n", prefix, static_cast<const void*>(result));
628    return result;
629}
630// ======================================================================
631
632
633
634/* Pass in Callback function */
635COINLIBAPI void COINLINKAGE
636Cbc_registerCallBack(Cbc_Model * model,
637                     cbc_callback userCallBack)
638{
639    const char prefix[] = "Cbc_C_Interface::Cbc_registerCallBack(): ";
640//  const int  VERBOSE = 1;
641    if (VERBOSE > 0) printf("%s begin\n", prefix);
642
643    // reuse existing log level
644    int oldLogLevel = model->model_->messageHandler()->logLevel();
645    // Will be copy of users one
646    delete model->handler_;
647    model->handler_ = new Cbc_MessageHandler(*(model->model_->messageHandler()));
648    model->handler_->setCallBack(userCallBack);
649    model->handler_->setModel(model);
650    model->model_->passInMessageHandler(model->handler_);
651    model->model_->messageHandler()->setLogLevel(oldLogLevel);
652
653    if (VERBOSE > 0) printf("%s return\n", prefix);
654}
655/* Unset Callback function */
656COINLIBAPI void COINLINKAGE
657Cbc_clearCallBack(Cbc_Model * model)
658{
659    const char prefix[] = "Cbc_C_Interface::Cbc_clearCallBack(): ";
660//  const int  VERBOSE = 1;
661    if (VERBOSE > 0) printf("%s begin\n", prefix);
662
663    delete model->handler_;
664    model->handler_ = NULL;
665
666    if (VERBOSE > 0) printf("%s return\n", prefix);
667}
668/* length of names (0 means no names0 */
669COINLIBAPI int COINLINKAGE
670Cbc_lengthNames(Cbc_Model * /*model*/)
671{
672    const char prefix[] = "Cbc_C_Interface::Cbc_lengthNames(): ";
673//  const int  VERBOSE = 1;
674    if (VERBOSE > 0) printf("%s begin\n", prefix);
675
676    int result = 0;
677// cannot find names in Cbc, Osi, or OsiClp
678//tbd  result = model->model_->lengthNames();
679    if (VERBOSE > 0) printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
680
681    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
682    return result;
683}
684/* Fill in array (at least lengthNames+1 long) with a row name */
685COINLIBAPI void COINLINKAGE
686Cbc_rowName(Cbc_Model * /*model*/, int iRow, char * name)
687{
688    const char prefix[] = "Cbc_C_Interface::Cbc_rowName(): ";
689//  const int  VERBOSE = 1;
690    if (VERBOSE > 0) printf("%s begin\n", prefix);
691
692    sprintf(name, "ROW%5i", iRow);
693// cannot find names in Cbc, Osi, or OsiClp
694//tbd  std::string rowName=model->model_->rowName(iRow);
695//tbd  strcpy(name,rowName.c_str());
696
697    if (VERBOSE > 0) printf("%s return\n", prefix);
698}
699/* Fill in array (at least lengthNames+1 long) with a column name */
700// cannot find names in Cbc, Osi, or OsiClp
701COINLIBAPI void COINLINKAGE
702Cbc_columnName(Cbc_Model * /*model*/, int iColumn, char * name)
703{
704    const char prefix[] = "Cbc_C_Interface::Cbc_columnName(): ";
705//  const int  VERBOSE = 1;
706    if (VERBOSE > 0) printf("%s begin\n", prefix);
707
708    sprintf(name, "COL%5i", iColumn);
709//tbd  std::string columnName= model->model_->columnName(iColumn);
710//tbd  strcpy(name,columnName.c_str());
711
712    if (VERBOSE > 0) printf("%s return\n", prefix);
713}
714
715COINLIBAPI int COINLINKAGE
716Cbc_solve(Cbc_Model * model)
717{
718    const char prefix[] = "Cbc_C_Interface::Cbc_solve(): ";
719    int result = 0;
720    const char *argv[] = {"Cbc_C_Interface","-solve", "-quit"};
721    try {
722       
723        CbcMain1(3, argv, *model->model_);
724    } catch (CoinError e) {
725        printf("%s ERROR: %s::%s, %s\n", prefix,
726               e.className().c_str(), e.methodName().c_str(), e.message().c_str());
727    }
728    result = model->model_->status();
729
730    return result;
731}
732
733/* Sum of primal infeasibilities */
734COINLIBAPI double COINLINKAGE
735Cbc_sumPrimalInfeasibilities(Cbc_Model * /*model*/)
736{
737    const char prefix[] = "Cbc_C_Interface::Cbc_sumPrimalInfeasibilities(): ";
738//  const int  VERBOSE = 1;
739    if (VERBOSE > 0) printf("%s begin\n", prefix);
740
741    double result = 0;
742// cannot find names in Cbc, Osi, or OsiClp
743//tbd result = model->model_->sumPrimalInfeasibilities();
744    if (VERBOSE > 0) printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
745
746    if (VERBOSE > 0) printf("%s return %g\n", prefix, result);
747    return result;
748}
749/* Number of primal infeasibilities */
750COINLIBAPI int COINLINKAGE
751Cbc_numberPrimalInfeasibilities(Cbc_Model * /*model*/)
752{
753    const char prefix[] = "Cbc_C_Interface::Cbc_numberPrimalInfeasibilities(): ";
754//  const int  VERBOSE = 1;
755    if (VERBOSE > 0) printf("%s begin\n", prefix);
756
757    int result = 0;
758//tbd  result = model->model_->getContinuousInfeasibilities();
759    if (VERBOSE > 0) printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
760
761    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
762    return result;
763}
764
765
766/** Call this to really test if a valid solution can be feasible
767    Solution is number columns in size.
768    If fixVariables true then bounds of continuous solver updated.
769    Returns objective value (worse than cutoff if not feasible)
770*/
771COINLIBAPI void COINLINKAGE
772Cbc_checkSolution(Cbc_Model * /*model*/)
773{
774    const char prefix[] = "Cbc_C_Interface::Cbc_checkSolution(): ";
775//  const int  VERBOSE = 1;
776    if (VERBOSE > 0) printf("%s begin\n", prefix);
777
778    // see CbcModel::checkSolution(double cutoff, const double * solution,
779    //         bool fixVariables);
780//  model->model_->checkSolution();
781
782    if (VERBOSE > 0) printf("%s return\n", prefix);
783    return;
784}
785
786
787
788CbcGetProperty(int, getNumCols)
789CbcGetProperty(int, getNumRows)
790CbcGetProperty(int, getIterationCount)
791CbcGetProperty(int, isAbandoned)
792CbcGetProperty(int, isProvenOptimal)
793CbcGetProperty(int, isProvenInfeasible)
794CbcGetProperty(int, isContinuousUnbounded)
795CbcGetProperty(int, isNodeLimitReached)
796CbcGetProperty(int, isSecondsLimitReached)
797CbcGetProperty(int, isSolutionLimitReached)
798CbcGetProperty(int, isInitialSolveAbandoned)
799CbcGetProperty(int, isInitialSolveProvenOptimal)
800CbcGetProperty(int, isInitialSolveProvenPrimalInfeasible)
801
802CbcGetProperty(double, getObjSense)
803
804COINLIBAPI void COINLINKAGE
805Cbc_setObjSense(Cbc_Model * model, double sense)
806{
807    model->model_->setObjSense(sense);
808}
809
810CbcGetProperty(const double*, getRowActivity)
811CbcGetProperty(const double*, getColSolution)
812
813COINLIBAPI void COINLINKAGE
814Cbc_setColSolution(Cbc_Model * model, const double * input)
815{
816    const char prefix[] = "Cbc_C_Interface::Cbc_setColSolution(): ";
817//  const int  VERBOSE = 1;
818    if (VERBOSE > 0) printf("%s begin\n", prefix);
819
820    OsiSolverInterface * solver = model->model_->solver();
821    solver->setColSolution(input);
822
823    if (VERBOSE > 0) printf("%s return\n", prefix);
824    return;
825}
826
827CbcGetProperty(const double*, getRowLower)
828CbcGetProperty(const double*, getRowUpper)
829CbcGetProperty(const double*, getObjCoefficients)
830CbcGetProperty(const double*, getColLower)
831CbcGetProperty(const double*, getColUpper)
832
833CbcGetProperty(double, getObjValue)
834
835/* Print model */
836COINLIBAPI void COINLINKAGE
837Cbc_printModel(Cbc_Model * model, const char * argPrefix)
838{
839    const char prefix[] = "Cbc_C_Interface::Cbc_printModel(): ";
840    const int  VERBOSE = 4;
841    if (VERBOSE > 0) printf("%s begin\n", prefix);
842
843    CbcModel *cbc_model = model->model_;
844    int numrows    = cbc_model->getNumRows();
845    int numcols    = cbc_model->getNumCols();
846    int numelem    = cbc_model->getNumElements();
847    const CoinPackedMatrix * matrix = cbc_model->solver()->getMatrixByCol();
848    const CoinBigIndex     * start  = matrix->getVectorStarts();
849    const int              * index  = matrix->getIndices();
850    const double           * value  = matrix->getElements();
851    const double           * collb  = cbc_model->getColLower();
852    const double           * colub  = cbc_model->getColUpper();
853    const double           * obj    = cbc_model->getObjCoefficients();
854    const double           * rowlb  = cbc_model->getRowLower();
855    const double           * rowub  = cbc_model->getRowUpper();
856
857    printf("%s numcols = %i, numrows = %i, numelem = %i\n",
858           argPrefix, numcols, numrows, numelem);
859    printf("%s model = %p, start = %p, index = %p, value = %p\n",
860           argPrefix, static_cast<void*>(model), static_cast<const void*>(start),
861           static_cast<const void*>(index), static_cast<const void*>(value));
862    matrix->dumpMatrix(NULL);
863    {
864        int i;
865        for (i = 0; i <= numcols; i++)
866            printf("%s start[%i] = %i\n", argPrefix, i, start[i]);
867        for (i = 0; i < numelem; i++)
868            printf("%s index[%i] = %i, value[%i] = %g\n",
869                   argPrefix, i, index[i], i, value[i]);
870    }
871
872    printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
873           argPrefix, static_cast<const void*>(collb),
874           static_cast<const void*>(colub), static_cast<const void*>(obj),
875           static_cast<const void*>(rowlb), static_cast<const void*>(rowub));
876    printf("%s optimization direction = %g\n", argPrefix, Cbc_getObjSense(model));
877    printf("  (1 - minimize, -1 - maximize, 0 - ignore)\n");
878    {
879        int i;
880        for (i = 0; i < numcols; i++)
881            printf("%s collb[%i] = %g, colub[%i] = %g, obj[%i] = %g\n",
882                   argPrefix, i, collb[i], i, colub[i], i, obj[i]);
883        for (i = 0; i < numrows; i++)
884            printf("%s rowlb[%i] = %g, rowub[%i] = %g\n",
885                   argPrefix, i, rowlb[i], i, rowub[i]);
886    }
887
888    if (VERBOSE > 0) printf("%s return\n", prefix);
889}  // Cbc_printModel()
890
891COINLIBAPI int COINLINKAGE
892Cbc_isInteger(Cbc_Model * model, int i)
893{
894    const char prefix[] = "Cbc_C_Interface::Cbc_isInteger(): ";
895//  const int  VERBOSE = 1;
896    if (VERBOSE > 0) printf("%s begin\n", prefix);
897
898    bool result = false;
899    result = model->model_->isInteger(i);
900
901    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
902    return (result) ? 1 : 0;
903}
904
905COINLIBAPI double COINLINKAGE
906Cbc_cpuTime(Cbc_Model * /*model*/)
907{
908    const char prefix[] = "Cbc_C_Interface::Cbc_cpuTime(): ";
909//  const int  VERBOSE = 1;
910    if (VERBOSE > 0) printf("%s begin\n", prefix);
911
912    double result = 0;
913    result = CoinCpuTime() ;
914
915    if (VERBOSE > 0) printf("%s return %g\n", prefix, result);
916    return result;
917}
918
919CbcGetProperty(int, getNodeCount)
920
921/** Return a copy of this model */
922COINLIBAPI Cbc_Model * COINLINKAGE
923Cbc_clone(Cbc_Model * model)
924{
925    const char prefix[] = "Cbc_C_Interface::Cbc_clone(): ";
926//  const int  VERBOSE = 1;
927    if (VERBOSE > 0) printf("%s begin\n", prefix);
928
929    Cbc_Model * result = new Cbc_Model();
930    result->model_     = new CbcModel(*(model->model_));
931    result->solver_    = dynamic_cast< OsiClpSolverInterface*> (result->model_->solver());
932    result->handler_   = NULL;
933
934    if (VERBOSE > 0) printf("%s return\n", prefix);
935    return model;
936}
937/** Set this the variable to be continuous */
938COINLIBAPI Cbc_Model * COINLINKAGE
939Cbc_setContinuous(Cbc_Model * model, int iColumn)
940{
941    const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
942//  const int  VERBOSE = 1;
943    if (VERBOSE > 0) printf("%s begin\n", prefix);
944
945    model->model_->solver()->setContinuous(iColumn);
946
947    if (VERBOSE > 0) printf("%s return\n", prefix);
948    return model;
949}
950/** Set this the variable to be integer */
951COINLIBAPI Cbc_Model * COINLINKAGE
952Cbc_setInteger(Cbc_Model * model, int iColumn)
953{
954    const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
955//  const int  VERBOSE = 1;
956    if (VERBOSE > 0) printf("%s begin\n", prefix);
957
958    model->model_->solver()->setInteger(iColumn);
959
960    if (VERBOSE > 0) printf("%s return\n", prefix);
961    return model;
962}
963/* Add an SOS constraint to the model */
964COINLIBAPI void  COINLINKAGE
965Cbc_addSOS_Dense(Cbc_Model * model, int numObjects, const int * len,
966                 const int * const* which, const double * weights, const int type)
967{
968    const char prefix[] = "Cbc_C_Interface::Cbc_addSOS_Dense(): ";
969//  const int  VERBOSE = 2;
970    if (VERBOSE > 0) printf("%sbegin\n", prefix);
971
972    assert(1 > 0);// this is probably broken
973    int i, j;
974    // I think this is a different model due to overriding = operator
975    CbcModel m = *(model->model_);
976
977    CbcObject ** objects = new CbcObject * [numObjects];
978
979    if (VERBOSE > 1) printf("%s numObjects = %i\n", prefix, numObjects);
980    for (i = 0; i < numObjects; i++) {
981        if (VERBOSE > 1) {
982            printf("%s len[%i] = %i, identifier = %i, type = %i\n",
983                   prefix, i, len[i], i, type);
984            fflush(stdout);
985            for (j = 0; j < len[i]; j++) {
986                if (VERBOSE > 2 || j == 0 || j == (len[i] - 1)) {
987                    printf("%s which[%i][%i] = %d, weights[%i] = %g\n",
988                           prefix, i, j, which[i][j], j, weights[j]);
989                    fflush(stdout);
990                }
991            }
992        }
993
994        // Make a CbcSOS and assign it to objects
995        if (VERBOSE > 1) printf("%s len[%i] = %i\n", prefix, i, len[i]);
996        if (VERBOSE > 1) printf("%s new CbcSOS()\n", prefix);
997        // ***
998        objects[i] = new CbcSOS(model->model_, (int)(len[i]),
999                                (const int*)which[i], (const double*)weights, (int)i, (int)type);
1000        // ***
1001        if (objects[i] == NULL) {
1002            printf("%s ERROR: objects[%i] == NULL\n", prefix, i);
1003            fflush(stdout);
1004            assert(objects[i] != NULL);
1005        }
1006    }
1007    if (VERBOSE > 1) printf("%s calling addObjects()\n", prefix);
1008    fflush(stdout);
1009    model->model_->addObjects(numObjects, objects);
1010    if (VERBOSE > 1) printf("%s finished addObjects()\n", prefix);
1011
1012    for (i = 0; i < numObjects; i++) delete objects[i];
1013    delete [] objects;
1014
1015    if (VERBOSE > 0) printf("%sreturn\n", prefix);
1016    return;
1017}
1018/** Add SOS constraints to the model using row-order matrix */
1019COINLIBAPI void  COINLINKAGE
1020Cbc_addSOS_Sparse(Cbc_Model * model, const int * rowStarts,
1021                  const int * rowIndices, const double * weights, const int type)
1022{
1023    const char prefix[] = "Cbc_C_Interface::Cbc_addSOS_Sparse(): ";
1024//  const int  VERBOSE = 1;
1025    if (VERBOSE > 0) printf("%sbegin\n", prefix);
1026
1027    int numRows = Cbc_getNumRows(model);
1028    if (VERBOSE > 0) printf("%s numRows = %i\n", prefix, numRows);
1029
1030    // The passed sparse matrix must have the same number of rows as the model
1031    assert(numRows == Cbc_getNumRows(model));
1032
1033    int row, i;
1034    const int *colIndex;
1035    const double *colWeight;
1036
1037    // loop on rows and count number of objects according to numWeights>0
1038    int numObjects = 0;
1039    for (row = 0; row < numRows; row++) {
1040        if (VERBOSE > 2) {
1041            printf("%s row = %i\n", prefix, row);
1042            printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
1043            printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row+1]);
1044            fflush(stdout);
1045        }
1046        const int numWeights = rowStarts[row+1] - rowStarts[row];
1047        if (VERBOSE > 2) printf("%s  numWeights = %i\n", prefix, numWeights);
1048        if (numWeights > 0) numObjects++;
1049    }
1050
1051    // make objects
1052    CbcObject ** objects = new CbcObject * [numObjects];
1053//  if (VERBOSE>1) printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
1054
1055    // loop on rows and make an object when numWeights>0
1056    int objNum = 0;
1057    for (row = 0; row < numRows; row++) {
1058        if (VERBOSE > 2) {
1059            printf("%s row = %i\n", prefix, row);
1060            printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
1061            printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row+1]);
1062        }
1063        const int numWeights = rowStarts[row+1] - rowStarts[row];
1064        if (VERBOSE > 2) printf("%s  numWeights = %i\n", prefix, numWeights);
1065        colIndex    = rowIndices + rowStarts[row];
1066        colWeight   = weights + rowStarts[row];
1067        if (numWeights > 0) {
1068            // Make a CbcSOS and assign it to objects
1069            if (VERBOSE > 3) {
1070                for (i = 0; i < numWeights; i++) {
1071                    printf("%s  colIndex [%i] = %i\n", prefix, i, colIndex[i]);
1072                    printf("%s  colWeight[%i] = %f\n", prefix, i, colWeight[i]);
1073                }
1074                fflush(stdout);
1075            }
1076            objects[objNum] = new CbcSOS(model->model_, (int)(numWeights),
1077                                         (const int*)colIndex, (const double*)colWeight, (int)objNum, (int)type);
1078//      if (VERBOSE>2) printf("%s objects[%i] = %X\n",prefix,objNum,objects[objNum]);
1079            if (objects[objNum] == NULL) {
1080                printf("%s ERROR: objects[%i] == NULL\n", prefix, objNum);
1081                fflush(stdout);
1082                assert(objects[objNum] != NULL);
1083            }
1084            objNum++;
1085        }
1086    }
1087    if (VERBOSE > 2) {
1088        printf("%s calling addObjects()\n", prefix);
1089        /*
1090            printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
1091            for (row=0; row<numObjects; row++)
1092              printf("%s  objects[%i] = %X\n",prefix,row,objects[row]);
1093        */
1094    }
1095    fflush(stdout);
1096    model->model_->addObjects(numObjects, objects);
1097    if (VERBOSE > 1) printf("%s finished addObjects()\n", prefix);
1098
1099    for (objNum = 0; objNum < numObjects; objNum++) delete objects[objNum];
1100    delete [] objects;
1101
1102    if (VERBOSE > 0) printf("%sreturn\n", prefix);
1103    return;
1104}
1105
1106/** Delete all object information */
1107COINLIBAPI void  COINLINKAGE
1108Cbc_deleteObjects(Cbc_Model * model)
1109{
1110    const char prefix[] = "Cbc_C_Interface::Cbc_deleteObjects(): ";
1111//  const int  VERBOSE = 2;
1112    if (VERBOSE > 0) printf("%s begin\n", prefix);
1113
1114    model->model_->deleteObjects();
1115
1116    if (VERBOSE > 0) printf("%s return\n", prefix);
1117    return;
1118}
1119
1120/** Print the solution */
1121COINLIBAPI void  COINLINKAGE
1122Cbc_printSolution(Cbc_Model * model)
1123{
1124    {
1125        //
1126        //  Now to print out row solution.  The methods used return const
1127        //  pointers - which is of course much more virtuous.
1128        //
1129        //  This version just does non-zero columns
1130        //
1131
1132        // * Rows
1133
1134        int numberRows = Cbc_getNumRows(model);
1135        int iRow;
1136
1137
1138        const double * rowPrimal = Cbc_getRowActivity(model);
1139        const double * rowLower = Cbc_getRowLower(model);
1140        const double * rowUpper = Cbc_getRowUpper(model);
1141        printf("--------------------------------------\n");
1142
1143        // * If we have not kept names (parameter to readMps) this will be 0
1144        //    assert(Cbc_lengthNames(model));
1145
1146        printf("                       Primal          Lower         Upper\n");
1147        for (iRow = 0; iRow < numberRows; iRow++) {
1148            double value;
1149            value = rowPrimal[iRow];
1150            if (value > 1.0e-8 || value < -1.0e-8) {
1151                char name[20];
1152                //              Cbc_columnName(model,iColumn,name);
1153                sprintf(name, "ROW%5i", iRow);
1154                printf("%6d %8s", iRow, name);
1155                printf(" %13g", rowPrimal[iRow]);
1156                printf(" %13g", rowLower[iRow]);
1157                printf(" %13g", rowUpper[iRow]);
1158                printf("\n");
1159            }
1160        }
1161        printf("--------------------------------------\n");
1162    }
1163    {
1164        //
1165        //  Now to print out column solution.  The methods used return const
1166        //  pointers - which is of course much more virtuous.
1167        //
1168        //  This version just does non-zero columns
1169        //
1170        //
1171
1172        // * Columns
1173
1174        int numberColumns = Cbc_getNumCols(model);
1175        int iColumn;
1176
1177
1178        const double * columnPrimal = Cbc_getColSolution(model);
1179        const double * columnLower = Cbc_getColLower(model);
1180        const double * columnUpper = Cbc_getColUpper(model);
1181        const double * columnObjective = Cbc_getObjCoefficients(model);
1182
1183        printf("--------------------------------------\n");
1184
1185        // * If we have not kept names (parameter to readMps) this will be 0
1186//    assert(Cbc_lengthNames(model));
1187
1188        printf("                       Primal          Lower         Upper          Cost     isInteger\n");
1189        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1190            double value;
1191            value = columnPrimal[iColumn];
1192            if (value > 1.0e-8 || value < -1.0e-8) {
1193                char name[20];
1194//              Cbc_columnName(model,iColumn,name);
1195                sprintf(name, "COL%5i", iColumn);
1196                printf("%6d %8s", iColumn, name);
1197                printf(" %13g", columnPrimal[iColumn]);
1198                printf(" %13g", columnLower[iColumn]);
1199                printf(" %13g", columnUpper[iColumn]);
1200                printf(" %13g", columnObjective[iColumn]);
1201                printf(" %13i", Cbc_isInteger(model,iColumn));
1202                printf("\n");
1203            }
1204        }
1205        printf("--------------------------------------\n");
1206    }
1207    if (0) Cbc_printModel(model, "cbc::main(): ");
1208    return;
1209}
1210
1211#if defined(__MWERKS__)
1212#pragma export off
1213#endif
1214
Note: See TracBrowser for help on using the repository browser.