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

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

Changes to externals to make it easier to generate a new stable. Catches a few
changes in comments down in src.

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