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

Last change on this file since 1606 was 1606, checked in by forrest, 8 years ago

CbcCompareBase? changed - take out CbcCompareUser?

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