source: trunk/Cbc/src/CoinSolve.cpp @ 1573

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

Change to EPL license notice.

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