source: trunk/Cbc/examples/sample1.cpp @ 2496

Last change on this file since 2496 was 2469, checked in by unxusr, 9 months ago

formatting

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.1 KB
Line 
1// $Id: sample1.cpp 2469 2019-01-06 23:17:46Z forrest $
2// Copyright (C) 2002, 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#include <cassert>
7
8#include "CbcConfig.h"
9#include "CoinPragma.hpp"
10
11// For Branch and bound
12#include "OsiSolverInterface.hpp"
13#include "CbcModel.hpp"
14
15#include "OsiClpSolverInterface.hpp"
16#include "ClpPresolve.hpp"
17#include "CbcCompareUser.hpp"
18#include "CglProbing.hpp"
19
20//#############################################################################
21
22#ifdef NDEBUG
23#undef NDEBUG
24#endif
25// Time
26
27#include <time.h>
28#if !defined(_MSC_VER)
29#include <sys/times.h>
30#include <sys/resource.h>
31#include <unistd.h>
32#endif
33static double cpuTime()
34{
35  double cpu_temp;
36#if defined(_MSC_VER)
37  unsigned int ticksnow; /* clock_t is same as int */
38
39  ticksnow = (unsigned int)clock();
40
41  cpu_temp = (double)((double)ticksnow / CLOCKS_PER_SEC);
42#else
43  struct rusage usage;
44  getrusage(RUSAGE_SELF, &usage);
45  cpu_temp = (double)usage.ru_utime.tv_sec;
46  cpu_temp += 1.0e-6 * ((double)usage.ru_utime.tv_usec);
47#endif
48  return cpu_temp;
49}
50
51/************************************************************************
52
53This main program reads in an integer model from an mps file.
54
55It then sets up some Cgl cut generators and calls branch and cut.
56
57Branching is simple binary branching on integer variables.
58
59Node selection is depth first until first solution is found and then
60based on objective and number of unsatisfied integer variables.
61
62Variable branching selection is on maximum minimum-of-up-down change
63after strong branching on 5 variables closest to 0.5.
64
65A simple rounding heuristic is used.
66
67Any cut generators based on Cgl can be added in same way
68
69You may also wish to look at CbcModel.hpp
70
71
72************************************************************************/
73
74int main(int argc, const char *argv[])
75{
76
77  // Define your favorite OsiSolver
78
79  ClpSimplex simplex;
80  double time0 = cpuTime();
81  double time1 = time0;
82  double time2;
83
84  // Read in model using argv[1]
85  // and assert that it is a clean model
86
87  if (argc <= 1) {
88    printf("using %s <modelfile>\n", argv[0]);
89    return 1;
90  }
91  int numMpsReadErrors = simplex.readMps(argv[1], "");
92  if (numMpsReadErrors != 0) {
93    printf("%d errors reading MPS file\n", numMpsReadErrors);
94    return numMpsReadErrors;
95  }
96  time2 = cpuTime();
97  std::cout << "Input took " << time2 - time1 << " seconds" << std::endl;
98  ;
99  time1 = time2;
100  // Should work with OsiPresolve but not sure - so this is complicated
101  ClpPresolve pinfo;
102  ClpSimplex *simplex2 = pinfo.presolvedModel(simplex, 1.0e-8);
103  time2 = cpuTime();
104  std::cout << "Presolve took " << time2 - time1 << " seconds" << std::endl;
105  ;
106  time1 = time2;
107  if (!simplex2 || !simplex2->integerInformation()) {
108    std::cout << "Please use a feasible problem which has integers after presolve" << std::endl;
109    exit(77);
110  }
111  OsiClpSolverInterface solver1(simplex2);
112  solver1.writeMps("bad2");
113  // Do initial solve to continuous
114  solver1.initialSolve();
115  time2 = cpuTime();
116  std::cout << "Continuous solve took " << time2 - time1 << " seconds" << std::endl;
117  ;
118  time1 = time2;
119  solver1.messageHandler()->setLogLevel(0);
120  CbcModel model(solver1);
121  // Definition of node choice
122  CbcCompareUser compare;
123  model.setNodeComparison(compare);
124
125  // Maybe probing due to very large coefficients
126
127  CglProbing generator1;
128  generator1.setUsingObjective(true);
129  generator1.setMaxPass(3);
130  generator1.setMaxProbe(100);
131  generator1.setMaxLook(50);
132  generator1.setRowCuts(3);
133
134  // Add in generators
135  // model.addCutGenerator(&generator1,-1,"Probing");
136  // Switch off strong branching if wanted
137  model.setNumberStrong(0);
138  model.solver()->setIntParam(OsiMaxNumIterationHotStart, 100);
139  //model.solver()->setHintParam(OsiDoScale,false,OsiHintTry);
140  // Switch off most output
141  if (model.getNumCols() < 3000) {
142    model.messageHandler()->setLogLevel(1);
143    model.solver()->messageHandler()->setLogLevel(0);
144  } else {
145    model.messageHandler()->setLogLevel(2);
146    model.solver()->messageHandler()->setLogLevel(1);
147  }
148
149  // Do complete search
150
151  model.branchAndBound();
152  time2 = cpuTime();
153  std::cout << "Search took " << time2 - time1 << " seconds" << std::endl;
154  // as we made such a mess of presolve lets be safe
155  OsiClpSolverInterface *clpSolver
156    = dynamic_cast< OsiClpSolverInterface * >(model.solver());
157  assert(clpSolver);
158  ClpSimplex *clp = clpSolver->getModelPtr();
159  *simplex2 = *clp;
160  pinfo.postsolve(true);
161  time1 = time2;
162  // Fix all integers
163  const int *original = pinfo.originalColumns();
164  double *lower2 = simplex2->columnLower();
165  double *upper2 = simplex2->columnUpper();
166  const char *info2 = simplex2->integerInformation();
167  double *lower = simplex.columnLower();
168  double *upper = simplex.columnUpper();
169  int i;
170  for (i = 0; i < simplex2->numberColumns(); i++) {
171    if (info2[i]) {
172      int iSeq = original[i];
173      upper[iSeq] = upper2[i];
174      lower[iSeq] = lower2[i];
175    }
176  }
177
178  simplex.primal();
179  time2 = cpuTime();
180  std::cout << "Cleanup took " << time2 - time1 << " seconds" << std::endl;
181  ;
182  std::cout << "Total time " << time2 - time0 << " seconds" << std::endl;
183  ;
184  return 0;
185}
Note: See TracBrowser for help on using the repository browser.