source: trunk/Cbc/examples/sos.cpp

Last change on this file was 1898, checked in by stefan, 4 years ago

fixup examples

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.4 KB
Line 
1// $Id: sos.cpp 1898 2013-04-09 18:06:04Z forrest $
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
10#include "CoinPragma.hpp"
11
12// For Branch and bound
13#include "CbcModel.hpp"
14#include "CbcBranchActual.hpp"
15#include "OsiClpSolverInterface.hpp"
16
17// Time
18#include "CoinTime.hpp"
19
20
21/************************************************************************
22
23This main program reads in an integer model from an mps file.
24
25It then tries to find SOS structure
26
27*************************************************************************/
28int main (int argc, const char *argv[])
29{
30 
31  // Define your favorite OsiSolver
32 
33  OsiClpSolverInterface solver1;
34 
35  // Read in model using argv[1]
36  // and assert that it is a clean model
37  std::string mpsFileName;
38#if defined(MIPLIB3DIR)
39  mpsFileName = MIPLIB3DIR "/10teams";
40#else
41  if (argc < 2) {
42    fprintf(stderr, "Do not know where to find miplib3 MPS files.\n");
43    exit(1);
44  }
45#endif
46  if (argc>=2) mpsFileName = argv[1];
47  int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(),"");
48  if( numMpsReadErrors != 0 )
49  {
50     printf("%d errors reading MPS file\n", numMpsReadErrors);
51     return numMpsReadErrors;
52  }
53 
54  int iRow, iColumn;
55  int numberColumns = solver1.getNumCols();
56  int numberRows = solver1.getNumRows();
57  // get row copy
58  const CoinPackedMatrix * matrix = solver1.getMatrixByRow();
59  const double * element = matrix->getElements();
60  const int * column = matrix->getIndices();
61  const CoinBigIndex * rowStart = matrix->getVectorStarts();
62  const int * rowLength = matrix->getVectorLengths();
63  const double * rowLower = solver1.getRowLower();
64  const double * rowUpper = solver1.getRowUpper();
65  const double * columnLower = solver1.getColLower();
66 
67  // Look for possible SOS
68  int numberSOS=0;
69  int * mark = new int[numberColumns];
70  CoinFillN(mark,numberColumns,-1);
71  for (iRow=0;iRow<numberRows;iRow++) {
72    if (rowLower[iRow]==1.0&&rowUpper[iRow]==1.0) {
73      bool goodRow=true;
74      for (int j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
75        int iColumn = column[j];
76        if (element[j]!=1.0||!solver1.isInteger(iColumn)||mark[iColumn]>=0||columnLower[iColumn]) {
77          goodRow=false;
78          break;
79        }
80      }
81      if (goodRow) {
82        // mark all
83        for (int j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
84          int iColumn = column[j];
85          mark[iColumn]=numberSOS;
86        }
87        numberSOS++;
88      }
89    }
90  }
91  std::cout<<numberSOS<<" SOS"<<std::endl;
92  if (!numberSOS)
93    return 0;
94  /*  This example does not look to find the correct order.  SOS are much more
95      powerful if there is a genuine order e.g. size or time.
96
97      There are two pieces of code here.
98      1) Leave integrality conditions and add SOS as extra.  They should have
99      a higher priority.
100      2) Take off integrality conditions and do as SOS of type 2.  This is artificial
101      in this case.
102  */
103  //#define SOS2
104#ifndef SOS2
105  CbcModel model(solver1);
106  // Do sets and priorities
107  CbcObject ** objects = new CbcObject * [numberSOS];
108  int numberIntegers = model.numberIntegers();
109  /* model may not have created objects
110     If none then create
111  */
112  if (!numberIntegers||!model.numberObjects()) {
113    model.findIntegers(true);
114    numberIntegers = model.numberIntegers();
115  }
116  int * priority = new int[numberSOS];
117  // Set SOS priorities high
118  CoinFillN(priority,numberSOS,1);
119  // Set up SOS
120  int * which = new int[numberColumns];
121  for (int iSOS =0;iSOS<numberSOS;iSOS++) {
122    int n=0;
123    for (iColumn=0;iColumn<numberColumns;iColumn++) {
124      if (mark[iColumn]==iSOS)
125        which[n++]=iColumn;
126    }
127    // NULL uses 0,1,2 .. as weights
128    objects[iSOS]= new CbcSOS(&model,n,which,NULL,iSOS,1);
129  }
130#else
131  // take off integers
132    for (iColumn=0;iColumn<numberColumns;iColumn++) 
133      solver1.setContinuous(iColumn);
134  CbcModel model(solver1);
135  // Do sets and priorities
136  CbcObject ** objects = new CbcObject * [numberSOS];
137  // Set up SOS
138  int * which = new int[numberColumns];
139  for (int iSOS =0;iSOS<numberSOS;iSOS++) {
140    int n=0;
141    for (iColumn=0;iColumn<numberColumns;iColumn++) {
142      if (mark[iColumn]==iSOS)
143        which[n++]=iColumn;
144    }
145    // NULL uses 0,1,2 .. as weights
146    objects[iSOS]= new CbcSOS(&model,n,which,NULL,iSOS,2);
147  }
148#endif
149  delete [] mark;
150  delete [] which;
151  model.addObjects(numberSOS,objects);
152  for (iColumn=0;iColumn<numberSOS;iColumn++)
153    delete objects[iColumn];
154  delete [] objects;
155#ifndef SOS2
156  model.passInPriorities(priority,true);
157  delete [] priority;
158#endif
159
160  // If time is given then stop after that number of minutes
161  if (argc>2) {
162    int minutes = atoi(argv[2]);
163    std::cout<<"Stopping after "<<minutes<<" minutes"<<std::endl;
164    assert (minutes>=0);
165    model.setDblParam(CbcModel::CbcMaximumSeconds,60.0*minutes);
166  }
167  // Switch off most output
168  model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
169  if (model.getNumCols()<3000) {
170    model.messageHandler()->setLogLevel(1);
171    //model.solver()->messageHandler()->setLogLevel(0);
172  } else {
173    model.messageHandler()->setLogLevel(2);
174    model.solver()->messageHandler()->setLogLevel(1);
175  }
176  model.messageHandler()->setLogLevel(1);
177 
178  double time1 = CoinCpuTime();
179
180  // Do complete search
181 
182  model.branchAndBound();
183
184  std::cout<<mpsFileName<<" took "<<CoinCpuTime()-time1<<" seconds, "
185           <<model.getNodeCount()<<" nodes with objective "
186           <<model.getObjValue()
187           <<(!model.status() ? " Finished" : " Not finished")
188           <<std::endl;
189
190  // Print solution - we can't get names from Osi!
191
192  if (model.getMinimizationObjValue()<1.0e50) {
193    int numberColumns = model.solver()->getNumCols();
194   
195    const double * solution = model.solver()->getColSolution();
196   
197    int iColumn;
198    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);
199   
200    std::cout<<"--------------------------------------"<<std::endl;
201    for (iColumn=0;iColumn<numberColumns;iColumn++) {
202      double value=solution[iColumn];
203#ifndef SOS2
204      if (fabs(value)>1.0e-7&&model.solver()->isInteger(iColumn)) 
205        std::cout<<std::setw(6)<<iColumn<<" "<<value<<std::endl;
206#else
207      if (fabs(value)>1.0e-7) 
208        std::cout<<std::setw(6)<<iColumn<<" "<<value<<std::endl;
209#endif
210    }
211    std::cout<<"--------------------------------------"<<std::endl;
212 
213    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);
214  }
215  return 0;
216}   
Note: See TracBrowser for help on using the repository browser.