File: CoinSolve.cpp

package info (click to toggle)
coinor-cbc 2.9.9+repack1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 7,848 kB
  • ctags: 5,787
  • sloc: cpp: 104,337; sh: 8,921; xml: 2,950; makefile: 520; ansic: 491; awk: 197
file content (375 lines) | stat: -rw-r--r-- 11,118 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
/* $Id: CoinSolve.cpp 1607 2011-03-04 16:15:41Z lou $ */
// Copyright (C) 2007, International Business Machines
// Corporation and others.  All Rights Reserved.
// This code is licensed under the terms of the Eclipse Public License (EPL).


/*! \file CbcSolver.cpp
    \brief Main routine for the cbc stand-alone solver.
*/

#include "CbcConfig.h"
#include "CoinPragma.hpp"
#include "CbcModel.hpp"
#include "OsiClpSolverInterface.hpp"

/*
  We have the following compile-time symbols.

  CBC_OTHER_SOLVER	CoinSolve.cpp, CbcSolver.[cpp,hpp], CbcModel.cpp

    A value of 1 says `cplex'. Other values not defined. The intent with
    cplex is to apply all of cbc's smarts at the root, then hand the problem
    over to cplex to finish. Cplex is not used as an alternate lp solver
    under cbc control.

    Usage in CbcModel is a fake; a small bit of code that's now `#if 0'.


  CLP_DEBUG_MALLOC

    This ties in with the functions clp_malloc, clp_free, and clp_memory,
    which are defined in CoinOslFactorization.cpp. (Right where you'd expect
    to find them, eh?).  Looks to be a relatively nice debugging wrapper for
    standard C malloc.  Calls standard C malloc/free directly if
    CLP_DEBUG_MALLOC is not defined.  Worth consideration for breaking out as
    a separate utility.  The hooks for new and delete defined here should be
    incorporated.

    Absolutely not thread safe --- lots of static variables.

    Hmmm ... is it still the case that standard C malloc and C++ new/delete
    do not play well together? 'Cause the hooks here for new and delete will
    not escape from this file.
*/


#if CBC_OTHER_SOLVER == 1
#  ifndef COIN_HAS_CPX
#    error "Configuration did not detect cplex installation."
#  else
#    include "OsiCpxSolverInterface.hpp"
#  endif
#endif

/*
  Hooks for a debugging wrapper for malloc/free. This bit of definition hooks
  C++ new / delete and diverts them into the debugging wrapper.
*/
//#define CLP_DEBUG_MALLOC
#ifdef CLP_DEBUG_MALLOC
/*extern "C" */void clp_memory(int type);
/*extern "C" */
void * clp_malloc(int length);
/*extern "C" */
void clp_free(void * array);
#include <malloc.h>
#include <exception>
#include <new>
void * operator new (size_t size) throw (std::bad_alloc)
{
    void * p = clp_malloc(size);
    return p;
}
void operator delete (void *p) throw()
{
    clp_free(p);
}
#endif		// CLP_DEBUG_MALLOC

#include <cassert>
#include <cstdio>
#include <cmath>
#include <cfloat>
#include <cstring>
#include <iostream>


// define TEST_MESSAGE_HANDLER to check works on all messages
// #define TEST_MESSAGE_HANDLER
#ifdef TEST_MESSAGE_HANDLER
// This driver shows how to trap messages - this is just as in unitTest.cpp
// ****** THis code is similar to MyMessageHandler.hpp and MyMessagehandler.cpp
#include "CoinMessageHandler.hpp"

/** This just adds a model to CoinMessage and a void pointer so
    user can trap messages and do useful stuff.
    This is used in Clp/Test/unitTest.cpp

    The file pointer is just there as an example of user stuff.

  -- lh 071026 -- An accurate summary. Nothing is actually happening here
  except that messages will be prefixed with "==", which serves the purpose
  of demonstrating that this message handler is active. The extra parameters
  (CbcModel, FILE) are unused.

*/
class CbcModel;

