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

Last change on this file since 2345 was 2345, checked in by forrest, 20 months ago

ampl with COIN_BIG_INDEX

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