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

Last change on this file since 2363 was 2363, checked in by forrest, 21 months ago

add readLp to C interface

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.3 KB
Line 
1// $Id: Cbc_C_Interface.cpp 2363 2018-02-14 11:21:56Z forrest $
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/* Read an lp file from the given filename */
359COINLIBAPI int COINLINKAGE
360Cbc_readLp(Cbc_Model * model, const char *filename)
361{
362    const char prefix[] = "Cbc_C_Interface::Cbc_readLp(): ";
363//  const int  VERBOSE = 2;
364    if (VERBOSE > 0) printf("%s begin\n", prefix);
365    if (VERBOSE > 1) printf("%s filename = '%s'\n", prefix, filename);
366    int result = 1;
367    result = model->model_->solver()->readLp(filename);
368    assert(result == 0);
369
370    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
371    return result;
372}
373
374
375COINLIBAPI void COINLINKAGE
376Cbc_setInitialSolution(Cbc_Model *model, const double * sol)
377{
378    int n = Cbc_getNumCols(model);
379    // We need to manually compute the objective here for some reason
380    const double *objvec = Cbc_getObjCoefficients(model);
381    double objval = 0;
382    for (int i = 0; i < n; i++) {
383        objval += objvec[i]*sol[i];
384    }
385    model->model_->setBestSolution(sol, n, objval, true);
386}
387
388COINLIBAPI void COINLINKAGE
389Cbc_setParameter(Cbc_Model * model, const char * name, const char * value)
390{
391    model->cmdargs_.push_back(std::string("-")+name);
392    model->cmdargs_.push_back(value);
393}
394
395/* Fills in array with problem name  */
396COINLIBAPI void COINLINKAGE
397Cbc_problemName(Cbc_Model * model, int maxNumberCharacters, char * array)
398{
399    std::string name;
400    model->model_->solver()->getStrParam(OsiProbName, name);
401    strncpy(array, name.c_str(), maxNumberCharacters);
402}
403/* Sets problem name.  Must have \0 at end.  */
404COINLIBAPI int COINLINKAGE
405Cbc_setProblemName(Cbc_Model * model, const char * array)
406{
407    bool result = false;
408    result = model->model_->solver()->setStrParam(OsiProbName, array);
409
410    return (result) ? 1 : 0;
411}
412
413CbcGetProperty(int, status)
414
415CbcGetProperty(int, secondaryStatus)
416
417/* Number of elements in matrix */
418COINLIBAPI int COINLINKAGE
419Cbc_getNumElements(Cbc_Model * model)
420{
421    const char prefix[] = "Cbc_C_Interface::Cbc_getNumElements(): ";
422//  const int  VERBOSE = 1;
423    if (VERBOSE > 0) printf("%s begin\n", prefix);
424
425    int result = 0;
426    result = model->model_->getNumElements();
427
428    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
429    return result;
430}
431
432// Column starts in matrix
433COINLIBAPI const CoinBigIndex * COINLINKAGE
434Cbc_getVectorStarts(Cbc_Model * model)
435{
436    const CoinPackedMatrix * matrix = NULL;
437    matrix = model->model_->solver()->getMatrixByCol();
438    return (matrix == NULL) ? NULL : matrix->getVectorStarts();
439}
440// Row indices in matrix
441COINLIBAPI const int * COINLINKAGE
442Cbc_getIndices(Cbc_Model * model)
443{
444    const char prefix[] = "Cbc_C_Interface::Cbc_getIndices(): ";
445//  const int  VERBOSE = 1;
446    if (VERBOSE > 0) printf("%s begin\n", prefix);
447
448    const int * result = NULL;
449    const CoinPackedMatrix * matrix = NULL;
450    matrix = model->model_->solver()->getMatrixByCol();
451    result = (matrix == NULL) ? NULL : matrix->getIndices();
452
453    if (VERBOSE > 0)
454        printf("%s return %p\n", prefix, static_cast<const void*>(result));
455    return result;
456}
457
458
459// Element values in matrix
460COINLIBAPI const double * COINLINKAGE
461Cbc_getElements(Cbc_Model * model)
462{
463    const char prefix[] = "Cbc_C_Interface::Cbc_getElements(): ";
464//  const int  VERBOSE = 1;
465    if (VERBOSE > 0) printf("%s begin\n", prefix);
466
467    const double * result = NULL;
468    const CoinPackedMatrix * matrix = NULL;
469    matrix = model->model_->solver()->getMatrixByCol();
470    result = (matrix == NULL) ? NULL : matrix->getElements();
471
472    if (VERBOSE > 0)
473        printf("%s return %p\n", prefix, static_cast<const void*>(result));
474    return result;
475}
476// ======================================================================
477
478
479
480/* Pass in Callback function */
481COINLIBAPI void COINLINKAGE
482Cbc_registerCallBack(Cbc_Model * model,
483                     cbc_callback userCallBack)
484{
485    const char prefix[] = "Cbc_C_Interface::Cbc_registerCallBack(): ";
486//  const int  VERBOSE = 1;
487    if (VERBOSE > 0) printf("%s begin\n", prefix);
488
489    // Will be copy of users one
490    delete model->handler_;
491    model->handler_ = new Cbc_MessageHandler(*(model->model_->messageHandler()));
492    model->handler_->setCallBack(userCallBack);
493    model->handler_->setModel(model);
494    model->model_->passInMessageHandler(model->handler_);
495
496    if (VERBOSE > 0) printf("%s return\n", prefix);
497}
498/* Unset Callback function */
499COINLIBAPI void COINLINKAGE
500Cbc_clearCallBack(Cbc_Model * model)
501{
502    const char prefix[] = "Cbc_C_Interface::Cbc_clearCallBack(): ";
503//  const int  VERBOSE = 1;
504    if (VERBOSE > 0) printf("%s begin\n", prefix);
505
506    delete model->handler_;
507    model->handler_ = NULL;
508
509    if (VERBOSE > 0) printf("%s return\n", prefix);
510}
511/* length of names (0 means no names0 */
512COINLIBAPI size_t COINLINKAGE
513Cbc_maxNameLength(Cbc_Model * model)
514{
515    size_t result = 0;
516    OsiSolverInterface::OsiNameVec const & rownames = model->model_->solver()->getRowNames();
517    for (size_t i = 0; i < rownames.size(); i++) {
518        if (rownames[i].length() > result) result = rownames[i].length();
519    }
520    OsiSolverInterface::OsiNameVec const & colnames = model->model_->solver()->getColNames();
521    for (size_t i = 0; i < colnames.size(); i++) {
522        if (colnames[i].length() > result) result = colnames[i].length();
523    }
524    return result;
525}
526COINLIBAPI void COINLINKAGE
527Cbc_getRowName(Cbc_Model * model, int iRow, char * name, size_t maxLength)
528{
529    std::string rowname = model->model_->solver()->getRowName(iRow);
530    strncpy(name, rowname.c_str(), maxLength);
531    name[maxLength-1] = '\0';
532}
533COINLIBAPI void COINLINKAGE
534Cbc_getColName(Cbc_Model * model, int iRow, char * name, size_t maxLength)
535{
536    std::string colname = model->model_->solver()->getColName(iRow);
537    strncpy(name, colname.c_str(), maxLength);
538    name[maxLength-1] = '\0';
539}
540
541COINLIBAPI void COINLINKAGE
542Cbc_setColName(Cbc_Model * model, int iColumn, const char * name)
543{
544    model->model_->solver()->setColName(iColumn, name);
545}
546
547COINLIBAPI void COINLINKAGE
548Cbc_setRowName(Cbc_Model * model, int iRow, const char * name)
549{
550    model->model_->solver()->setRowName(iRow, name);
551}
552
553
554COINLIBAPI int COINLINKAGE
555Cbc_solve(Cbc_Model * model)
556{
557    const char prefix[] = "Cbc_C_Interface::Cbc_solve(): ";
558    int result = 0;
559    std::vector<const char*> argv;
560    argv.push_back("Cbc_C_Interface");
561    for (size_t i = 0; i < model->cmdargs_.size(); i++) {
562        argv.push_back(model->cmdargs_[i].c_str());
563    }
564    argv.push_back("-solve");
565    argv.push_back("-quit");
566    try {
567       
568        CbcMain1((int)argv.size(), &argv[0], *model->model_);
569    } catch (CoinError e) {
570        printf("%s ERROR: %s::%s, %s\n", prefix,
571               e.className().c_str(), e.methodName().c_str(), e.message().c_str());
572    }
573    result = model->model_->status();
574
575    return result;
576}
577
578/* Sum of primal infeasibilities */
579COINLIBAPI double COINLINKAGE
580Cbc_sumPrimalInfeasibilities(Cbc_Model * /*model*/)
581{
582    const char prefix[] = "Cbc_C_Interface::Cbc_sumPrimalInfeasibilities(): ";
583//  const int  VERBOSE = 1;
584    if (VERBOSE > 0) printf("%s begin\n", prefix);
585
586    double result = 0;
587// cannot find names in Cbc, Osi, or OsiClp
588//tbd result = model->model_->sumPrimalInfeasibilities();
589    if (VERBOSE > 0) printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
590
591    if (VERBOSE > 0) printf("%s return %g\n", prefix, result);
592    return result;
593}
594/* Number of primal infeasibilities */
595COINLIBAPI int COINLINKAGE
596Cbc_numberPrimalInfeasibilities(Cbc_Model * /*model*/)
597{
598    const char prefix[] = "Cbc_C_Interface::Cbc_numberPrimalInfeasibilities(): ";
599//  const int  VERBOSE = 1;
600    if (VERBOSE > 0) printf("%s begin\n", prefix);
601
602    int result = 0;
603//tbd  result = model->model_->getContinuousInfeasibilities();
604    if (VERBOSE > 0) printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
605
606    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
607    return result;
608}
609
610
611/** Call this to really test if a valid solution can be feasible
612    Solution is number columns in size.
613    If fixVariables true then bounds of continuous solver updated.
614    Returns objective value (worse than cutoff if not feasible)
615*/
616COINLIBAPI void COINLINKAGE
617Cbc_checkSolution(Cbc_Model * /*model*/)
618{
619    const char prefix[] = "Cbc_C_Interface::Cbc_checkSolution(): ";
620//  const int  VERBOSE = 1;
621    if (VERBOSE > 0) printf("%s begin\n", prefix);
622
623    // see CbcModel::checkSolution(double cutoff, const double * solution,
624    //         bool fixVariables);
625//  model->model_->checkSolution();
626
627    if (VERBOSE > 0) printf("%s return\n", prefix);
628    return;
629}
630
631
632
633CbcGetProperty(int, getNumCols)
634CbcGetProperty(int, getNumRows)
635CbcGetProperty(int, getIterationCount)
636CbcGetProperty(int, isAbandoned)
637CbcGetProperty(int, isProvenOptimal)
638CbcGetProperty(int, isProvenInfeasible)
639CbcGetProperty(int, isContinuousUnbounded)
640CbcGetProperty(int, isNodeLimitReached)
641CbcGetProperty(int, isSecondsLimitReached)
642CbcGetProperty(int, isSolutionLimitReached)
643CbcGetProperty(int, isInitialSolveAbandoned)
644CbcGetProperty(int, isInitialSolveProvenOptimal)
645CbcGetProperty(int, isInitialSolveProvenPrimalInfeasible)
646
647CbcGetProperty(double, getObjSense)
648
649COINLIBAPI void COINLINKAGE
650Cbc_setObjSense(Cbc_Model * model, double sense)
651{
652    model->model_->setObjSense(sense);
653}
654
655CbcGetProperty(const double*, getRowActivity)
656CbcGetProperty(const double*, getColSolution)
657
658CbcGetProperty(const double*, getRowLower)
659CbcSetSolverProperty(double, setRowLower)
660CbcGetProperty(const double*, getRowUpper)
661CbcSetSolverProperty(double, setRowUpper)
662CbcGetProperty(const double*, getObjCoefficients)
663CbcSetSolverProperty(double, setObjCoeff)
664CbcGetProperty(const double*, getColLower)
665CbcSetSolverProperty(double, setColLower)
666CbcGetProperty(const double*, getColUpper)
667CbcSetSolverProperty(double, setColUpper)
668
669CbcGetProperty(double, getObjValue)
670CbcGetProperty(double, getBestPossibleObjValue)
671
672/* Print model */
673COINLIBAPI void COINLINKAGE
674Cbc_printModel(Cbc_Model * model, const char * argPrefix)
675{
676    const char prefix[] = "Cbc_C_Interface::Cbc_printModel(): ";
677    const int  VERBOSE = 4;
678    if (VERBOSE > 0) printf("%s begin\n", prefix);
679
680    CbcModel *cbc_model = model->model_;
681    int numrows    = cbc_model->getNumRows();
682    int numcols    = cbc_model->getNumCols();
683    int numelem    = cbc_model->getNumElements();
684    const CoinPackedMatrix * matrix = cbc_model->solver()->getMatrixByCol();
685    const CoinBigIndex     * start  = matrix->getVectorStarts();
686    const int              * index  = matrix->getIndices();
687    const double           * value  = matrix->getElements();
688    const double           * collb  = cbc_model->getColLower();
689    const double           * colub  = cbc_model->getColUpper();
690    const double           * obj    = cbc_model->getObjCoefficients();
691    const double           * rowlb  = cbc_model->getRowLower();
692    const double           * rowub  = cbc_model->getRowUpper();
693
694    printf("%s numcols = %i, numrows = %i, numelem = %i\n",
695           argPrefix, numcols, numrows, numelem);
696    printf("%s model = %p, start = %p, index = %p, value = %p\n",
697           argPrefix, static_cast<void*>(model), static_cast<const void*>(start),
698           static_cast<const void*>(index), static_cast<const void*>(value));
699    matrix->dumpMatrix(NULL);
700    {
701        int i;
702        for (i = 0; i <= numcols; i++)
703            printf("%s start[%i] = %i\n", argPrefix, i, start[i]);
704        for (i = 0; i < numelem; i++)
705            printf("%s index[%i] = %i, value[%i] = %g\n",
706                   argPrefix, i, index[i], i, value[i]);
707    }
708
709    printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
710           argPrefix, static_cast<const void*>(collb),
711           static_cast<const void*>(colub), static_cast<const void*>(obj),
712           static_cast<const void*>(rowlb), static_cast<const void*>(rowub));
713    printf("%s optimization direction = %g\n", argPrefix, Cbc_getObjSense(model));
714    printf("  (1 - minimize, -1 - maximize, 0 - ignore)\n");
715    {
716        int i;
717        for (i = 0; i < numcols; i++)
718            printf("%s collb[%i] = %g, colub[%i] = %g, obj[%i] = %g\n",
719                   argPrefix, i, collb[i], i, colub[i], i, obj[i]);
720        for (i = 0; i < numrows; i++)
721            printf("%s rowlb[%i] = %g, rowub[%i] = %g\n",
722                   argPrefix, i, rowlb[i], i, rowub[i]);
723    }
724
725    if (VERBOSE > 0) printf("%s return\n", prefix);
726}  // Cbc_printModel()
727
728COINLIBAPI int COINLINKAGE
729Cbc_isInteger(Cbc_Model * model, int i)
730{
731    const char prefix[] = "Cbc_C_Interface::Cbc_isInteger(): ";
732//  const int  VERBOSE = 1;
733    if (VERBOSE > 0) printf("%s begin\n", prefix);
734
735    bool result = false;
736    result = model->model_->isInteger(i);
737
738    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
739    return (result) ? 1 : 0;
740}
741
742CbcGetProperty(int, getNodeCount)
743
744/** Return a copy of this model */
745COINLIBAPI Cbc_Model * COINLINKAGE
746Cbc_clone(Cbc_Model * model)
747{
748    const char prefix[] = "Cbc_C_Interface::Cbc_clone(): ";
749//  const int  VERBOSE = 1;
750    if (VERBOSE > 0) printf("%s begin\n", prefix);
751
752    Cbc_Model * result = new Cbc_Model();
753    result->model_     = new CbcModel(*(model->model_));
754    result->solver_    = dynamic_cast< OsiClpSolverInterface*> (result->model_->solver());
755    result->handler_   = NULL;
756    result->cmdargs_   = model->cmdargs_;
757
758    if (VERBOSE > 0) printf("%s return\n", prefix);
759    return model;
760}
761/** Set this the variable to be continuous */
762COINLIBAPI void COINLINKAGE
763Cbc_setContinuous(Cbc_Model * model, int iColumn)
764{
765    const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
766//  const int  VERBOSE = 1;
767    if (VERBOSE > 0) printf("%s begin\n", prefix);
768
769    model->model_->solver()->setContinuous(iColumn);
770
771    if (VERBOSE > 0) printf("%s return\n", prefix);
772}
773/** Set this the variable to be integer */
774COINLIBAPI void COINLINKAGE
775Cbc_setInteger(Cbc_Model * model, int iColumn)
776{
777    const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
778//  const int  VERBOSE = 1;
779    if (VERBOSE > 0) printf("%s begin\n", prefix);
780
781    model->model_->solver()->setInteger(iColumn);
782
783    if (VERBOSE > 0) printf("%s return\n", prefix);
784}
785/** Add SOS constraints to the model using row-order matrix */
786
787COINLIBAPI void  COINLINKAGE
788Cbc_addSOS(Cbc_Model * model, int numRows, const int * rowStarts,
789           const int * colIndices, const double * weights, const int type)
790{
791    const char prefix[] = "Cbc_C_Interface::Cbc_addSOS(): ";
792  //const int  VERBOSE = 4;
793    if (VERBOSE > 0) printf("%sbegin\n", prefix);
794
795    if (VERBOSE > 0) printf("%s numRows = %i\n", prefix, numRows);
796
797    int row, i;
798    const int *colIndex;
799    const double *colWeight;
800
801    // loop on rows and count number of objects according to numWeights>0
802    int numObjects = 0;
803    for (row = 0; row < numRows; row++) {
804        if (VERBOSE > 2) {
805            printf("%s row = %i\n", prefix, row);
806            printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
807            printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row+1]);
808            fflush(stdout);
809        }
810        const int numWeights = rowStarts[row+1] - rowStarts[row];
811        if (VERBOSE > 2) printf("%s  numWeights = %i\n", prefix, numWeights);
812        if (numWeights > 0) numObjects++;
813    }
814
815    // make objects
816    CbcObject ** objects = new CbcObject * [numObjects];
817//  if (VERBOSE>1) printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
818
819    // loop on rows and make an object when numWeights>0
820    int objNum = 0;
821    for (row = 0; row < numRows; row++) {
822        if (VERBOSE > 2) {
823            printf("%s row = %i\n", prefix, row);
824            printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
825            printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row+1]);
826        }
827        const int numWeights = rowStarts[row+1] - rowStarts[row];
828        if (VERBOSE > 2) printf("%s  numWeights = %i\n", prefix, numWeights);
829        colIndex    = colIndices + rowStarts[row];
830        colWeight   = weights + rowStarts[row];
831        if (numWeights > 0) {
832            // Make a CbcSOS and assign it to objects
833            if (VERBOSE > 3) {
834                for (i = 0; i < numWeights; i++) {
835                    printf("%s  colIndex [%i] = %i\n", prefix, i, colIndex[i]);
836                    printf("%s  colWeight[%i] = %f\n", prefix, i, colWeight[i]);
837                }
838                fflush(stdout);
839            }
840            objects[objNum] = new CbcSOS(model->model_, (int)(numWeights),
841                                         (const int*)colIndex, (const double*)colWeight, (int)objNum, (int)type);
842//      if (VERBOSE>2) printf("%s objects[%i] = %X\n",prefix,objNum,objects[objNum]);
843            if (objects[objNum] == NULL) {
844                printf("%s ERROR: objects[%i] == NULL\n", prefix, objNum);
845                fflush(stdout);
846                assert(objects[objNum] != NULL);
847            }
848            objNum++;
849        }
850    }
851    if (VERBOSE > 2) {
852        printf("%s calling addObjects()\n", prefix);
853       
854        //    printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
855        //    for (row=0; row<numObjects; row++)
856        //      printf("%s  objects[%i] = %X\n",prefix,row,objects[row]);
857       
858    }
859    fflush(stdout);
860    model->model_->addObjects(numObjects, objects);
861    if (VERBOSE > 1) printf("%s finished addObjects()\n", prefix);
862
863    for (objNum = 0; objNum < numObjects; objNum++) delete objects[objNum];
864    delete [] objects;
865
866    if (VERBOSE > 0) printf("%sreturn\n", prefix);
867    return;
868}
869
870/** Print the solution */
871COINLIBAPI void  COINLINKAGE
872Cbc_printSolution(Cbc_Model * model)
873{
874    {
875        //
876        //  Now to print out row solution.  The methods used return const
877        //  pointers - which is of course much more virtuous.
878        //
879        //  This version just does non-zero columns
880        //
881
882        // * Rows
883
884        int numberRows = Cbc_getNumRows(model);
885        int iRow;
886
887
888        const double * rowPrimal = Cbc_getRowActivity(model);
889        const double * rowLower = Cbc_getRowLower(model);
890        const double * rowUpper = Cbc_getRowUpper(model);
891        printf("--------------------------------------\n");
892
893        // * If we have not kept names (parameter to readMps) this will be 0
894        //    assert(Cbc_lengthNames(model));
895
896        printf("                       Primal          Lower         Upper\n");
897        for (iRow = 0; iRow < numberRows; iRow++) {
898            double value;
899            value = rowPrimal[iRow];
900            if (value > 1.0e-8 || value < -1.0e-8) {
901                char name[20];
902                //              Cbc_columnName(model,iColumn,name);
903                sprintf(name, "ROW%5i", iRow);
904                printf("%6d %8s", iRow, name);
905                printf(" %13g", rowPrimal[iRow]);
906                printf(" %13g", rowLower[iRow]);
907                printf(" %13g", rowUpper[iRow]);
908                printf("\n");
909            }
910        }
911        printf("--------------------------------------\n");
912    }
913    {
914        //
915        //  Now to print out column solution.  The methods used return const
916        //  pointers - which is of course much more virtuous.
917        //
918        //  This version just does non-zero columns
919        //
920        //
921
922        // * Columns
923
924        int numberColumns = Cbc_getNumCols(model);
925        int iColumn;
926
927
928        const double * columnPrimal = Cbc_getColSolution(model);
929        const double * columnLower = Cbc_getColLower(model);
930        const double * columnUpper = Cbc_getColUpper(model);
931        const double * columnObjective = Cbc_getObjCoefficients(model);
932
933        printf("--------------------------------------\n");
934
935        // * If we have not kept names (parameter to readMps) this will be 0
936//    assert(Cbc_lengthNames(model));
937
938        printf("                       Primal          Lower         Upper          Cost     isInteger\n");
939        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
940            double value;
941            value = columnPrimal[iColumn];
942            if (value > 1.0e-8 || value < -1.0e-8) {
943                char name[20];
944//              Cbc_columnName(model,iColumn,name);
945                sprintf(name, "COL%5i", iColumn);
946                printf("%6d %8s", iColumn, name);
947                printf(" %13g", columnPrimal[iColumn]);
948                printf(" %13g", columnLower[iColumn]);
949                printf(" %13g", columnUpper[iColumn]);
950                printf(" %13g", columnObjective[iColumn]);
951                printf(" %13i", Cbc_isInteger(model,iColumn));
952                printf("\n");
953            }
954        }
955        printf("--------------------------------------\n");
956    }
957    if (0) Cbc_printModel(model, "cbc::main(): ");
958    return;
959}
960
961#if defined(__MWERKS__)
962#pragma export off
963#endif
964
Note: See TracBrowser for help on using the repository browser.