class MyMessageHandler2 : public CoinMessageHandler {

public:
    /**@name Overrides */
    //@{
    virtual int print();
    //@}
    /**@name set and get */
    //@{
    /// Model
    const CbcModel * model() const;
    void setModel(CbcModel * model);
    //@}

    /**@name Constructors, destructor */
    //@{
    /** Default constructor. */
    MyMessageHandler2();
    /// Constructor with pointer to model
    MyMessageHandler2(CbcModel * model,
                      FILE * userPointer = NULL);
    /** Destructor */
    virtual ~MyMessageHandler2();
    //@}

    /**@name Copy method */
    //@{
    /** The copy constructor. */
    MyMessageHandler2(const MyMessageHandler2&);
    /** The copy constructor from an CoinSimplexMessageHandler. */
    MyMessageHandler2(const CoinMessageHandler&);

    MyMessageHandler2& operator=(const MyMessageHandler2&);
    /// Clone
    virtual CoinMessageHandler * clone() const ;
    //@}


protected:
    /**@name Data members
       The data members are protected to allow access for derived classes. */
    //@{
    /// Pointer back to model
    CbcModel * model_;
    //@}
};


//#############################################################################
// Constructors / Destructor / Assignment
//#############################################################################

//-------------------------------------------------------------------
// Default Constructor
//-------------------------------------------------------------------
MyMessageHandler2::MyMessageHandler2 ()
        : CoinMessageHandler(),
        model_(NULL)
{
}

//-------------------------------------------------------------------
// Copy constructor
//-------------------------------------------------------------------
MyMessageHandler2::MyMessageHandler2 (const MyMessageHandler2 & rhs)
        : CoinMessageHandler(rhs),
        model_(rhs.model_)
{
}

MyMessageHandler2::MyMessageHandler2 (const CoinMessageHandler & rhs)
        : CoinMessageHandler(),
        model_(NULL)
{
}

// Constructor with pointer to model
MyMessageHandler2::MyMessageHandler2(CbcModel * model,
                                     FILE * userPointer)
        : CoinMessageHandler(),
        model_(model)
{
}

//-------------------------------------------------------------------
// Destructor
//-------------------------------------------------------------------
MyMessageHandler2::~MyMessageHandler2 ()
{
}

//----------------------------------------------------------------
// Assignment operator
//-------------------------------------------------------------------
MyMessageHandler2 &
MyMessageHandler2::operator=(const MyMessageHandler2 & rhs)
{
    if (this != &rhs) {
        CoinMessageHandler::operator=(rhs);
        model_ = rhs.model_;
    }
    return *this;
}
//-------------------------------------------------------------------
// Clone
//-------------------------------------------------------------------
CoinMessageHandler * MyMessageHandler2::clone() const
{
    return new MyMessageHandler2(*this);
}
int
MyMessageHandler2::print()
{
    // Just add ==
    fprintf(fp_, " == ");
    fprintf(fp_, "%s\n", messageBuffer_);
    return 0;
}
const CbcModel *
MyMessageHandler2::model() const
{
    return model_;
}
void
MyMessageHandler2::setModel(CbcModel * model)
{
    model_ = model;
}
#endif /* TEST_MESSAGE_HANDLER */

//#############################################################################

// To use USERCBC or USERCLP change 0 to 1 in defines and add in your fake main program(s) and any other code
//#define USER_HAS_FAKE_CBC
//#define USER_HAS_FAKE_CLP

#ifdef USER_HAS_FAKE_CBC
#endif
void fakeMain (ClpSimplex & model, OsiSolverInterface & /*osiSolver*/, CbcModel & babSolver)
{
#ifdef USER_HAS_FAKE_CBC
#else
    printf("Dummy user cbc code - model has %d rows and %d columns\n",
           model.getNumRows(), model.getNumCols());
    // Reduce printout
    babSolver.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
    // Do complete search
    babSolver.branchAndBound();
#endif
}

