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

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

Allow passing arbitrary command-line parameters using the C interface

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