source: trunk/Cbc/examples/sos.cpp @ 1468

Last change on this file since 1468 was 1468, checked in by stefan, 11 years ago

do not require CbcConfig?.h in example to decide whether sample or miplib3 is present - do this in makefile

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.3 KB
Line 
1// Copyright (C) 2005, International Business Machines
2// Corporation and others.  All Rights Reserved.
3#if defined(_MSC_VER)
4// Turn off compiler warning about long names
5#  pragma warning(disable:4786)
6#endif
7
8#include <cassert>
9#include <iomanip>
10
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  assert(numMpsReadErrors==0);
49 
50  int iRow, iColumn;
51  int numberColumns = solver1.getNumCols();
52  int numberRows = solver1.getNumRows();
53  // get row copy
54  const CoinPackedMatrix * matrix = solver1.getMatrixByRow();
55  const double * element = matrix->getElements();
56  const int * column = matrix->getIndices();
57  const CoinBigIndex * rowStart = matrix->getVectorStarts();
58  const int * rowLength = matrix->getVectorLengths();
59  const double * rowLower = solver1.getRowLower();
60  const double * rowUpper = solver1.getRowUpper();
61  const double * columnLower = solver1.getColLower();
62 
63  // Look for possible SOS
64  int numberSOS=0;
65  int * mark = new int[numberColumns];
66  CoinFillN(mark,numberColumns,-1);
67  for (iRow=0;iRow<numberRows;iRow++) {
68    if (rowLower[iRow]==1.0&&rowUpper[iRow]==1.0) {
69      bool goodRow=true;
70      for (int j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
71        int iColumn = column[j];
72        if (element[j]!=1.0||!solver1.isInteger(iColumn)||mark[iColumn]>=0||columnLower[iColumn]) {
73          goodRow=false;
74          break;
75        }
76      }
77      if (goodRow) {
78        // mark all
79        for (int j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
80          int iColumn = column[j];
81          mark[iColumn]=numberSOS;
82        }
83        numberSOS++;
84      }
85    }
86  }
87  std::cout<<numberSOS<<" SOS"<<std::endl;
88  if (!numberSOS)
89    return 0;
90  /*  This example does not look to find the correct order.  SOS are much more
91      powerful if there is a genuine order e.g. size or time.
92
93      There are two pieces of code here.
94      1) Leave integrality conditions and add SOS as extra.  They should have
95      a higher priority.
96      2) Take off integrality conditions and do as SOS of type 2.  This is artificial
97      in this case.
98  */
99  //#define SOS2
100#ifndef SOS2
101  CbcModel model(solver1);
102  // Do sets and priorities
103  CbcObject ** objects = new CbcObject * [numberSOS];
104  int numberIntegers = model.numberIntegers();
105  /* model may not have created objects
106     If none then create
107  */
108  if (!numberIntegers||!model.numberObjects()) {
109    model.findIntegers(true);
110    numberIntegers = model.numberIntegers();
111  }
112  int * priority = new int[numberSOS];
113  // Set SOS priorities high
114  CoinFillN(priority,numberSOS,1);
115  // Set up SOS
116  int * which = new int[numberColumns];
117  for (int iSOS =0;iSOS<numberSOS;iSOS++) {
118    int n=0;
119    for (iColumn=0;iColumn<numberColumns;iColumn++) {
120      if (mark[iColumn]==iSOS)
121        which[n++]=iColumn;
122    }
123    // NULL uses 0,1,2 .. as weights
124    objects[iSOS]= new CbcSOS(&model,n,which,NULL,iSOS,1);
125  }
126#else
127  // take off integers
128    for (iColumn=0;iColumn<numberColumns;iColumn++) 
129      solver1.setContinuous(iColumn);
130  CbcModel model(solver1);
131  // Do sets and priorities
132  CbcObject ** objects = new CbcObject * [numberSOS];
133  // Set up SOS
134  int * which = new int[numberColumns];
135  for (int iSOS =0;iSOS<numberSOS;iSOS++) {
136    int n=0;
137    for (iColumn=0;iColumn<numberColumns;iColumn++) {
138      if (mark[iColumn]==iSOS)
139        which[n++]=iColumn;
140    }
141    // NULL uses 0,1,2 .. as weights
142    objects[iSOS]= new CbcSOS(&model,n,which,NULL,iSOS,2);
143  }
144#endif
145  delete [] mark;
146  delete [] which;
147  model.addObjects(numberSOS,objects);
148  for (iColumn=0;iColumn<numberSOS;iColumn++)
149    delete objects[iColumn];
150  delete [] objects;
151#ifndef SOS2
152  model.passInPriorities(priority,true);
153  delete [] priority;
154#endif
155
156  // If time is given then stop after that number of minutes
157  if (argc>2) {
158    int minutes = atoi(argv[2]);
159    std::cout<<"Stopping after "<<minutes<<" minutes"<<std::endl;
160    assert (minutes>=0);
161    model.setDblParam(CbcModel::CbcMaximumSeconds,60.0*minutes);
162  }
163  // Switch off most output
164  model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
165  if (model.getNumCols()<3000) {
166    model.messageHandler()->setLogLevel(1);
167    //model.solver()->messageHandler()->setLogLevel(0);
168  } else {
169    model.messageHandler()->setLogLevel(2);
170    model.solver()->messageHandler()->setLogLevel(1);
171  }
172  model.messageHandler()->setLogLevel(1);
173 
174  double time1 = CoinCpuTime();
175
176  // Do complete search
177 
178  model.branchAndBound();
179
180  std::cout<<mpsFileName<<" took "<<CoinCpuTime()-time1<<" seconds, "
181           <<model.getNodeCount()<<" nodes with objective "
182           <<model.getObjValue()
183           <<(!model.status() ? " Finished" : " Not finished")
184           <<std::endl;
185
186  // Print solution - we can't get names from Osi!
187
188  if (model.getMinimizationObjValue()<1.0e50) {
189    int numberColumns = model.solver()->getNumCols();
190   
191    const double * solution = model.solver()->getColSolution();
192   
193    int iColumn;
194    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);
195   
196    std::cout<<"--------------------------------------"<<std::endl;
197    for (iColumn=0;iColumn<numberColumns;iColumn++) {
198      double value=solution[iColumn];
199#ifndef SOS2
200      if (fabs(value)>1.0e-7&&model.solver()->isInteger(iColumn)) 
201        std::cout<<std::setw(6)<<iColumn<<" "<<value<<std::endl;
202#else
203      if (fabs(value)>1.0e-7) 
204        std::cout<<std::setw(6)<<iColumn<<" "<<value<<std::endl;
205#endif
206    }
207    std::cout<<"--------------------------------------"<<std::endl;
208 
209    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);
210  }
211  return 0;
212}   
Note: See TracBrowser for help on using the repository browser.