source: trunk/Cbc/examples/driver4.cpp @ 1574

Last change on this file since 1574 was 1574, checked in by lou, 8 years ago

Change to EPL license notice.

File size: 8.9 KB
Line 
1// $Id$
2// Copyright (C) 2007, 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#if defined(_MSC_VER)
7// Turn off compiler warning about long names
8#  pragma warning(disable:4786)
9#endif
10
11#include <cassert>
12#include <iomanip>
13
14
15#include "CbcModel.hpp"
16#include "OsiClpSolverInterface.hpp"
17#include "CbcCompareUser.hpp"
18#include "CbcSolver.hpp"
19
20#include  "CoinTime.hpp"
21
22//#############################################################################
23
24
25/************************************************************************
26
27This main program shows how to take advantage of the standalone cbc in your program,
28while still making major modifications.
29First it reads in an integer model from an mps file
30Then it initializes the integer model with cbc defaults
31Then it calls CbcMain1 passing all parameters apart from first but with callBack to modify stuff
32Finally it prints solution
33
34************************************************************************/
35/* Meaning of whereFrom:
36   1 after initial solve by dualsimplex etc
37   2 after preprocessing
38   3 just before branchAndBound (so user can override)
39   4 just after branchAndBound (before postprocessing)
40   5 after postprocessing
41*/
42/* Meaning of model status is as normal
43   status
44      -1 before branchAndBound
45      0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found
46      (or check value of best solution)
47      1 stopped - on maxnodes, maxsols, maxtime
48      2 difficulties so run was abandoned
49      (5 event user programmed event occurred)
50
51      cbc secondary status of problem
52        -1 unset (status_ will also be -1)
53        0 search completed with solution
54        1 linear relaxation not feasible (or worse than cutoff)
55        2 stopped on gap
56        3 stopped on nodes
57        4 stopped on time
58        5 stopped on user event
59        6 stopped on solutions
60        7 linear relaxation unbounded
61
62   but initially check if status is 0 and secondary status is 1 -> infeasible
63   or you can check solver status.
64*/
65/* Return non-zero to return quickly */   
66static int callBack(CbcModel * model, int whereFrom)
67{
68  int returnCode=0;
69  switch (whereFrom) {
70  case 1:
71  case 2:
72    if (!model->status()&&model->secondaryStatus())
73      returnCode=1;
74    break;
75  case 3:
76    {
77      CbcCompareUser compare;
78      model->setNodeComparison(compare);
79    }
80    break;
81  case 4:
82    // If not good enough could skip postprocessing
83    break;
84  case 5:
85    break;
86  default:
87    abort();
88  }
89  return returnCode;
90}
91#include "CbcEventHandler.hpp"
92/** This is so user can trap events and do useful stuff. 
93
94    CbcModel model_ is available as well as anything else you care
95    to pass in
96*/
97
98class MyEventHandler3 : public CbcEventHandler {
99 
100public:
101  /**@name Overrides */
102  //@{
103  virtual CbcAction event(CbcEvent whichEvent);
104  //@}
105
106  /**@name Constructors, destructor etc*/
107  //@{
108  /** Default constructor. */
109  MyEventHandler3();
110  /// Constructor with pointer to model (redundant as setEventHandler does)
111  MyEventHandler3(CbcModel * model);
112  /** Destructor */
113  virtual ~MyEventHandler3();
114  /** The copy constructor. */
115  MyEventHandler3(const MyEventHandler3 & rhs);
116  /// Assignment
117  MyEventHandler3& operator=(const MyEventHandler3 & rhs);
118  /// Clone
119  virtual CbcEventHandler * clone() const ;
120  //@}
121   
122   
123protected:
124  // data goes here
125};
126//-------------------------------------------------------------------
127// Default Constructor
128//-------------------------------------------------------------------
129MyEventHandler3::MyEventHandler3 () 
130  : CbcEventHandler()
131{
132}
133
134//-------------------------------------------------------------------
135// Copy constructor
136//-------------------------------------------------------------------
137MyEventHandler3::MyEventHandler3 (const MyEventHandler3 & rhs) 
138: CbcEventHandler(rhs)
139{ 
140}
141
142// Constructor with pointer to model
143MyEventHandler3::MyEventHandler3(CbcModel * model)
144  : CbcEventHandler(model)
145{
146}
147
148//-------------------------------------------------------------------
149// Destructor
150//-------------------------------------------------------------------
151MyEventHandler3::~MyEventHandler3 ()
152{
153}
154
155//----------------------------------------------------------------
156// Assignment operator
157//-------------------------------------------------------------------
158MyEventHandler3 &
159MyEventHandler3::operator=(const MyEventHandler3& rhs)
160{
161  if (this != &rhs) {
162    CbcEventHandler::operator=(rhs);
163  }
164  return *this;
165}
166//-------------------------------------------------------------------
167// Clone
168//-------------------------------------------------------------------
169CbcEventHandler * MyEventHandler3::clone() const
170{
171  return new MyEventHandler3(*this);
172}
173
174CbcEventHandler::CbcAction
175MyEventHandler3::event(CbcEvent whichEvent)
176{
177  // If in sub tree carry on
178  if (!model_->parentModel()) {
179    if (whichEvent==solution||whichEvent==heuristicSolution) {
180#ifdef STOP_EARLY
181      return stop; // say finished
182#else
183      // If preprocessing was done solution will be to processed model
184      int numberColumns = model_->getNumCols();
185      const double * bestSolution = model_->bestSolution();
186      assert (bestSolution);
187      printf("value of solution is %g\n",model_->getObjValue());
188      for (int i=0;i<numberColumns;i++) {
189        if (fabs(bestSolution[i])>1.0e-8)
190          printf("%d %g\n",i,bestSolution[i]);
191      }
192      return noAction; // carry on
193#endif
194    } else {
195      return noAction; // carry on
196    }
197  } else {
198      return noAction; // carry on
199  }
200}
201
202int main (int argc, const char *argv[])
203{
204
205  OsiClpSolverInterface solver1;
206  //#define USE_OSI_NAMES
207#ifdef USE_OSI_NAMES
208  // Say we are keeping names (a bit slower this way)
209  solver1.setIntParam(OsiNameDiscipline,1);
210#endif
211  // Read in model using argv[1]
212  // and assert that it is a clean model
213  std::string mpsFileName;
214#if defined(SAMPLEDIR)
215  mpsFileName = SAMPLEDIR "/p0033.mps";
216#else
217  if (argc < 2) {
218    fprintf(stderr, "Do not know where to find sample MPS files.\n");
219    exit(1);
220  }
221#endif
222  if (argc>=2) mpsFileName = argv[1];
223  int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(),"");
224  assert(numMpsReadErrors==0);
225  // Tell solver to return fast if presolve or initial solve infeasible
226  solver1.getModelPtr()->setMoreSpecialOptions(3);
227
228  /* Two ways of doing this depending on whether NEW_STYLE_SOLVER defined.
229     So we need pointer to model.  Old way could use modelA. rather than model->
230   */
231  // Messy code below copied from CbcSolver.cpp
232#ifdef CLP_FAST_CODE
233// force new style solver
234#ifndef NEW_STYLE_SOLVER
235#define NEW_STYLE_SOLVER 1
236#endif
237#else
238// Not new style solver
239#ifndef NEW_STYLE_SOLVER
240#define NEW_STYLE_SOLVER 0
241#endif
242#endif
243#if NEW_STYLE_SOLVER==0
244  // Pass to Cbc initialize defaults
245  CbcModel modelA(solver1);
246  CbcModel * model = &modelA;
247  CbcMain0(modelA);
248  // Event handler
249  MyEventHandler3 eventHandler;
250  model->passInEventHandler(&eventHandler);
251  /* Now go into code for standalone solver
252     Could copy arguments and add -quit at end to be safe
253     but this will do
254  */
255  if (argc>2) {
256    CbcMain1(argc-1,argv+1,modelA,callBack);
257  } else {
258    const char * argv2[]={"driver4","-solve","-quit"};
259    CbcMain1(3,argv2,modelA,callBack);
260  }
261#else
262  CbcSolver control(solver1);
263  // initialize
264  control.fillValuesInSolver();
265  // Event handler
266  MyEventHandler3 eventHandler;
267  CbcModel * model = control.model();
268  model->passInEventHandler(&eventHandler);
269  control.solve (argc-1, argv+1, 1);
270#endif
271  // Solver was cloned so get current copy
272  OsiSolverInterface * solver = model->solver();
273  // Print solution if finished (could get from model->bestSolution() as well
274
275  if (model->bestSolution()) {
276   
277    const double * solution = solver->getColSolution();
278   
279    int iColumn;
280    int numberColumns = solver->getNumCols();
281    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);
282   
283    std::cout<<"--------------------------------------"<<std::endl;
284#ifdef USE_OSI_NAMES
285   
286    for (iColumn=0;iColumn<numberColumns;iColumn++) {
287      double value=solution[iColumn];
288      if (fabs(value)>1.0e-7&&solver->isInteger(iColumn)) 
289        std::cout<<std::setw(6)<<iColumn<<" "<<std::setw(8)<<setiosflags(std::ios::left)<<solver->getColName(iColumn)
290                 <<resetiosflags(std::ios::adjustfield)<<std::setw(14)<<" "<<value<<std::endl;
291    }
292#else
293    // names may not be in current solver - use original
294   
295    for (iColumn=0;iColumn<numberColumns;iColumn++) {
296      double value=solution[iColumn];
297      if (fabs(value)>1.0e-7&&solver->isInteger(iColumn)) 
298        std::cout<<std::setw(6)<<iColumn<<" "<<std::setw(8)<<setiosflags(std::ios::left)<<solver1.getModelPtr()->columnName(iColumn)
299                 <<resetiosflags(std::ios::adjustfield)<<std::setw(14)<<" "<<value<<std::endl;
300    }
301#endif
302    std::cout<<"--------------------------------------"<<std::endl;
303 
304    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);
305  } else {
306    std::cout<<" No solution!"<<std::endl;
307  }
308  return 0;
309}   
Note: See TracBrowser for help on using the repository browser.