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

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

Implement Cbc_setInitialSolution for providing a feasible solution.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 33.8 KB
Line 
1// $Id: Cbc_C_Interface.cpp 2032 2014-05-08 04:11:17Z 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
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 const char* COINLINKAGE Cbc_getVersion()
223{
224    return CBC_VERSION;
225}
226
227/* Default Cbc_Model constructor */
228COINLIBAPI Cbc_Model *  COINLINKAGE
229Cbc_newModel()
230{
231    const char prefix[] = "Cbc_C_Interface::Cbc_newModel(): ";
232//  const int  VERBOSE = 1;
233    if (VERBOSE > 0) printf("%s begin\n", prefix);
234
235    Cbc_Model * model = new Cbc_Model();
236    OsiClpSolverInterface solver1;
237    model->solver_    = &solver1;
238    model->model_     = new CbcModel(solver1);
239    CbcMain0(*model->model_);
240    model->handler_   = NULL;
241
242    if (VERBOSE > 0) printf("%s return\n", prefix);
243    return model;
244}
245/* Cbc_Model Destructor */
246COINLIBAPI void COINLINKAGE
247Cbc_deleteModel(Cbc_Model * model)
248{
249    const char prefix[] = "Cbc_C_Interface::Cbc_deleteModel(): ";
250//  const int  VERBOSE = 1;
251    if (VERBOSE > 0) printf("%s begin\n", prefix);
252    fflush(stdout);
253
254    if (VERBOSE > 1) printf("%s delete model->model_\n", prefix);
255    fflush(stdout);
256    delete model->model_;
257
258    if (VERBOSE > 1) printf("%s delete model->handler_\n", prefix);
259    fflush(stdout);
260    delete model->handler_;
261
262    if (VERBOSE > 1) printf("%s delete model\n", prefix);
263    fflush(stdout);
264    delete model;
265
266    if (VERBOSE > 0) printf("%s return\n", prefix);
267    fflush(stdout);
268}
269
270/* Loads a problem (the constraints on the
271    rows are given by lower and upper bounds). If a pointer is NULL then the
272    following values are the default:
273    <ul>
274    <li> <code>colub</code>: all columns have upper bound infinity
275    <li> <code>collb</code>: all columns have lower bound 0
276    <li> <code>rowub</code>: all rows have upper bound infinity
277    <li> <code>rowlb</code>: all rows have lower bound -infinity
278    <li> <code>obj</code>: all variables have 0 objective coefficient
279    </ul>
280
281   Just like the other loadProblem() method except that the matrix is
282   given in a standard column major ordered format (without gaps).
283*/
284COINLIBAPI void COINLINKAGE
285Cbc_loadProblem (Cbc_Model * model,  const int numcols, const int numrows,
286                 const CoinBigIndex * start, const int* index,
287                 const double* value,
288                 const double* collb, const double* colub,
289                 const double* obj,
290                 const double* rowlb, const double* rowub)
291{
292    const char prefix[] = "Cbc_C_Interface::Cbc_loadProblem(): ";
293//  const int  VERBOSE = 2;
294    if (VERBOSE > 0) printf("%s begin\n", prefix);
295
296    OsiSolverInterface * solver = model->model_->solver();
297
298    if (VERBOSE > 1) {
299        printf("%s numcols = %i, numrows = %i\n",
300               prefix, numcols, numrows);
301        printf("%s model = %p, start = %p, index = %p, value = %p\n",
302               prefix, static_cast<void*>(model), static_cast<const void*>(start),
303               static_cast<const void*>(index), static_cast<const void*>(value));
304        printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
305               prefix, static_cast<const void*>(collb),
306               static_cast<const void*>(colub), static_cast<const void*>(obj),
307               static_cast<const void*>(rowlb), static_cast<const void*>(rowub));
308    }
309
310    if (VERBOSE > 1) printf("%s Calling solver->loadProblem()\n", prefix);
311    fflush(stdout);
312
313    solver->loadProblem(numcols, numrows, start, index, value,
314                        collb, colub, obj, rowlb, rowub);
315    if (VERBOSE > 1) printf("%s Finished solver->loadProblem()\n", prefix);
316    fflush(stdout);
317
318    if (VERBOSE > 0) printf("%s return\n", prefix);
319} //  Cbc_loadProblem()
320
321/* Read an mps file from the given filename */
322COINLIBAPI int COINLINKAGE
323Cbc_readMps(Cbc_Model * model, const char *filename)
324{
325    const char prefix[] = "Cbc_C_Interface::Cbc_readMps(): ";
326//  const int  VERBOSE = 2;
327    if (VERBOSE > 0) printf("%s begin\n", prefix);
328    if (VERBOSE > 1) printf("%s filename = '%s'\n", prefix, filename);
329
330    int result = 1;
331    result = model->model_->solver()->readMps(filename);
332    assert(result == 0);
333
334    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
335    return result;
336}
337/* Write an mps file from the given filename */
338COINLIBAPI void COINLINKAGE
339Cbc_writeMps(Cbc_Model * model, const char *filename)
340{
341    const char prefix[] = "Cbc_C_Interface::Cbc_writeMps(): ";
342//  const int  VERBOSE = 2;
343    if (VERBOSE > 0) printf("%s begin\n", prefix);
344    if (VERBOSE > 1) printf("%s filename = '%s'\n", prefix, filename);
345
346    model->model_->solver()->writeMps(filename, "mps", Cbc_getObjSense(model));
347
348    if (VERBOSE > 0) printf("%s return\n", prefix);
349    return;
350}
351
352
353COINLIBAPI void COINLINKAGE
354Cbc_setInitialSolution(Cbc_Model *model, const double * sol)
355{
356    int n = Cbc_getNumCols(model);
357    // We need to manually compute the objective here for some reason
358    const double *objvec = Cbc_getObjCoefficients(model);
359    double objval = 0;
360    for (int i = 0; i < n; i++) {
361        objval += objvec[i]*sol[i];
362    }
363    model->model_->setBestSolution(sol, n, objval, true);
364}
365
366/* Deletes rows */
367COINLIBAPI void COINLINKAGE
368Cbc_deleteRows(Cbc_Model * model, int number, const int * which)
369{
370    const char prefix[] = "Cbc_C_Interface::Cbc_deleteRows(): ";
371    if (VERBOSE > 0) printf("%s begin\n", prefix);
372
373    OsiSolverInterface * solver = model->model_->solver();
374    solver->deleteRows(number, which);
375
376    if (VERBOSE > 0) printf("%s return\n", prefix);
377}
378/* Add rows */
379COINLIBAPI void COINLINKAGE
380Cbc_addRows(Cbc_Model * /*model*/, const int /*number*/,
381            const double * /*rowLower*/,
382            const double * /*rowUpper*/,
383            const int * /*rowStarts*/, const int * /*columns*/,
384            const double * /*elements*/)
385{
386    const char prefix[] = "Cbc_C_Interface::Cbc_addRows(): ";
387    if (VERBOSE > 0) printf("%s begin\n", prefix);
388
389// available through OsiClp
390//tbd  model->model_->addRows(number,rowLower,rowUpper,rowStarts,columns,elements);
391    if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);
392
393    if (VERBOSE > 0) printf("%s return\n", prefix);
394}
395
396/* Deletes columns */
397COINLIBAPI void COINLINKAGE
398Cbc_deleteColumns(Cbc_Model * model, int number, const int * which)
399{
400    const char prefix[] = "Cbc_C_Interface::Cbc_deleteColumns(): ";
401//  const int  VERBOSE = 1;
402    if (VERBOSE > 0) printf("%s begin\n", prefix);
403
404    OsiSolverInterface * solver = model->model_->solver();
405    solver->deleteCols(number, which);
406
407    if (VERBOSE > 0) printf("%s return\n", prefix);
408}
409/* Add columns */
410COINLIBAPI void COINLINKAGE
411Cbc_addColumns(Cbc_Model * /*model*/, int /*number*/,
412               const double * /*columnLower*/,
413               const double * /*columnUpper*/,
414               const double * /*objective*/,
415               const int * /*columnStarts*/, const int * /*rows*/,
416               const double * /*elements*/)
417{
418    const char prefix[] = "Cbc_C_Interface::Cbc_addColumns(): ";
419//  const int  VERBOSE = 1;
420    if (VERBOSE > 0) printf("%s begin\n", prefix);
421
422// available through OsiClp
423//tbd  model->model_->addColumns(number,columnLower,columnUpper,objective,
424//tbd                       columnStarts,rows,elements);
425    if (VERBOSE > 0) printf("%s WARNING: NOT IMPLEMENTED\n", prefix);
426
427    if (VERBOSE > 0) printf("%s return\n", prefix);
428}
429
430
431COINLIBAPI void COINLINKAGE
432Cbc_setParameter(Cbc_Model * model, const char * name, const char * value)
433{
434    model->cmdargs_.push_back(std::string("-")+name);
435    model->cmdargs_.push_back(value);
436}
437
438/* Fills in array with problem name  */
439COINLIBAPI void COINLINKAGE
440Cbc_problemName(Cbc_Model * model, int maxNumberCharacters, char * array)
441{
442    std::string name;
443    model->model_->solver()->getStrParam(OsiProbName, name);
444    strncpy(array, name.c_str(), maxNumberCharacters);
445}
446/* Sets problem name.  Must have \0 at end.  */
447COINLIBAPI int COINLINKAGE
448Cbc_setProblemName(Cbc_Model * model, const char * array)
449{
450    bool result = false;
451    result = model->model_->solver()->setStrParam(OsiProbName, array);
452
453    return (result) ? 1 : 0;
454}
455
456CbcGetProperty(int, status)
457
458CbcGetProperty(int, secondaryStatus)
459
460/* Number of elements in matrix */
461COINLIBAPI int COINLINKAGE
462Cbc_getNumElements(Cbc_Model * model)
463{
464    const char prefix[] = "Cbc_C_Interface::Cbc_getNumElements(): ";
465//  const int  VERBOSE = 1;
466    if (VERBOSE > 0) printf("%s begin\n", prefix);
467
468    int result = 0;
469    result = model->model_->getNumElements();
470
471    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
472    return result;
473}
474
475// Column starts in matrix
476COINLIBAPI const CoinBigIndex * COINLINKAGE
477Cbc_getVectorStarts(Cbc_Model * model)
478{
479    const CoinPackedMatrix * matrix = NULL;
480    matrix = model->model_->solver()->getMatrixByCol();
481    return (matrix == NULL) ? NULL : matrix->getVectorStarts();
482}
483// Row indices in matrix
484COINLIBAPI const int * COINLINKAGE
485Cbc_getIndices(Cbc_Model * model)
486{
487    const char prefix[] = "Cbc_C_Interface::Cbc_getIndices(): ";
488//  const int  VERBOSE = 1;
489    if (VERBOSE > 0) printf("%s begin\n", prefix);
490
491    const int * result = NULL;
492    const CoinPackedMatrix * matrix = NULL;
493    matrix = model->model_->solver()->getMatrixByCol();
494    result = (matrix == NULL) ? NULL : matrix->getIndices();
495
496    if (VERBOSE > 0)
497        printf("%s return %p\n", prefix, static_cast<const void*>(result));
498    return result;
499}
500
501
502// Element values in matrix
503COINLIBAPI const double * COINLINKAGE
504Cbc_getElements(Cbc_Model * model)
505{
506    const char prefix[] = "Cbc_C_Interface::Cbc_getElements(): ";
507//  const int  VERBOSE = 1;
508    if (VERBOSE > 0) printf("%s begin\n", prefix);
509
510    const double * result = NULL;
511    const CoinPackedMatrix * matrix = NULL;
512    matrix = model->model_->solver()->getMatrixByCol();
513    result = (matrix == NULL) ? NULL : matrix->getElements();
514
515    if (VERBOSE > 0)
516        printf("%s return %p\n", prefix, static_cast<const void*>(result));
517    return result;
518}
519// ======================================================================
520
521
522
523/* Pass in Callback function */
524COINLIBAPI void COINLINKAGE
525Cbc_registerCallBack(Cbc_Model * model,
526                     cbc_callback userCallBack)
527{
528    const char prefix[] = "Cbc_C_Interface::Cbc_registerCallBack(): ";
529//  const int  VERBOSE = 1;
530    if (VERBOSE > 0) printf("%s begin\n", prefix);
531
532    // Will be copy of users one
533    delete model->handler_;
534    model->handler_ = new Cbc_MessageHandler(*(model->model_->messageHandler()));
535    model->handler_->setCallBack(userCallBack);
536    model->handler_->setModel(model);
537    model->model_->passInMessageHandler(model->handler_);
538
539    if (VERBOSE > 0) printf("%s return\n", prefix);
540}
541/* Unset Callback function */
542COINLIBAPI void COINLINKAGE
543Cbc_clearCallBack(Cbc_Model * model)
544{
545    const char prefix[] = "Cbc_C_Interface::Cbc_clearCallBack(): ";
546//  const int  VERBOSE = 1;
547    if (VERBOSE > 0) printf("%s begin\n", prefix);
548
549    delete model->handler_;
550    model->handler_ = NULL;
551
552    if (VERBOSE > 0) printf("%s return\n", prefix);
553}
554/* length of names (0 means no names0 */
555COINLIBAPI size_t COINLINKAGE
556Cbc_maxNameLength(Cbc_Model * model)
557{
558    size_t result = 0;
559    OsiSolverInterface::OsiNameVec const & rownames = model->model_->solver()->getRowNames();
560    for (size_t i = 0; i < rownames.size(); i++) {
561        if (rownames[i].length() > result) result = rownames[i].length();
562    }
563    OsiSolverInterface::OsiNameVec const & colnames = model->model_->solver()->getColNames();
564    for (size_t i = 0; i < colnames.size(); i++) {
565        if (colnames[i].length() > result) result = colnames[i].length();
566    }
567    return result;
568}
569COINLIBAPI void COINLINKAGE
570Cbc_getRowName(Cbc_Model * model, int iRow, char * name, size_t maxLength)
571{
572    std::string rowname = model->model_->solver()->getRowName(iRow);
573    strncpy(name, rowname.c_str(), maxLength);
574    name[maxLength-1] = '\0';
575}
576COINLIBAPI void COINLINKAGE
577Cbc_getColName(Cbc_Model * model, int iRow, char * name, size_t maxLength)
578{
579    std::string colname = model->model_->solver()->getColName(iRow);
580    strncpy(name, colname.c_str(), maxLength);
581    name[maxLength-1] = '\0';
582}
583
584COINLIBAPI void COINLINKAGE
585Cbc_setColName(Cbc_Model * model, int iColumn, const char * name)
586{
587    model->model_->solver()->setColName(iColumn, name);
588}
589
590COINLIBAPI void COINLINKAGE
591Cbc_setRowName(Cbc_Model * model, int iRow, const char * name)
592{
593    model->model_->solver()->setRowName(iRow, name);
594}
595
596
597COINLIBAPI int COINLINKAGE
598Cbc_solve(Cbc_Model * model)
599{
600    const char prefix[] = "Cbc_C_Interface::Cbc_solve(): ";
601    int result = 0;
602    std::vector<const char*> argv;
603    argv.push_back("Cbc_C_Interface");
604    for (size_t i = 0; i < model->cmdargs_.size(); i++) {
605        argv.push_back(model->cmdargs_[i].c_str());
606    }
607    argv.push_back("-solve");
608    argv.push_back("-quit");
609    try {
610       
611        CbcMain1((int)argv.size(), &argv[0], *model->model_);
612    } catch (CoinError e) {
613        printf("%s ERROR: %s::%s, %s\n", prefix,
614               e.className().c_str(), e.methodName().c_str(), e.message().c_str());
615    }
616    result = model->model_->status();
617
618    return result;
619}
620
621/* Sum of primal infeasibilities */
622COINLIBAPI double COINLINKAGE
623Cbc_sumPrimalInfeasibilities(Cbc_Model * /*model*/)
624{
625    const char prefix[] = "Cbc_C_Interface::Cbc_sumPrimalInfeasibilities(): ";
626//  const int  VERBOSE = 1;
627    if (VERBOSE > 0) printf("%s begin\n", prefix);
628
629    double result = 0;
630// cannot find names in Cbc, Osi, or OsiClp
631//tbd result = model->model_->sumPrimalInfeasibilities();
632    if (VERBOSE > 0) printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
633
634    if (VERBOSE > 0) printf("%s return %g\n", prefix, result);
635    return result;
636}
637/* Number of primal infeasibilities */
638COINLIBAPI int COINLINKAGE
639Cbc_numberPrimalInfeasibilities(Cbc_Model * /*model*/)
640{
641    const char prefix[] = "Cbc_C_Interface::Cbc_numberPrimalInfeasibilities(): ";
642//  const int  VERBOSE = 1;
643    if (VERBOSE > 0) printf("%s begin\n", prefix);
644
645    int result = 0;
646//tbd  result = model->model_->getContinuousInfeasibilities();
647    if (VERBOSE > 0) printf("%s WARNING:  NOT IMPLEMENTED\n", prefix);
648
649    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
650    return result;
651}
652
653
654/** Call this to really test if a valid solution can be feasible
655    Solution is number columns in size.
656    If fixVariables true then bounds of continuous solver updated.
657    Returns objective value (worse than cutoff if not feasible)
658*/
659COINLIBAPI void COINLINKAGE
660Cbc_checkSolution(Cbc_Model * /*model*/)
661{
662    const char prefix[] = "Cbc_C_Interface::Cbc_checkSolution(): ";
663//  const int  VERBOSE = 1;
664    if (VERBOSE > 0) printf("%s begin\n", prefix);
665
666    // see CbcModel::checkSolution(double cutoff, const double * solution,
667    //         bool fixVariables);
668//  model->model_->checkSolution();
669
670    if (VERBOSE > 0) printf("%s return\n", prefix);
671    return;
672}
673
674
675
676CbcGetProperty(int, getNumCols)
677CbcGetProperty(int, getNumRows)
678CbcGetProperty(int, getIterationCount)
679CbcGetProperty(int, isAbandoned)
680CbcGetProperty(int, isProvenOptimal)
681CbcGetProperty(int, isProvenInfeasible)
682CbcGetProperty(int, isContinuousUnbounded)
683CbcGetProperty(int, isNodeLimitReached)
684CbcGetProperty(int, isSecondsLimitReached)
685CbcGetProperty(int, isSolutionLimitReached)
686CbcGetProperty(int, isInitialSolveAbandoned)
687CbcGetProperty(int, isInitialSolveProvenOptimal)
688CbcGetProperty(int, isInitialSolveProvenPrimalInfeasible)
689
690CbcGetProperty(double, getObjSense)
691
692COINLIBAPI void COINLINKAGE
693Cbc_setObjSense(Cbc_Model * model, double sense)
694{
695    model->model_->setObjSense(sense);
696}
697
698CbcGetProperty(const double*, getRowActivity)
699CbcGetProperty(const double*, getColSolution)
700
701CbcGetProperty(const double*, getRowLower)
702CbcGetProperty(const double*, getRowUpper)
703CbcGetProperty(const double*, getObjCoefficients)
704CbcGetProperty(const double*, getColLower)
705CbcGetProperty(const double*, getColUpper)
706
707CbcGetProperty(double, getObjValue)
708CbcGetProperty(double, getBestPossibleObjValue)
709
710/* Print model */
711COINLIBAPI void COINLINKAGE
712Cbc_printModel(Cbc_Model * model, const char * argPrefix)
713{
714    const char prefix[] = "Cbc_C_Interface::Cbc_printModel(): ";
715    const int  VERBOSE = 4;
716    if (VERBOSE > 0) printf("%s begin\n", prefix);
717
718    CbcModel *cbc_model = model->model_;
719    int numrows    = cbc_model->getNumRows();
720    int numcols    = cbc_model->getNumCols();
721    int numelem    = cbc_model->getNumElements();
722    const CoinPackedMatrix * matrix = cbc_model->solver()->getMatrixByCol();
723    const CoinBigIndex     * start  = matrix->getVectorStarts();
724    const int              * index  = matrix->getIndices();
725    const double           * value  = matrix->getElements();
726    const double           * collb  = cbc_model->getColLower();
727    const double           * colub  = cbc_model->getColUpper();
728    const double           * obj    = cbc_model->getObjCoefficients();
729    const double           * rowlb  = cbc_model->getRowLower();
730    const double           * rowub  = cbc_model->getRowUpper();
731
732    printf("%s numcols = %i, numrows = %i, numelem = %i\n",
733           argPrefix, numcols, numrows, numelem);
734    printf("%s model = %p, start = %p, index = %p, value = %p\n",
735           argPrefix, static_cast<void*>(model), static_cast<const void*>(start),
736           static_cast<const void*>(index), static_cast<const void*>(value));
737    matrix->dumpMatrix(NULL);
738    {
739        int i;
740        for (i = 0; i <= numcols; i++)
741            printf("%s start[%i] = %i\n", argPrefix, i, start[i]);
742        for (i = 0; i < numelem; i++)
743            printf("%s index[%i] = %i, value[%i] = %g\n",
744                   argPrefix, i, index[i], i, value[i]);
745    }
746
747    printf("%s collb = %p, colub = %p, obj = %p, rowlb = %p, rowub = %p\n",
748           argPrefix, static_cast<const void*>(collb),
749           static_cast<const void*>(colub), static_cast<const void*>(obj),
750           static_cast<const void*>(rowlb), static_cast<const void*>(rowub));
751    printf("%s optimization direction = %g\n", argPrefix, Cbc_getObjSense(model));
752    printf("  (1 - minimize, -1 - maximize, 0 - ignore)\n");
753    {
754        int i;
755        for (i = 0; i < numcols; i++)
756            printf("%s collb[%i] = %g, colub[%i] = %g, obj[%i] = %g\n",
757                   argPrefix, i, collb[i], i, colub[i], i, obj[i]);
758        for (i = 0; i < numrows; i++)
759            printf("%s rowlb[%i] = %g, rowub[%i] = %g\n",
760                   argPrefix, i, rowlb[i], i, rowub[i]);
761    }
762
763    if (VERBOSE > 0) printf("%s return\n", prefix);
764}  // Cbc_printModel()
765
766COINLIBAPI int COINLINKAGE
767Cbc_isInteger(Cbc_Model * model, int i)
768{
769    const char prefix[] = "Cbc_C_Interface::Cbc_isInteger(): ";
770//  const int  VERBOSE = 1;
771    if (VERBOSE > 0) printf("%s begin\n", prefix);
772
773    bool result = false;
774    result = model->model_->isInteger(i);
775
776    if (VERBOSE > 0) printf("%s return %i\n", prefix, result);
777    return (result) ? 1 : 0;
778}
779
780CbcGetProperty(int, getNodeCount)
781
782/** Return a copy of this model */
783COINLIBAPI Cbc_Model * COINLINKAGE
784Cbc_clone(Cbc_Model * model)
785{
786    const char prefix[] = "Cbc_C_Interface::Cbc_clone(): ";
787//  const int  VERBOSE = 1;
788    if (VERBOSE > 0) printf("%s begin\n", prefix);
789
790    Cbc_Model * result = new Cbc_Model();
791    result->model_     = new CbcModel(*(model->model_));
792    result->solver_    = dynamic_cast< OsiClpSolverInterface*> (result->model_->solver());
793    result->handler_   = NULL;
794    result->cmdargs_   = model->cmdargs_;
795
796    if (VERBOSE > 0) printf("%s return\n", prefix);
797    return model;
798}
799/** Set this the variable to be continuous */
800COINLIBAPI Cbc_Model * COINLINKAGE
801Cbc_setContinuous(Cbc_Model * model, int iColumn)
802{
803    const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
804//  const int  VERBOSE = 1;
805    if (VERBOSE > 0) printf("%s begin\n", prefix);
806
807    model->model_->solver()->setContinuous(iColumn);
808
809    if (VERBOSE > 0) printf("%s return\n", prefix);
810    return model;
811}
812/** Set this the variable to be integer */
813COINLIBAPI Cbc_Model * COINLINKAGE
814Cbc_setInteger(Cbc_Model * model, int iColumn)
815{
816    const char prefix[] = "Cbc_C_Interface::Cbc_setContinuous(): ";
817//  const int  VERBOSE = 1;
818    if (VERBOSE > 0) printf("%s begin\n", prefix);
819
820    model->model_->solver()->setInteger(iColumn);
821
822    if (VERBOSE > 0) printf("%s return\n", prefix);
823    return model;
824}
825/* Add an SOS constraint to the model */
826COINLIBAPI void  COINLINKAGE
827Cbc_addSOS_Dense(Cbc_Model * model, int numObjects, const int * len,
828                 const int * const* which, const double * weights, const int type)
829{
830    const char prefix[] = "Cbc_C_Interface::Cbc_addSOS_Dense(): ";
831//  const int  VERBOSE = 2;
832    if (VERBOSE > 0) printf("%sbegin\n", prefix);
833
834    assert(1 > 0);// this is probably broken
835    int i, j;
836    // I think this is a different model due to overriding = operator
837    CbcModel m = *(model->model_);
838
839    CbcObject ** objects = new CbcObject * [numObjects];
840
841    if (VERBOSE > 1) printf("%s numObjects = %i\n", prefix, numObjects);
842    for (i = 0; i < numObjects; i++) {
843        if (VERBOSE > 1) {
844            printf("%s len[%i] = %i, identifier = %i, type = %i\n",
845                   prefix, i, len[i], i, type);
846            fflush(stdout);
847            for (j = 0; j < len[i]; j++) {
848                if (VERBOSE > 2 || j == 0 || j == (len[i] - 1)) {
849                    printf("%s which[%i][%i] = %d, weights[%i] = %g\n",
850                           prefix, i, j, which[i][j], j, weights[j]);
851                    fflush(stdout);
852                }
853            }
854        }
855
856        // Make a CbcSOS and assign it to objects
857        if (VERBOSE > 1) printf("%s len[%i] = %i\n", prefix, i, len[i]);
858        if (VERBOSE > 1) printf("%s new CbcSOS()\n", prefix);
859        // ***
860        objects[i] = new CbcSOS(model->model_, (int)(len[i]),
861                                (const int*)which[i], (const double*)weights, (int)i, (int)type);
862        // ***
863        if (objects[i] == NULL) {
864            printf("%s ERROR: objects[%i] == NULL\n", prefix, i);
865            fflush(stdout);
866            assert(objects[i] != NULL);
867        }
868    }
869    if (VERBOSE > 1) printf("%s calling addObjects()\n", prefix);
870    fflush(stdout);
871    model->model_->addObjects(numObjects, objects);
872    if (VERBOSE > 1) printf("%s finished addObjects()\n", prefix);
873
874    for (i = 0; i < numObjects; i++) delete objects[i];
875    delete [] objects;
876
877    if (VERBOSE > 0) printf("%sreturn\n", prefix);
878    return;
879}
880/** Add SOS constraints to the model using row-order matrix */
881COINLIBAPI void  COINLINKAGE
882Cbc_addSOS_Sparse(Cbc_Model * model, const int * rowStarts,
883                  const int * rowIndices, const double * weights, const int type)
884{
885    const char prefix[] = "Cbc_C_Interface::Cbc_addSOS_Sparse(): ";
886//  const int  VERBOSE = 1;
887    if (VERBOSE > 0) printf("%sbegin\n", prefix);
888
889    int numRows = Cbc_getNumRows(model);
890    if (VERBOSE > 0) printf("%s numRows = %i\n", prefix, numRows);
891
892    // The passed sparse matrix must have the same number of rows as the model
893    assert(numRows == Cbc_getNumRows(model));
894
895    int row, i;
896    const int *colIndex;
897    const double *colWeight;
898
899    // loop on rows and count number of objects according to numWeights>0
900    int numObjects = 0;
901    for (row = 0; row < numRows; row++) {
902        if (VERBOSE > 2) {
903            printf("%s row = %i\n", prefix, row);
904            printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
905            printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row+1]);
906            fflush(stdout);
907        }
908        const int numWeights = rowStarts[row+1] - rowStarts[row];
909        if (VERBOSE > 2) printf("%s  numWeights = %i\n", prefix, numWeights);
910        if (numWeights > 0) numObjects++;
911    }
912
913    // make objects
914    CbcObject ** objects = new CbcObject * [numObjects];
915//  if (VERBOSE>1) printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
916
917    // loop on rows and make an object when numWeights>0
918    int objNum = 0;
919    for (row = 0; row < numRows; row++) {
920        if (VERBOSE > 2) {
921            printf("%s row = %i\n", prefix, row);
922            printf("%s rowStarts[%i] = %i\n", prefix, row, rowStarts[row]);
923            printf("%s rowStarts[%i+1] = %i\n", prefix, row, rowStarts[row+1]);
924        }
925        const int numWeights = rowStarts[row+1] - rowStarts[row];
926        if (VERBOSE > 2) printf("%s  numWeights = %i\n", prefix, numWeights);
927        colIndex    = rowIndices + rowStarts[row];
928        colWeight   = weights + rowStarts[row];
929        if (numWeights > 0) {
930            // Make a CbcSOS and assign it to objects
931            if (VERBOSE > 3) {
932                for (i = 0; i < numWeights; i++) {
933                    printf("%s  colIndex [%i] = %i\n", prefix, i, colIndex[i]);
934                    printf("%s  colWeight[%i] = %f\n", prefix, i, colWeight[i]);
935                }
936                fflush(stdout);
937            }
938            objects[objNum] = new CbcSOS(model->model_, (int)(numWeights),
939                                         (const int*)colIndex, (const double*)colWeight, (int)objNum, (int)type);
940//      if (VERBOSE>2) printf("%s objects[%i] = %X\n",prefix,objNum,objects[objNum]);
941            if (objects[objNum] == NULL) {
942                printf("%s ERROR: objects[%i] == NULL\n", prefix, objNum);
943                fflush(stdout);
944                assert(objects[objNum] != NULL);
945            }
946            objNum++;
947        }
948    }
949    if (VERBOSE > 2) {
950        printf("%s calling addObjects()\n", prefix);
951        /*
952            printf("%s numObjects = %i, objects = %X\n",prefix,numObjects,objects);
953            for (row=0; row<numObjects; row++)
954              printf("%s  objects[%i] = %X\n",prefix,row,objects[row]);
955        */
956    }
957    fflush(stdout);
958    model->model_->addObjects(numObjects, objects);
959    if (VERBOSE > 1) printf("%s finished addObjects()\n", prefix);
960
961    for (objNum = 0; objNum < numObjects; objNum++) delete objects[objNum];
962    delete [] objects;
963
964    if (VERBOSE > 0) printf("%sreturn\n", prefix);
965    return;
966}
967
968/** Print the solution */
969COINLIBAPI void  COINLINKAGE
970Cbc_printSolution(Cbc_Model * model)
971{
972    {
973        //
974        //  Now to print out row solution.  The methods used return const
975        //  pointers - which is of course much more virtuous.
976        //
977        //  This version just does non-zero columns
978        //
979
980        // * Rows
981
982        int numberRows = Cbc_getNumRows(model);
983        int iRow;
984
985
986        const double * rowPrimal = Cbc_getRowActivity(model);
987        const double * rowLower = Cbc_getRowLower(model);
988        const double * rowUpper = Cbc_getRowUpper(model);
989        printf("--------------------------------------\n");
990
991        // * If we have not kept names (parameter to readMps) this will be 0
992        //    assert(Cbc_lengthNames(model));
993
994        printf("                       Primal          Lower         Upper\n");
995        for (iRow = 0; iRow < numberRows; iRow++) {
996            double value;
997            value = rowPrimal[iRow];
998            if (value > 1.0e-8 || value < -1.0e-8) {
999                char name[20];
1000                //              Cbc_columnName(model,iColumn,name);
1001                sprintf(name, "ROW%5i", iRow);
1002                printf("%6d %8s", iRow, name);
1003                printf(" %13g", rowPrimal[iRow]);
1004                printf(" %13g", rowLower[iRow]);
1005                printf(" %13g", rowUpper[iRow]);
1006                printf("\n");
1007            }
1008        }
1009        printf("--------------------------------------\n");
1010    }
1011    {
1012        //
1013        //  Now to print out column solution.  The methods used return const
1014        //  pointers - which is of course much more virtuous.
1015        //
1016        //  This version just does non-zero columns
1017        //
1018        //
1019
1020        // * Columns
1021
1022        int numberColumns = Cbc_getNumCols(model);
1023        int iColumn;
1024
1025
1026        const double * columnPrimal = Cbc_getColSolution(model);
1027        const double * columnLower = Cbc_getColLower(model);
1028        const double * columnUpper = Cbc_getColUpper(model);
1029        const double * columnObjective = Cbc_getObjCoefficients(model);
1030
1031        printf("--------------------------------------\n");
1032
1033        // * If we have not kept names (parameter to readMps) this will be 0
1034//    assert(Cbc_lengthNames(model));
1035
1036        printf("                       Primal          Lower         Upper          Cost     isInteger\n");
1037        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1038            double value;
1039            value = columnPrimal[iColumn];
1040            if (value > 1.0e-8 || value < -1.0e-8) {
1041                char name[20];
1042//              Cbc_columnName(model,iColumn,name);
1043                sprintf(name, "COL%5i", iColumn);
1044                printf("%6d %8s", iColumn, name);
1045                printf(" %13g", columnPrimal[iColumn]);
1046                printf(" %13g", columnLower[iColumn]);
1047                printf(" %13g", columnUpper[iColumn]);
1048                printf(" %13g", columnObjective[iColumn]);
1049                printf(" %13i", Cbc_isInteger(model,iColumn));
1050                printf("\n");
1051            }
1052        }
1053        printf("--------------------------------------\n");
1054    }
1055    if (0) Cbc_printModel(model, "cbc::main(): ");
1056    return;
1057}
1058
1059#if defined(__MWERKS__)
1060#pragma export off
1061#endif
1062
Note: See TracBrowser for help on using the repository browser.