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

Last change on this file since 741 was 741, checked in by forrest, 12 years ago

event handling

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