// Clp stuff
#ifdef USER_HAS_FAKE_CLP
#endif
void fakeMain2 (ClpSimplex & /*model*/,
                OsiClpSolverInterface & osiSolver,
                int /*options*/)
{
#ifdef USER_HAS_FAKE_CLP
#else
    ClpSimplex * lpSolver = osiSolver.getModelPtr();
    printf("Dummy user clp code - model has %d rows and %d columns\n",
           lpSolver->numberRows(), lpSolver->numberColumns());
    osiSolver.initialSolve();
#endif
}
//  End any fake main program

//#############################################################################

// void CbcClpUnitTest (const CbcModel & saveModel);

#ifdef CBC_STATISTICS
int osi_crunch = 0;
static int cbc_resolve = 0;
int osi_primal = 0;
int osi_dual = 0;
int osi_hot = 0;
void cbc_resolve_check(const OsiSolverInterface * solver)
{
    cbc_resolve++;
    printf("R %d stats %d %d %d\n",
           cbc_resolve, solver->getNumRows(), solver->getNumCols(),
           solver->getMatrixByCol()->getNumElements());
    if ((cbc_resolve % 1000) == 0)
        printf("RR %d resolve crunch %d primal %d dual %d hot %d\n",
               cbc_resolve, osi_crunch, osi_primal, osi_dual, osi_hot);
}
#endif

int main (int argc, const char *argv[])
{
    int returnCode = 0;
#ifdef CLP_DEBUG_MALLOC
    clp_memory(0);
#endif
    {
#ifndef CBC_OTHER_SOLVER
        OsiClpSolverInterface solver1;
#elif CBC_OTHER_SOLVER==1
        OsiCpxSolverInterface solver1;
#endif
        CbcModel model(solver1);

        // define TEST_MESSAGE_HANDLER at top of file to check works on all messages
#ifdef TEST_MESSAGE_HANDLER
        MyMessageHandler2 messageHandler(&model);
        std::cout << "Testing derived message handler" << std::endl;
        model.passInMessageHandler(&messageHandler);
        OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (model.solver());
        // Could use different handlers (if different log levels)
        clpSolver->passInMessageHandler(&messageHandler);
        //clpSolver->getModelPtr()->passInMessageHandler(&messageHandler);
#endif

        // initialize
        CbcMain0(model);

#ifdef TEST_MESSAGE_HANDLER
        // Set log levels same so can use one message handler
        clpSolver->messageHandler()->setLogLevel(1) ;
        model.messageHandler()->setLogLevel(1);
        // switch off some printing
        void setCbcOrClpPrinting(bool yesNo);
        setCbcOrClpPrinting(false);
#endif

        returnCode = CbcMain1 (argc, argv, model);
    }

#ifdef CLP_DEBUG_MALLOC
    clp_memory(1);
#endif

    if (returnCode != 777) {
        return returnCode;
    } else {
        return 0;
    }
}




/*
  Version 1.00.00 November 16 2005.
  This is to stop me (JJF) messing about too much.
  Tuning changes should be noted here.
  The testing next version may be activated by CBC_NEXT_VERSION
  This applies to OsiClp, Clp etc
  Version 1.00.01 November 24 2005
  Added several classes for advanced users.  This can't affect code (if you don't use it)
  Made some tiny changes (for N way branching) which should not change anything.
  CbcNWay object class - for N way branching this also allows use of CbcConsequence class.
  CbcBranchAllDifferent object class - for branching on general integer variables
  to stop them having same value so branches are x >= y+1 and x <= y-1.
  Added two new Cgl classes - CglAllDifferent which does column fixing (too slowly)
  and CglStored which just has a list of cuts which can be activated.
  Modified preprocess option to SOS
  Version 1.00.02 December 9 2005
  Added use of CbcStrategy to do clean preprocessing
  Added use of referenceSolver for cleaner repetition of Cbc
  Version 1.01.00 February 2 2006
  Added first try at Ampl interface
  Made dummy program so real main can be called from other programs
*/