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

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

Improved documentation. Tests for callbacks and row/column names. More restructuring.

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