source: branches/sandbox/Cbc/src/CoinSolve.cpp @ 1361

Last change on this file since 1361 was 1361, checked in by bjarni, 10 years ago

Added Lou's annotations to Cbc_ampl.cpp, CbcSolver?.cpp, CbcSolver?.hpp, CbcStrategy?.cpp, CbcTreeLocal?.cpp, ClpAmplStuff?.cpp, CoinSolve?.cpp, and unitTestClp.cpp

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.4 KB
Line 
1/* $Id: CoinSolve.cpp 1361 2009-12-04 22:15:40Z bjarni $ */
2// Copyright (C) 2007, International Business Machines
3// Corporation and others.  All Rights Reserved.
4
5/*! \file CbcSolver.cpp
6    \brief Main routine for the cbc stand-alone solver.
7*/
8
9#include "CbcConfig.h"
10#include "CoinPragma.hpp"
11#include "CbcModel.hpp"
12#include "CbcOrClpParam.hpp"
13#include "OsiClpSolverInterface.hpp"
14
15/*
16  We have the following compile-time symbols.
17
18  NEW_STYLE_SOLVER      CoinSolve.cpp, CbcSolver.cpp
19
20    Unclear what this does just yet. A value of 0 seems to be `old style
21    solver'.
22
23
24  CBC_OTHER_SOLVER      CoinSolve.cpp, CbcSolver.[cpp,hpp], CbcModel.cpp
25
26    Usage in CbcSolver.hpp says `other solver' is Cplex (only).
27
28    Here in CoinSolver, CBC_OTHER_SOLVER dominates NEW_STYLE_SOLVER.
29
30    Usage in CbcModel is a fake; a small bit of code that's now `#if 0'.
31
32
33  CPX_KEEP_RESULTS      CoinSolve.cpp, CbcSolver.cpp
34
35    Unclear what this does just yet. The name seems clear, but how / what is
36    affected is not. Defining this symbol forces CBC_OTHER_SOLVER.
37
38
39  CLP_DEBUG_MALLOC
40
41    This ties in with the functions clp_malloc, clp_free, and clp_memory,
42    which are defined in CoinOslFactorization.cpp. (Right where you'd expect
43    to find them, eh?).  Looks to be a relatively nice debugging wrapper for
44    standard C malloc.  Calls standard C malloc/free directly if
45    CLP_DEBUG_MALLOC is not defined.  Worth consideration for breaking out as
46    a separate utility.  The hooks for new and delete defined here should be
47    incorporated.
48
49    Absolutely not thread safe --- lots of static variables.
50
51    Hmmm ... is it still the case that standard C malloc and C++ new/delete
52    do not play well together? 'Cause the hooks here for new and delete will
53    not escape from this file.
54
55*/
56
57
58/*
59  Allow (force?) use of cplex for something.
60*/
61
62#ifdef CPX_KEEP_RESULTS
63#define CBC_OTHER_SOLVER 1
64#endif
65#if CBC_OTHER_SOLVER==1
66#include "OsiCpxSolverInterface.hpp"
67#endif
68
69/*
70  Hooks for a debugging wrapper for malloc/free. This bit of definition hooks
71  C++ new / delete and diverts them into the debugging wrapper.
72*/
73//#define CLP_DEBUG_MALLOC
74#ifdef CLP_DEBUG_MALLOC
75/*extern "C" */void clp_memory(int type);
76/*extern "C" */
77void * clp_malloc(int length);
78/*extern "C" */
79void clp_free(void * array);
80#include <malloc.h>
81#include <exception>
82#include <new>
83void * operator new (size_t size) throw (std::bad_alloc)
84{
85    void * p = clp_malloc(size);
86    return p;
87}
88void operator delete (void *p) throw()
89{
90    clp_free(p);
91}
92#endif          // CLP_DEBUG_MALLOC
93
94#include <cassert>
95#include <cstdio>
96#include <cmath>
97#include <cfloat>
98#include <cstring>
99#include <iostream>
100
101/*
102  The subtleties are unclear, but the gross action is that CBC_OTHER_SOLVER
103  will overrule NEW_STYLE_SOLVER. NEW_STYLE_SOLVER undefined or 0 seems to
104  mean `old style solver'.
105*/
106#ifndef NEW_STYLE_SOLVER
107 #define NEW_STYLE_SOLVER 0
108#endif
109#ifdef CBC_OTHER_SOLVER
110 #undef NEW_STYLE_SOLVER
111 #define NEW_STYLE_SOLVER 0
112#endif
113
114
115
116#if NEW_STYLE_SOLVER == 0
117// define TEST_MESSAGE_HANDLER to check works on all messages
118// #define TEST_MESSAGE_HANDLER
119#ifdef TEST_MESSAGE_HANDLER
120// This driver shows how to trap messages - this is just as in unitTest.cpp
121// ****** THis code is similar to MyMessageHandler.hpp and MyMessagehandler.cpp
122#include "CoinMessageHandler.hpp"
123
124/** This just adds a model to CoinMessage and a void pointer so
125    user can trap messages and do useful stuff.
126    This is used in Clp/Test/unitTest.cpp
127
128    The file pointer is just there as an example of user stuff.
129
130  -- lh 071026 -- An accurate summary. Nothing is actually happening here
131  except that messages will be prefixed with "==", which serves the purpose
132  of demonstrating that this message handler is active. The extra parameters
133  (CbcModel, FILE) are unused.
134
135*/
136class CbcModel;
137
138class MyMessageHandler2 : public CoinMessageHandler {
139
140public:
141    /**@name Overrides */
142    //@{
143    virtual int print();
144    //@}
145    /**@name set and get */
146    //@{
147    /// Model
148    const CbcModel * model() const;
149    void setModel(CbcModel * model);
150    //@}
151
152    /**@name Constructors, destructor */
153    //@{
154    /** Default constructor. */
155    MyMessageHandler2();
156    /// Constructor with pointer to model
157    MyMessageHandler2(CbcModel * model,
158                      FILE * userPointer = NULL);
159    /** Destructor */
160    virtual ~MyMessageHandler2();
161    //@}
162
163    /**@name Copy method */
164    //@{
165    /** The copy constructor. */
166    MyMessageHandler2(const MyMessageHandler2&);
167    /** The copy constructor from an CoinSimplexMessageHandler. */
168    MyMessageHandler2(const CoinMessageHandler&);
169
170    MyMessageHandler2& operator=(const MyMessageHandler2&);
171    /// Clone
172    virtual CoinMessageHandler * clone() const ;
173    //@}
174
175
176protected:
177    /**@name Data members
178       The data members are protected to allow access for derived classes. */
179    //@{
180    /// Pointer back to model
181    CbcModel * model_;
182    //@}
183};
184
185
186//#############################################################################
187// Constructors / Destructor / Assignment
188//#############################################################################
189
190//-------------------------------------------------------------------
191// Default Constructor
192//-------------------------------------------------------------------
193MyMessageHandler2::MyMessageHandler2 ()
194        : CoinMessageHandler(),
195        model_(NULL)
196{
197}
198
199//-------------------------------------------------------------------
200// Copy constructor
201//-------------------------------------------------------------------
202MyMessageHandler2::MyMessageHandler2 (const MyMessageHandler2 & rhs)
203        : CoinMessageHandler(rhs),
204        model_(rhs.model_)
205{
206}
207
208MyMessageHandler2::MyMessageHandler2 (const CoinMessageHandler & rhs)
209        : CoinMessageHandler(),
210        model_(NULL)
211{
212}
213
214// Constructor with pointer to model
215MyMessageHandler2::MyMessageHandler2(CbcModel * model,
216                                     FILE * userPointer)
217        : CoinMessageHandler(),
218        model_(model)
219{
220}
221
222//-------------------------------------------------------------------
223// Destructor
224//-------------------------------------------------------------------
225MyMessageHandler2::~MyMessageHandler2 ()
226{
227}
228
229//----------------------------------------------------------------
230// Assignment operator
231//-------------------------------------------------------------------
232MyMessageHandler2 &
233MyMessageHandler2::operator=(const MyMessageHandler2 & rhs)
234{
235    if (this != &rhs) {
236        CoinMessageHandler::operator=(rhs);
237        model_ = rhs.model_;
238    }
239    return *this;
240}
241//-------------------------------------------------------------------
242// Clone
243//-------------------------------------------------------------------
244CoinMessageHandler * MyMessageHandler2::clone() const
245{
246    return new MyMessageHandler2(*this);
247}
248int
249MyMessageHandler2::print()
250{
251    // Just add ==
252    fprintf(fp_, " == ");
253    fprintf(fp_, "%s\n", messageBuffer_);
254    return 0;
255}
256const CbcModel *
257MyMessageHandler2::model() const
258{
259    return model_;
260}
261void
262MyMessageHandler2::setModel(CbcModel * model)
263{
264    model_ = model;
265}
266#endif /* TEST_MESSAGE_HANDLER */
267
268//#############################################################################
269
270// To use USERCBC or USERCLP change 0 to 1 in defines and add in your fake main program(s) and any other code
271//#define USER_HAS_FAKE_CBC
272//#define USER_HAS_FAKE_CLP
273
274#ifdef USER_HAS_FAKE_CBC
275#endif
276void fakeMain (ClpSimplex & model, OsiSolverInterface & /*osiSolver*/, CbcModel & babSolver)
277{
278#ifdef USER_HAS_FAKE_CBC
279#else
280    printf("Dummy user cbc code - model has %d rows and %d columns\n",
281           model.getNumRows(), model.getNumCols());
282    // Reduce printout
283    babSolver.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
284    // Do complete search
285    babSolver.branchAndBound();
286#endif
287}
288
289// Clp stuff
290#ifdef USER_HAS_FAKE_CLP
291#endif
292void fakeMain2 (ClpSimplex & /*model*/,
293                OsiClpSolverInterface & osiSolver,
294                int /*options*/)
295{
296#ifdef USER_HAS_FAKE_CLP
297#else
298    ClpSimplex * lpSolver = osiSolver.getModelPtr();
299    printf("Dummy user clp code - model has %d rows and %d columns\n",
300           lpSolver->numberRows(), lpSolver->numberColumns());
301    osiSolver.initialSolve();
302#endif
303}
304//  End any fake main program
305
306//#############################################################################
307
308// void CbcClpUnitTest (const CbcModel & saveModel);
309
310#ifdef CBC_STATISTICS
311int osi_crunch = 0;
312static int cbc_resolve = 0;
313int osi_primal = 0;
314int osi_dual = 0;
315int osi_hot = 0;
316void cbc_resolve_check(const OsiSolverInterface * solver)
317{
318    cbc_resolve++;
319    printf("R %d stats %d %d %d\n",
320           cbc_resolve, solver->getNumRows(), solver->getNumCols(),
321           solver->getMatrixByCol()->getNumElements());
322    if ((cbc_resolve % 1000) == 0)
323        printf("RR %d resolve crunch %d primal %d dual %d hot %d\n",
324               cbc_resolve, osi_crunch, osi_primal, osi_dual, osi_hot);
325}
326#endif
327
328int main (int argc, const char *argv[])
329{
330    int returnCode = 0;
331#ifdef CLP_DEBUG_MALLOC
332    clp_memory(0);
333#endif
334    {
335#ifndef CBC_OTHER_SOLVER
336        OsiClpSolverInterface solver1;
337#elif CBC_OTHER_SOLVER==1
338        OsiCpxSolverInterface solver1;
339#endif
340        CbcModel model(solver1);
341
342        // define TEST_MESSAGE_HANDLER at top of file to check works on all messages
343#ifdef TEST_MESSAGE_HANDLER
344        MyMessageHandler2 messageHandler(&model);
345        std::cout << "Testing derived message handler" << std::endl;
346        model.passInMessageHandler(&messageHandler);
347        OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (model.solver());
348        // Could use different handlers (if different log levels)
349        clpSolver->passInMessageHandler(&messageHandler);
350        //clpSolver->getModelPtr()->passInMessageHandler(&messageHandler);
351#endif
352
353        // initialize
354        CbcMain0(model);
355
356#ifdef TEST_MESSAGE_HANDLER
357        // Set log levels same so can use one message handler
358        clpSolver->messageHandler()->setLogLevel(1) ;
359        model.messageHandler()->setLogLevel(1);
360        // switch off some printing
361        void setCbcOrClpPrinting(bool yesNo);
362        setCbcOrClpPrinting(false);
363#endif
364
365        returnCode = CbcMain1 (argc, argv, model);
366    }
367
368#ifdef CLP_DEBUG_MALLOC
369    clp_memory(1);
370#endif
371
372#ifdef CBC_STATISTICS
373#endif
374
375    if (returnCode != 777) {
376        return returnCode;
377    } else {
378        return 0;
379    }
380}
381
382
383
384#else   /* NEW_STYLE_SOLVER */
385
386/*
387  As best I can see, this is not yet fully functional. NEW_STYLE_SOLVER is
388  normally undefined or forced to 0. See CbcSolver.hpp for jjf's thoughts on
389  where this is going (a good direction, in my opinion [lh]).
390*/
391
392#include "CbcSolver.hpp"
393
394/*
395  ClpAmplStuff.cpp
396*/
397void addAmplToCbc(CbcSolver *);
398
399int main (int argc, const char *argv[])
400{
401    int returnCode;
402
403    /*
404      // Only active if malloc switched on in CbcSolver.cpp
405
406      Magic value 0 initialises the package. Anything else dumps statistics.
407    */
408#ifdef CLP_DEBUG_MALLOC
409    clp_memory(0);
410#endif
411
412    // Open a block to ease memory leak checks.
413    {
414        OsiClpSolverInterface solver1;
415        CbcSolver control(solver1);
416        // initialize
417        control.fillValuesInSolver();
418
419#ifdef COIN_HAS_ASL
420        addAmplToCbc(&control);
421#endif
422
423        returnCode = control.solve (argc, argv, 1);
424    }
425#ifdef CLP_DEBUG_MALLOC
426    clp_memory(1);
427#endif
428    return returnCode;
429}
430
431#endif  /* NEW_STYLE_SOLVER */
432
433
434
435/*
436  Version 1.00.00 November 16 2005.
437  This is to stop me (JJF) messing about too much.
438  Tuning changes should be noted here.
439  The testing next version may be activated by CBC_NEXT_VERSION
440  This applies to OsiClp, Clp etc
441  Version 1.00.01 November 24 2005
442  Added several classes for advanced users.  This can't affect code (if you don't use it)
443  Made some tiny changes (for N way branching) which should not change anything.
444  CbcNWay object class - for N way branching this also allows use of CbcConsequence class.
445  CbcBranchAllDifferent object class - for branching on general integer variables
446  to stop them having same value so branches are x >= y+1 and x <= y-1.
447  Added two new Cgl classes - CglAllDifferent which does column fixing (too slowly)
448  and CglStored which just has a list of cuts which can be activated.
449  Modified preprocess option to SOS
450  Version 1.00.02 December 9 2005
451  Added use of CbcStrategy to do clean preprocessing
452  Added use of referenceSolver for cleaner repetition of Cbc
453  Version 1.01.00 February 2 2006
454  Added first try at Ampl interface
455  Made dummy program so real main can be called from other programs
456*/
Note: See TracBrowser for help on using the repository browser.