source: trunk/Cbc/examples/driver6.cpp @ 2050

Last change on this file since 2050 was 2050, checked in by forrest, 4 years ago

fix error if orbital not activated and add example

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