source: trunk/Cbc/examples/longthin.cpp @ 2469

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

formatting

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.4 KB
Line 
1// $Id: longthin.cpp 2469 2019-01-06 23:17:46Z unxusr $
2// Copyright (C) 2005, 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#include <iomanip>
8
9#include "CoinPragma.hpp"
10// For Branch and bound
11#include "OsiSolverInterface.hpp"
12#include "CbcModel.hpp"
13#include "CbcBranchActual.hpp"
14#include "CbcBranchUser.hpp"
15#include "CbcCompareUser.hpp"
16#include "CbcCutGenerator.hpp"
17#include "CbcHeuristicGreedy.hpp"
18#include "CbcSolver2.hpp"
19#include "CoinModel.hpp"
20
21// Cuts
22
23#include "CglProbing.hpp"
24
25#include "CoinTime.hpp"
26
27/************************************************************************
28
29This main program reads in an integer model from an mps file.
30It expects it to be unit coefficients and unit rhs and long and thin
31
32Branching is simple binary branching on integer variables.
33
34*/
35int main(int argc, const char *argv[])
36{
37
38  // Define a Solver for long thin problems
39
40  CbcSolver2 solver1;
41
42  // Read in model using argv[1]
43  // and assert that it is a clean model
44  std::string mpsFileName;
45#if defined(SAMPLEDIR)
46  mpsFileName = SAMPLEDIR "/p0033.mps";
47#else
48  if (argc < 2) {
49    fprintf(stderr, "Do not know where to find sample MPS files.\n");
50    exit(1);
51  }
52#endif
53  if (argc >= 2)
54    mpsFileName = argv[1];
55  int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(), "");
56  if (numMpsReadErrors != 0) {
57    printf("%d errors reading MPS file\n", numMpsReadErrors);
58    return numMpsReadErrors;
59  }
60  double time1 = CoinCpuTime();
61
62  solver1.initialSolve();
63  // Reduce printout
64  solver1.setHintParam(OsiDoReducePrint, true, OsiHintTry);
65
66  OsiSolverInterface *solver2 = &solver1;
67  CbcModel model(*solver2);
68  // Point to solver
69  OsiSolverInterface *solver3 = model.solver();
70  CbcSolver2 *osiclp = dynamic_cast< CbcSolver2 * >(solver3);
71  assert(osiclp);
72  osiclp->initialize(&model, NULL);
73  osiclp->setAlgorithm(2);
74  osiclp->setMemory(1000);
75  // Set up some cut generators and defaults
76  // Probing first as gets tight bounds on continuous
77
78  CglProbing generator1;
79  generator1.setUsingObjective(true);
80  generator1.setMaxPass(3);
81  // Number of unsatisfied variables to look at
82  generator1.setMaxProbe(10);
83  // How far to follow the consequences
84  generator1.setMaxLook(50);
85  // Only look at rows with fewer than this number of elements
86  generator1.setMaxElements(200);
87  generator1.setRowCuts(3);
88
89  // Add in generators
90  // Experiment with -1 and -99 etc
91  model.addCutGenerator(&generator1, -99, "Probing");
92  // Allow rounding heuristic
93
94  CbcRounding heuristic1(model);
95  model.addHeuristic(&heuristic1);
96
97  // And Greedy heuristic
98
99  CbcHeuristicGreedyCover heuristic2(model);
100  // Use original upper and perturb more
101  heuristic2.setAlgorithm(11);
102  model.addHeuristic(&heuristic2);
103
104  // Redundant definition of default branching (as Default == User)
105  CbcBranchUserDecision branch;
106  model.setBranchingMethod(&branch);
107
108  // Definition of node choice
109  CbcCompareUser compare;
110  model.setNodeComparison(compare);
111
112  int iColumn;
113  int numberColumns = solver3->getNumCols();
114  // do pseudo costs
115  CbcObject **objects = new CbcObject *[numberColumns];
116  const CoinPackedMatrix *matrix = solver3->getMatrixByCol();
117  // Column copy
118  const int *columnLength = matrix->getVectorLengths();
119  const double *objective = model.getObjCoefficients();
120  int numberIntegers = 0;
121  for (iColumn = 0; iColumn < numberColumns; iColumn++) {
122    if (solver3->isInteger(iColumn)) {
123      /*  Branching up gets us much closer to an integer solution so we want
124          to encourage up - so we will branch up if variable value > 0.333333.
125          The expected cost of going up obviously depends on the cost of the
126          variable so we just choose pseudo costs to reflect that.  We could also
127          decide to try and use the pseudo costs to make it more likely to branch
128          on a variable with many coefficients.  This leads to the computation below.
129      */
130      double cost = objective[iColumn] * (1.0 + 0.2 * ((double)columnLength[iColumn]));
131      CbcSimpleIntegerPseudoCost *newObject = new CbcSimpleIntegerPseudoCost(&model, iColumn,
132        2.0 * cost, cost);
133      newObject->setMethod(3);
134      objects[numberIntegers++] = newObject;
135    }
136  }
137  model.addObjects(numberIntegers, objects);
138  for (iColumn = 0; iColumn < numberIntegers; iColumn++)
139    delete objects[iColumn];
140  delete[] objects;
141
142  // Do initial solve to continuous
143  model.initialSolve();
144
145  // Do more strong branching if small
146  // Switch off strong branching if wanted
147  model.setNumberStrong(5);
148
149  // say use resolve for strong branching
150  osiclp->setSpecialOptions(16);
151  // We had better allow a lot
152  model.solver()->setIntParam(OsiMaxNumIterationHotStart, 10000);
153  // So use strategy to keep rows
154  osiclp->setStrategy(1);
155
156  // Switch off most output
157  if (model.getNumCols() < 3000) {
158    model.messageHandler()->setLogLevel(1);
159    //model.solver()->messageHandler()->setLogLevel(0);
160  } else {
161    model.messageHandler()->setLogLevel(2);
162    model.solver()->messageHandler()->setLogLevel(1);
163  }
164  //model.setPrintFrequency(50);
165
166  // Do complete search
167  try {
168    model.branchAndBound();
169  } catch (CoinError e) {
170    e.print();
171    if (e.lineNumber() >= 0)
172      std::cout << "This was from a CoinAssert" << std::endl;
173    exit(0);
174  }
175  //void printHowMany();
176  //printHowMany();
177  std::cout << mpsFileName << " took " << CoinCpuTime() - time1 << " seconds, "
178            << model.getNodeCount() << " nodes with objective "
179            << model.getObjValue()
180            << (!model.status() ? " Finished" : " Not finished")
181            << std::endl;
182
183  // Print solution if finished - we can't get names from Osi!
184
185  if (model.getMinimizationObjValue() < 1.0e50) {
186    int numberColumns = model.solver()->getNumCols();
187
188    const double *solution = model.solver()->getColSolution();
189
190    int iColumn;
191    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14);
192
193    std::cout << "--------------------------------------" << std::endl;
194    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
195      double value = solution[iColumn];
196      if (fabs(value) > 1.0e-7 && model.solver()->isInteger(iColumn))
197        std::cout << std::setw(6) << iColumn << " " << value << std::endl;
198    }
199    std::cout << "--------------------------------------" << std::endl;
200
201    std::cout << std::resetiosflags(std::ios::fixed | std::ios::showpoint | std::ios::scientific);
202  }
203  return 0;
204}
Note: See TracBrowser for help on using the repository browser.