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

Last change on this file since 2039 was 2039, checked in by mlubin, 4 years ago

reenable SOS code

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.8 KB
Line 
1// $Id: Cbc_C_Interface.cpp 2039 2014-06-20 02:34:45Z 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 <cmath>
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
36#define CbcSetSolverProperty(T,prop) \
37COINLIBAPI void COINLINKAGE \
38Cbc_ ## prop (Cbc_Model *m, int index, T val) \
39{ \
40    m->model_->solver()->prop(index,val); \
41}
42
43const int  VERBOSE = 0;
44
45// To allow call backs
46class Cbc_MessageHandler
47            : public CoinMessageHandler {
48
49public:
50    /**@name Overrides */
51    //@{
52    virtual int print();
53    //@}
54    /**@name set and get */
55    //@{
56    /// Model
57    const Cbc_Model * model() const;
58    void setModel(Cbc_Model * model);
59    /// Call back
60    void setCallBack(cbc_callback callback);
61    //@}
62
63    /**@name Constructors, destructor */
64    //@{
65    /** Default constructor. */
66    Cbc_MessageHandler();
67    /// Constructor with pointer to model
68    Cbc_MessageHandler(Cbc_Model * model,
69                       FILE * userPointer = NULL);
70    /** Destructor */
71    virtual ~Cbc_MessageHandler();
72    //@}
73
74    /**@name Copy method */
75    //@{
76    /** The copy constructor. */
77    Cbc_MessageHandler(const Cbc_MessageHandler&);
78    /** The copy constructor from an CoinSimplexMessageHandler. */
79    Cbc_MessageHandler(const CoinMessageHandler&);
80
81    Cbc_MessageHandler& operator=(const Cbc_MessageHandler&);
82    /// Clone
83    virtual CoinMessageHandler * clone() const ;
84    //@}
85
86
87protected:
88    /**@name Data members
89       The data members are protected to allow access for derived classes. */
90    //@{
91    /// Pointer back to model
92    Cbc_Model * model_;
93    /// call back
94    cbc_callback callback_;
95    //@}
96};
97
98
99//-------------------------------------------------------------------
100// Default Constructor
101//-------------------------------------------------------------------
102Cbc_MessageHandler::Cbc_MessageHandler ()
103        : CoinMessageHandler(),
104        model_(NULL),
105        callback_(NULL)
106{
107}
108
109//-------------------------------------------------------------------
110// Copy constructor
111//-------------------------------------------------------------------
112Cbc_MessageHandler::Cbc_MessageHandler (const Cbc_MessageHandler & rhs)
113        : CoinMessageHandler(rhs),
114        model_(rhs.model_),
115        callback_(rhs.callback_)
116{
117}
118
119Cbc_MessageHandler::Cbc_MessageHandler (const CoinMessageHandler & rhs)
120        : CoinMessageHandler(rhs),
121        model_(NULL),
122        callback_(NULL)
123{
124}
125
126// Constructor with pointer to model
127Cbc_MessageHandler::Cbc_MessageHandler(Cbc_Model * model,
128                                       FILE * /*userPointer*/)
129        : CoinMessageHandler(),
130        model_(model),
131        callback_(NULL)
132{
133}
134
135//-------------------------------------------------------------------
136// Destructor
137//-------------------------------------------------------------------
138Cbc_MessageHandler::~Cbc_MessageHandler ()
139{
140}
141
142//----------------------------------------------------------------
143// Assignment operator
144//-------------------------------------------------------------------
145Cbc_MessageHandler &
146Cbc_MessageHandler::operator=(const Cbc_MessageHandler & rhs)
147{
148    if (this != &rhs) {
149        CoinMessageHandler::operator=(rhs);
150        model_ = rhs.model_;
151        callback_ = rhs.callback_;
152    }
153    return *this;
154}
155//-------------------------------------------------------------------
156// Clone
157//-------------------------------------------------------------------
158CoinMessageHandler * Cbc_MessageHandler::clone() const
159{
160    return new Cbc_MessageHandler(*this);
161}
162int
163Cbc_MessageHandler::print()
164{
165    if (callback_) {
166        int messageNumber = currentMessage().externalNumber();
167        if (currentSource() != "Cbc")
168            messageNumber += 1000000;
169        int i;
170        int nDouble = numberDoubleFields();
171        assert (nDouble <= 200);
172        double vDouble[200];
173        for (i = 0; i < nDouble; i++)
174            vDouble[i] = doubleValue(i);
175        int nInt = numberIntFields();
176        assert (nInt <= 200);
177        int vInt[200];
178        for (i = 0; i < nInt; i++)
179            vInt[i] = intValue(i);
180        int nString = numberStringFields();
181        assert (nString <= 200);
182        char * vString[200];
183        for (i = 0; i < nString; i++) {
184            std::string value = stringValue(i);
185            vString[i] = CoinStrdup(value.c_str());
186        }
187        callback_(model_, messageNumber,
188                  nDouble, vDouble,
189                  nInt, vInt,
190                  nString, vString);
191        for (i = 0; i < nString; i++)
192            free(vString[i]);
193
194    }
195    return CoinMessageHandler::print();
196    return 0;
197}
198const Cbc_Model *
199Cbc_MessageHandler::model() const
200{
201    return model_;
202}
203void
204Cbc_MessageHandler::setModel(Cbc_Model * model)
205{
206    model_ = model;
207}
208// Call back
209void
210Cbc_MessageHandler::setCallBack(cbc_callback callback)
211{
212    callback_ = callback;
213}
214/**
215  *
216  *  C Interface Routines
217  *
218  */
219#include "Cbc_C_Interface.h"
220#include <string>
221#include <stdio.h>
222#include <iostream>
223
224#if defined(__MWERKS__)
225#pragma export on
226#endif
227
228/* Version */
229COINLIBAPI const char* COINLINKAGE Cbc_getVersion()
230{
231    return CBC_VERSION;
232}
233
234/* Default Cbc_Model constructor */
235COINLIBAPI Cbc_Model *  COINLINKAGE
236Cbc_newModel()
237{
238    const char prefix[] = "Cbc_C_Interface::Cbc_newModel(): ";
239//  const int  VERBOSE = 1;
240    if (VERBOSE > 0) printf("%s begin\n", prefix);
241
242    Cbc_Model * model = new Cbc_Model();
243    OsiClpSolverInterface solver1;
244    model->solver_    = &solver1;
245    model->model_     = new CbcModel(solver1);
246    CbcMain0(*model->model_);
247    model->handler_   = NULL;
248
249    if (VERBOSE > 0) printf("%s return\n", prefix);
250    return model;
251}
252/* Cbc_Model Destructor */
253COINLIBAPI void COINLINKAGE
254Cbc_deleteModel(Cbc_Model * model)
255{
256    const char prefix[] = "Cbc_C_Interface::Cbc_deleteModel(): ";
257//  const int  VERBOSE = 1;
258    if (VERBOSE > 0) printf("%s begin\n", prefix);
259    fflush(stdout);
260
261    if (VERBOSE > 1) printf("%s delete model->model_\n", prefix);
262    fflush(stdout);
263    delete model->model_;
264
265    if (VERBOSE > 1) printf("%s delete model->handler_\n", prefix);
266    fflush(stdout);
267    delete model->handler_;
268
269    if (VERBOSE > 1) printf("%s delete model\n", prefix);
270    fflush(stdout);
271    delete model;
272
273    if (VERBOSE > 0) printf("%s return\n", prefix);
274    fflush(stdout);
275}
276
277/* Loads a problem (the constraints on the
278    rows are given by lower and upper bounds). If a pointer is NULL then the
279    following values are the default:
280    <ul>
281    <li> <code>colub</code>: all columns have upper bound infinity
282    <li> <code>collb</code>: all columns have lower bound 0
283    <li> <code>rowub</code>: all rows have upper bound infinity
284    <li> <code>rowlb</code>: all rows have lower bound -infinity
285    <li> <code>obj</code>: all variables have 0 objective coefficient
286    </ul>
287
288   Just like the other loadProblem() method except that the matrix is
289   given in a standard column major ordered format (without gaps).
290*/
291COINLIBAPI void COINLINKAGE
292Cbc_loadProblem (Cbc_Model * model,  const int numcols, const int numrows,
293                 const CoinBigIndex * start, const int* index,
294                 const double* value,
295                 const double* collb, const double* colub,
296                 const double* obj,
297                 const double* rowlb, const double* rowub)
298{
299    const char prefix[] = "Cbc_C_Interface::Cbc_loadProblem(): ";
300//  const int  VERBOSE = 2;
301    if (VERBOSE > 0) printf("%s begin\n", prefix);
302
303    OsiSolverInterface * solver = model->model_->solver();
304
305    if (VERBOSE > 1) {
306        printf("%s numcols = %i, numrows = %i\n",
307               prefix, numcols, numrows);
308        printf("%s model = %p, start = %p, index = %p, value = %p\n",
309               prefix, static_cast<void*>(model), static_cast<const void*>(start),
310               static_cast<const void*>(index), static_cast<const void*>(value));
311        printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
312               prefix, static_cast<const void*>(collb),
313               static_cast<const void*>(colub), static_cast<const void*>(obj),
314               static_cast<const void*>(rowlb), static_cast<const void*>(rowub));
315    }
316
317    if (VERBOSE > 1) printf("%s Calling solver->loadProblem()\n", prefix);
318    fflush(stdout);
319
320    solver->loadProblem(numcols, numrows, start, index, value,
321                        collb, colub, obj, rowlb, rowub);
322    if (VERBOSE > 1) printf("%s Finished solver->loadProblem()\n", prefix);
323    fflush(stdout);
324
325    if (VERBOSE > 0) printf("%s return\n", prefix);
326} //  Cbc_loadProblem()
327
328/* Read an mps file from the given filename */
329COINLIBAPI int COINLINKAGE
330Cbc_readMps(Cbc_Model * model, const char *filename)
331{
332    const char prefix[] = "Cbc_C_Interface::Cbc_readMps(): ";
333//  const int  VERBOSE = 2;
334    if (VERBOSE > 0) printf("%s begin\n", prefix);
335    if (VERBOSE > 1) printf("%s filename = '%s'\n", prefix, filename);
336
337    int result = 1;
338    result = model->model_->solver()->readMps(filename);
339    assert(result == 0);
340
341    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
342    return result;
343}
344/* Write an mps file from the given filename */
345COINLIBAPI void COINLINKAGE
346Cbc_writeMps(Cbc_Model * model, const char *filename)
347{
348    const char prefix[] = "Cbc_C_Interface::Cbc_writeMps(): ";
349//  const int  VERBOSE = 2;
350    if (VERBOSE > 0) printf("%s begin\n", prefix);
351    if (VERBOSE > 1) printf("%s filename = '%s'\n", prefix, filename);
352
353    model->model_->solver()->writeMps(filename, "mps", Cbc_getObjSense(model));
354
355    if (VERBOSE > 0) printf("%s return\n", prefix);
356    return;
357}
358
359
360COINLIBAPI void COINLINKAGE
361Cbc_setInitialSolution(Cbc_Model *model, const double * sol)
362{
363    int n = Cbc_getNumCols(model);
364    // We need to manually compute the objective here for some reason
365    const double *objvec = Cbc_getObjCoefficients(model);
366    double objval = 0;
367    for (int i = 0; i < n; i++) {
368        objval += objvec[i]*sol[i];
369    }
370    model->model_->setBestSolution(sol, n, objval, true);
371}
372
373COINLIBAPI void COINLINKAGE
374Cbc_setParameter(Cbc_Model * model, const char * name, const char * value)
375{
376    model->cmdargs_.push_back(std::string("-")+name);
377    model->cmdargs_.push_back(value);
378}
379
380/* Fills in array with problem name  */
381COINLIBAPI void COINLINKAGE
382Cbc_problemName(Cbc_Model * model, int maxNumberCharacters, char * array)
383{
384    std::string name;
385    model->model_->solver()->getStrParam(OsiProbName, name);
386    strncpy(array, name.c_str(), maxNumberCharacters);
387}
388/* Sets problem name.  Must have \0 at end.  */
389COINLIBAPI int COINLINKAGE
390Cbc_setProblemName(Cbc_Model * model, const char * array)
391{
392    bool result = false;
393    result = model->model_->solver()->setStrParam(OsiProbName, array);
394
395    return (result) ? 1 : 0;
396}
397
398CbcGetProperty(int, status)
399
400CbcGetProperty(int, secondaryStatus)
401
402/* Number of elements in matrix */
403COINLIBAPI int COINLINKAGE
404Cbc_getNumElements(Cbc_Model * model)
405{
406    const char prefix[] = "Cbc_C_Interface::Cbc_getNumElements(): ";
407//  const int  VERBOSE = 1;
408    if (VERBOSE > 0) printf("%s begin\n", prefix);
409
410    int result = 0;
411    result = model->model_->getNumElements();
412
413    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
414    return result;
415}
416
417// Column starts in matrix
418COINLIBAPI const CoinBigIndex * COINLINKAGE
419Cbc_getVectorStarts(Cbc_Model * model)
420{
421    const CoinPackedMatrix * matrix = NULL;
422    matrix = model->model_->solver()->getMatrixByCol();
423    return (matrix == NULL) ? NULL : matrix->getVectorStarts();
424}
425// Row indices in matrix
426COINLIBAPI const int * COINLINKAGE
427Cbc_getIndices(Cbc_Model * model)
428{
429    const char prefix[] = "Cbc_C_Interface::Cbc_getIndices(): ";
430//  const int  VERBOSE = 1;
431    if (VERBOSE > 0) printf("%s begin\n", prefix);
432
433    const int * result = NULL;
434    const CoinPackedMatrix * matrix = NULL;
435    matrix = model->model_->solver()->getMatrixByCol();
436    result = (matrix == NULL) ? NULL : matrix->getIndices();
437
438    if (VERBOSE > 0)
439        printf("%s return %p\n", prefix, static_cast<const void*>(result));
440    return result;
441}
442
443
444// Element values in matrix
445COINLIBAPI const double * COINLINKAGE
446Cbc_getElements(Cbc_Model * model)
447{
448    const char prefix[] = "Cbc_C_Interface::Cbc_getElements(): ";
449//  const int  VERBOSE = 1;
450    if (VERBOSE > 0) printf("%s begin\n", prefix);
451
452    const double * result = NULL;
453    const CoinPackedMatrix * matrix = NULL;
454    matrix = model->model_->solver()->getMatrixByCol();
455    result = (matrix == NULL) ? NULL : matrix->getElements();
456
457    if (VERBOSE > 0)
458        printf("%s return %p\n", prefix, static_cast<const void*>(result));
459    return result;
460}
461// ======================================================================
462
463
464
465/* Pass in Callback function */
466COINLIBAPI void COINLINKAGE
467Cbc_registerCallBack(Cbc_Model * model,
468                     cbc_callback userCallBack)
469{
470    const char prefix[] = "Cbc_C_Interface::Cbc_registerCallBack(): ";
471//  const int  VERBOSE = 1;
472    if (VERBOSE > 0) printf("%s begin\n", prefix);
473
474    // Will be copy of users one
475    delete model->handler_;
476    model->handler_ = new Cbc_MessageHandler(*(model->model_->messageHandler()));
477    model->handler_->setCallBack(userCallBack);
478    model->handler_->setModel(model);
479    model->model_->passInMessageHandler(model->handler_);
480
481    if (VERBOSE > 0) printf("%s return\n", prefix);
482}
483/* Unset Callback function */
484COINLIBAPI void COINLINKAGE
485Cbc_clearCallBack(Cbc_Model * model)
486{
487    const char prefix[] = "Cbc_C_Interface::Cbc_clearCallBack(): ";
488//  const int  VERBOSE = 1;
489    if (VERBOSE > 0) printf("%s begin\n", prefix);
490
491    delete model->handler_;
492    model->handler_ = NULL;
493
494    if (VERBOSE > 0) printf("%s return\n", prefix);
495}
496/* length of names (0 means no names0 */
497COINLIBAPI size_t COINLINKAGE
498Cbc_maxNameLength(Cbc_Model * model)
499{
500    size_t result = 0;
501    OsiSolverInterface::OsiNameVec const & rownames = model->model_->solver()->getRowNames();
502    for (size_t i = 0; i < rownames.size(); i++) {
503        if (rownames[i].length() > result) result = rownames[i].length();
504    }
505    OsiSolverInterface::OsiNameVec const & colnames = model->model_->solver()->getColNames();
506    for (size_t i = 0; i < colnames.size(); i++) {
507        if (colnames[i].length() > result) result = colnames[i].length();
508    }
509    return result;
510}
511COINLIBAPI void COINLINKAGE
512Cbc_getRowName(Cbc_Model * model, int iRow, char * name, size_t maxLength)
513{
514    std::string rowname = model->model_->solver()->getRowName(iRow);
515    strncpy(name, rowname.c_str(), maxLength);
516    name[maxLength-1] = '\0';
517}
518COINLIBAPI void COINLINKAGE
519Cbc_getColName(Cbc_Model * model, int iRow, char * name, size_t maxLength)
520{
521    std::string colname = model->model_->solver()->getColName(iRow);
522    strncpy(name, colname.c_str(), maxLength);
523    name[maxLength-1] = '\0';
524}
525
526COINLIBAPI void COINLINKAGE
527Cbc_setColName(Cbc_Model * model, int iColumn, const char * name)
528{
529    model->model_->solver()->setColName(iColumn, name);
530}
531
532COINLIBAPI void COINLINKAGE
533Cbc_setRowName(Cbc_Model * model, int iRow, const char * name)
534{
535    model->model_->solver()->setRowName(iRow, name);
536}
537
538
539COINLIBAPI int COINLINKAGE
540Cbc_solve(Cbc_Model * model)
541{
542    const char prefix[] = "Cbc_C_Interface::Cbc_solve(): ";
543    int result = 0;
544    std::vector<const char*> argv;
545    argv.push_back("Cbc_C_Interface");
546    for (size_t i = 0; i < model->cmdargs_.size(); i++) {
547        argv.push_back(model->cmdargs_[i].c_str());
548    }
549    argv.push_back("-solve");
550    argv.push_back("-quit");
551    try {
552       
553        CbcMain1((int)argv.size(), &argv[0], *model->model_);
554    } catch (CoinError e) {
555        printf("%s ERROR: %s::%s, %s\n", prefix,
556               e.className().c_str(), e.methodName().c_str(), e.message().c_str());
557    }
558    result = model->model_->status();
559
560    return result;
561}
562
563/* Sum of primal infeasibilities */
564COINLIBAPI double COINLINKAGE
565Cbc_sumPrimalInfeasibilities(Cbc_Model * /*model*/)
566{
567    const char prefix[] = "Cbc_C_Interface::Cbc_sumPrimalInfeasibilities(): ";
568//  const int  VERBOSE = 1;
569    if (VERBOSE > 0) printf("%s begin\n", prefix);
570
571    double result = 0;
572// cannot find names in Cbc, Osi, or OsiClp
573//tbd result = model->model_->sumPrimalInfeasibilities();
574    if (VERBOSE > 0) printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
575
576    if (VERBOSE > 0) printf("%s return %g\n", prefix, result);
577    return result;
578}
579/* Number of primal infeasibilities */
580COINLIBAPI int COINLINKAGE
581Cbc_numberPrimalInfeasibilities(Cbc_Model * /*model*/)
582{
583    const char prefix[] = "Cbc_C_Interface::Cbc_numberPrimalInfeasibilities(): ";
584//  const int  VERBOSE = 1;
585    if (VERBOSE > 0) printf("%s begin\n", prefix);
586
587    int result = 0;
588//tbd  result = model->model_->getContinuousInfeasibilities();
589    if (VERBOSE > 0) printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
590
591    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
592    return result;
593}
594
595
596/** Call this to really test if a valid solution can be feasible
597    Solution is number columns in size.
598    If fixVariables true then bounds of continuous solver updated.
599    Returns objective value (worse than cutoff if not feasible)
600*/
601COINLIBAPI void COINLINKAGE
602Cbc_checkSolution(Cbc_Model * /*model*/)
603{
604    const char prefix[] = "Cbc_C_Interface::Cbc_checkSolution(): ";
605//  const int  VERBOSE = 1;
606    if (VERBOSE > 0) printf("%s begin\n", prefix);
607
608    // see CbcModel::checkSolution(double cutoff, const double * solution,
609    //         bool fixVariables);
610//  model->model_->checkSolution();
611
612    if (VERBOSE > 0) printf("%s return\n", prefix);
613    return;
614}
615
616
617
618CbcGetProperty(int, getNumCols)
619CbcGetProperty(int, getNumRows)
620CbcGetProperty(int, getIterationCount)
621CbcGetProperty(int, isAbandoned)
622CbcGetProperty(int, isProvenOptimal)
623CbcGetProperty(int, isProvenInfeasible)
624CbcGetProperty(int, isContinuousUnbounded)
625CbcGetProperty(int, isNodeLimitReached)
626CbcGetProperty(int, isSecondsLimitReached)
627CbcGetProperty(int, isSolutionLimitReached)
628CbcGetProperty(int, isInitialSolveAbandoned)
629CbcGetProperty(int, isInitialSolveProvenOptimal)
630CbcGetProperty(int, isInitialSolveProvenPrimalInfeasible)
631
632CbcGetProperty(double, getObjSense)
633
634COINLIBAPI void COINLINKAGE
635Cbc_setObjSense(Cbc_Model * model, double sense)
636{
637    model->model_->setObjSense(sense);
638}
639
640CbcGetProperty(const double*, getRowActivity)
641CbcGetProperty(const double*, getColSolution)
642
643CbcGetProperty(const double*, getRowLower)
644CbcSetSolverProperty(double, setRowLower)
645CbcGetProperty(const double*, getRowUpper)
646CbcSetSolverProperty(double, setRowUpper)
647CbcGetProperty(const double*, getObjCoefficients)
648CbcSetSolverProperty(double, setObjCoeff)
649CbcGetProperty(const double*, getColLower)
650CbcSetSolverProperty(double, setColLower)
651CbcGetProperty(const double*, getColUpper)
652CbcSetSolverProperty(double, setColUpper)
653
654CbcGetProperty(double, getObjValue)
655CbcGetProperty(double, getBestPossibleObjValue)
656
657/* Print model */
658COINLIBAPI void COINLINKAGE
659Cbc_printModel(Cbc_Model * model, const char * argPrefix)
660{
661    const char prefix[] = "Cbc_C_Interface::Cbc_printModel(): ";
662    const int  VERBOSE = 4;
663    if (VERBOSE > 0) printf("%s begin\n", prefix);
664
665    CbcModel *cbc_model = model->model_;
666    int numrows    = cbc_model->getNumRows();
667    int numcols    = cbc_model->getNumCols();
668    int numelem    = cbc_model->getNumElements();
669    const CoinPackedMatrix * matrix = cbc_model->solver()->getMatrixByCol();
670    const CoinBigIndex     * start  = matrix->getVectorStarts();
671    const int              * index  = matrix->getIndices();
672    const double           * value  = matrix->getElements();
673    const double           * collb  = cbc_model->getColLower();
674    const double           * colub  = cbc_model->getColUpper();
675    const double           * obj    = cbc_model->getObjCoefficients();
676    const double           * rowlb  = cbc_model->getRowLower();
677    const double           * rowub  = cbc_model->getRowUpper();
678
679    printf("%s numcols = %i, numrows = %i, numelem = %i\n",
680           argPrefix, numcols, numrows, numelem);
681    printf("%s model = %p, start = %p, index = %p, value = %p\n",
682           argPrefix, static_cast<void*>(model), static_cast<const void*>(start),
683           static_cast<const void*>(index), static_cast<const void*>(value));
684    matrix->dumpMatrix(NULL);
685    {
686        int i;
687        for (i = 0; i <= numcols; i++)
688            printf("%s start[%i] = %i\n", argPrefix, i, start[i]);
689        for (i = 0; i < numelem; i++)
690            printf("%s index[%i] = %i, value[%i] = %g\n",
691                   argPrefix, i, index[i], i, value[i]);
692    }
693
694    printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
695           argPrefix, static_cast<const void*>(collb),
696           static_cast<const void*>(colub), static_cast<const void*>(obj),
697           static_cast<const void*>(rowlb), static_cast<const void*>(rowub));
698    printf("%s optimization direction = %g\n", argPrefix, Cbc_getObjSense(model));
699    printf("  (1 - minimize, -1 - maximize, 0 - ignore)\n");
700    {
701        int i;
702        for (i = 0; i < numcols; i++)
703            printf("%s collb[%i] = %g, colub[%i] = %g, obj[%i] = %g\n",
704                   argPrefix, i, collb[i], i, colub[i], i, obj[i]);
705        for (i = 0; i < numrows; i++)
706            printf("%s rowlb[%i] = %g, rowub[%i] = %g\n",
707                   argPrefix, i, rowlb[i], i, rowub[i]);
708    }
709
710    if (VERBOSE > 0) printf("%s return\n", prefix);
711}  // Cbc_printModel()
712
713COINLIBAPI int COINLINKAGE
714Cbc_isInteger(Cbc_Model * model, int i)
715{
716    const char prefix[] = "Cbc_C_Interface::Cbc_isInteger(): ";
717//  const int  VERBOSE = 1;
718    if (VERBOSE > 0) printf("%s begin\n", prefix);
719
720    bool result = false;
721    result = model->model_->isInteger(i);
722
723    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
724    return (result) ? 1 : 0;
725}
726
727CbcGetProperty(int, getNodeCount)
728
729/** Return a copy of this model */
730COINLIBAPI Cbc_Model * COINLINKAGE
731Cbc_clone(Cbc_Model * model)
732{
733    const char prefix[] = "Cbc_C_Interface::Cbc_clone(): ";
734//  const int  VERBOSE = 1;
735    if (VERBOSE > 0) printf("%s begin\n", prefix);
736
737    Cbc_Model * result = new Cbc_Model();
738    result->model_     = new CbcModel(*(model->model_));
739    result->solver_    = dynamic_cast< OsiClpSolverInterface*> (result->model_->solver());
740    result->handler_   = NULL;
741    result->cmdargs_   = model->cmdargs_;
742
743    if (VERBOSE > 0) printf("%s return\n", prefix);
744    return model;
745}
746/** Set this the variable to be continuous */
747COINLIBAPI void COINLINKAGE
748Cbc_setContinuous(Cbc_Model * model, int iColumn)
749{
750    const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
751//  const int  VERBOSE = 1;
752    if (VERBOSE > 0) printf("%s begin\n", prefix);
753
754    model->model_->solver()->setContinuous(iColumn);
755
756    if (VERBOSE > 0) printf("%s return\n", prefix);
757}
758/** Set this the variable to be integer */
759COINLIBAPI void COINLINKAGE
760Cbc_setInteger(Cbc_Model * model, int iColumn)
761{
762    const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
763//  const int  VERBOSE = 1;
764    if (VERBOSE > 0) printf("%s begin\n", prefix);
765
766    model->model_->solver()->setInteger(iColumn);
767
768    if (VERBOSE > 0) printf("%s return\n", prefix);
769}
770/** Add SOS constraints to the model using row-order matrix */
771
772COINLIBAPI void  COINLINKAGE
773Cbc_addSOS(Cbc_Model * model, int numRows, const int * rowStarts,
774           const int * colIndices, const double * weights, const int type)
775{
776    const char prefix[] = "Cbc_C_Interface::Cbc_addSOS(): ";
777  //const int  VERBOSE = 4;
778    if (VERBOSE > 0) printf("%sbegin\n", prefix);
779
780    if (VERBOSE > 0) printf("%s numRows = %i\n", prefix, numRows);
781
782    int row, i;
783    const int *colIndex;
784    const double *colWeight;
785
786    // loop on rows and count number of objects according to numWeights>0
787    int numObjects = 0;
788    for (row = 0; row < numRows; row++) {
789        if (VERBOSE > 2) {
790            printf("%s row = %i\n", prefix, row);
791            printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
792            printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row+1]);
793            fflush(stdout);
794        }
795        const int numWeights = rowStarts[row+1] - rowStarts[row];
796        if (VERBOSE > 2) printf("%s  numWeights = %i\n", prefix, numWeights);
797        if (numWeights > 0) numObjects++;
798    }
799
800    // make objects
801    CbcObject ** objects = new CbcObject * [numObjects];
802//  if (VERBOSE>1) printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
803
804    // loop on rows and make an object when numWeights>0
805    int objNum = 0;
806    for (row = 0; row < numRows; row++) {
807        if (VERBOSE > 2) {
808            printf("%s row = %i\n", prefix, row);
809            printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
810            printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row+1]);
811        }
812        const int numWeights = rowStarts[row+1] - rowStarts[row];
813        if (VERBOSE > 2) printf("%s  numWeights = %i\n", prefix, numWeights);
814        colIndex    = colIndices + rowStarts[row];
815        colWeight   = weights + rowStarts[row];
816        if (numWeights > 0) {
817            // Make a CbcSOS and assign it to objects
818            if (VERBOSE > 3) {
819                for (i = 0; i < numWeights; i++) {
820                    printf("%s  colIndex [%i] = %i\n", prefix, i, colIndex[i]);
821                    printf("%s  colWeight[%i] = %f\n", prefix, i, colWeight[i]);
822                }
823                fflush(stdout);
824            }
825            objects[objNum] = new CbcSOS(model->model_, (int)(numWeights),
826                                         (const int*)colIndex, (const double*)colWeight, (int)objNum, (int)type);
827//      if (VERBOSE>2) printf("%s objects[%i] = %X\n",prefix,objNum,objects[objNum]);
828            if (objects[objNum] == NULL) {
829                printf("%s ERROR: objects[%i] == NULL\n", prefix, objNum);
830                fflush(stdout);
831                assert(objects[objNum] != NULL);
832            }
833            objNum++;
834        }
835    }
836    if (VERBOSE > 2) {
837        printf("%s calling addObjects()\n", prefix);
838       
839        //    printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
840        //    for (row=0; row<numObjects; row++)
841        //      printf("%s  objects[%i] = %X\n",prefix,row,objects[row]);
842       
843    }
844    fflush(stdout);
845    model->model_->addObjects(numObjects, objects);
846    if (VERBOSE > 1) printf("%s finished addObjects()\n", prefix);
847
848    for (objNum = 0; objNum < numObjects; objNum++) delete objects[objNum];
849    delete [] objects;
850
851    if (VERBOSE > 0) printf("%sreturn\n", prefix);
852    return;
853}
854
855/** Print the solution */
856COINLIBAPI void  COINLINKAGE
857Cbc_printSolution(Cbc_Model * model)
858{
859    {
860        //
861        //  Now to print out row solution.  The methods used return const
862        //  pointers - which is of course much more virtuous.
863        //
864        //  This version just does non-zero columns
865        //
866
867        // * Rows
868
869        int numberRows = Cbc_getNumRows(model);
870        int iRow;
871
872
873        const double * rowPrimal = Cbc_getRowActivity(model);
874        const double * rowLower = Cbc_getRowLower(model);
875        const double * rowUpper = Cbc_getRowUpper(model);
876        printf("--------------------------------------\n");
877
878        // * If we have not kept names (parameter to readMps) this will be 0
879        //    assert(Cbc_lengthNames(model));
880
881        printf("                       Primal          Lower         Upper\n");
882        for (iRow = 0; iRow < numberRows; iRow++) {
883            double value;
884            value = rowPrimal[iRow];
885            if (value > 1.0e-8 || value < -1.0e-8) {
886                char name[20];
887                //              Cbc_columnName(model,iColumn,name);
888                sprintf(name, "ROW%5i", iRow);
889                printf("%6d %8s", iRow, name);
890                printf(" %13g", rowPrimal[iRow]);
891                printf(" %13g", rowLower[iRow]);
892                printf(" %13g", rowUpper[iRow]);
893                printf("\n");
894            }
895        }
896        printf("--------------------------------------\n");
897    }
898    {
899        //
900        //  Now to print out column solution.  The methods used return const
901        //  pointers - which is of course much more virtuous.
902        //
903        //  This version just does non-zero columns
904        //
905        //
906
907        // * Columns
908
909        int numberColumns = Cbc_getNumCols(model);
910        int iColumn;
911
912
913        const double * columnPrimal = Cbc_getColSolution(model);
914        const double * columnLower = Cbc_getColLower(model);
915        const double * columnUpper = Cbc_getColUpper(model);
916        const double * columnObjective = Cbc_getObjCoefficients(model);
917
918        printf("--------------------------------------\n");
919
920        // * If we have not kept names (parameter to readMps) this will be 0
921//    assert(Cbc_lengthNames(model));
922
923        printf("                       Primal          Lower         Upper          Cost     isInteger\n");
924        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
925            double value;
926            value = columnPrimal[iColumn];
927            if (value > 1.0e-8 || value < -1.0e-8) {
928                char name[20];
929//              Cbc_columnName(model,iColumn,name);
930                sprintf(name, "COL%5i", iColumn);
931                printf("%6d %8s", iColumn, name);
932                printf(" %13g", columnPrimal[iColumn]);
933                printf(" %13g", columnLower[iColumn]);
934                printf(" %13g", columnUpper[iColumn]);
935                printf(" %13g", columnObjective[iColumn]);
936                printf(" %13i", Cbc_isInteger(model,iColumn));
937                printf("\n");
938            }
939        }
940        printf("--------------------------------------\n");
941    }
942    if (0) Cbc_printModel(model, "cbc::main(): ");
943    return;
944}
945
946#if defined(__MWERKS__)
947#pragma export off
948#endif
949
Note: See TracBrowser for help on using the repository browser.