source: trunk/Clp/examples/sprint2.cpp @ 800

Last change on this file since 800 was 225, checked in by forrest, 16 years ago

This should break everything

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.5 KB
Line 
1// Copyright (C) 2003, International Business Machines
2// Corporation and others.  All Rights Reserved.
3
4#include "ClpSimplex.hpp"
5#include "ClpPresolve.hpp"
6#include "CoinSort.hpp"
7#include <iomanip>
8
9int main (int argc, const char *argv[])
10{
11  ClpSimplex  model;
12  int status;
13  // Keep names
14  if (argc<2) {
15    status=model.readMps("small.mps",true);
16  } else {
17    status=model.readMps(argv[1],true);
18  }
19  if (status)
20    exit(10);
21  /*
22    This driver implements the presolve variation of Sprint.
23    This assumes we can get feasible easily
24  */
25
26  int numberRows = model.numberRows();
27  int numberColumns = model.numberColumns();
28
29  // We will need arrays to choose variables.  These are too big but ..
30  double * weight = new double [numberRows+numberColumns];
31  int * sort = new int [numberRows+numberColumns];
32
33  double * columnLower = model.columnLower();
34  double * columnUpper = model.columnUpper();
35  double * saveLower = new double [numberColumns];
36  memcpy(saveLower,columnLower,numberColumns*sizeof(double));
37  double * saveUpper = new double [numberColumns];
38  memcpy(saveUpper,columnUpper,numberColumns*sizeof(double));
39  // Fix in some magical way so remaining problem is easy
40  // This is from a real-world problem
41  for (int iColumn=0;iColumn<numberColumns;iColumn++) {
42    char firstCharacter = model.columnName(iColumn)[0];
43    if (firstCharacter=='F'||firstCharacter=='P'
44        ||firstCharacter=='L'||firstCharacter=='T') {
45      columnUpper[iColumn]=columnLower[iColumn];
46    }
47  }
48  double * solution = model.primalColumnSolution();
49
50  // Just do this number of passes
51  int maxPass=100;
52  int iPass;
53  double lastObjective=1.0e31;
54
55  // Just take this number of columns in small problem
56  int smallNumberColumns = 3*numberRows;
57  // And we want number of rows to be this
58  int smallNumberRows = numberRows/4;
59
60  for (iPass=0;iPass<maxPass;iPass++) {
61    printf("Start of pass %d\n",iPass);
62    ClpSimplex * model2;
63    ClpPresolve pinfo;
64    int numberPasses=1; // can change this
65    model2 = pinfo.presolvedModel(model,1.0e-8,false,numberPasses,false);
66    if (!model2) {
67      fprintf(stdout,"ClpPresolve says %s is infeasible with tolerance of %g\n",
68              argv[1],1.0e-8);
69      // model was infeasible - maybe try again with looser tolerances
70      model2 = pinfo.presolvedModel(model,1.0e-7,false,numberPasses,false);
71      if (!model2) {
72        fprintf(stdout,"ClpPresolve says %s is infeasible with tolerance of %g\n",
73                argv[1],1.0e-7);
74        exit(2);
75      }
76    }
77    // change factorization frequency from 200
78    model2->setFactorizationFrequency(100+model2->numberRows()/50);
79    model2->primal();
80    pinfo.postsolve(true);
81
82    // adjust smallNumberColumns if necessary
83    if (iPass) {
84      double ratio = ((double) smallNumberRows)/((double) model2->numberRows());
85      smallNumberColumns = (int) (smallNumberColumns*ratio);
86    }
87    delete model2;
88    /* After this postsolve model should be optimal.
89       We can use checkSolution and test feasibility */
90    model.checkSolution();
91    if (model.numberDualInfeasibilities()||
92        model.numberPrimalInfeasibilities()) 
93      printf("%g dual %g(%d) Primal %g(%d)\n",
94             model.objectiveValue(),
95             model.sumDualInfeasibilities(),
96             model.numberDualInfeasibilities(),
97             model.sumPrimalInfeasibilities(),
98             model.numberPrimalInfeasibilities());
99    // Put back true bounds
100    memcpy(columnLower,saveLower,numberColumns*sizeof(double));
101    memcpy(columnUpper,saveUpper,numberColumns*sizeof(double));
102    if ((model.objectiveValue()>lastObjective-1.0e-7&&iPass>5)||
103        iPass==maxPass-1) {
104      break; // finished
105    } else {
106      lastObjective = model.objectiveValue();
107      // now massage weight so all basic in plus good djs
108      for (int iColumn=0;iColumn<numberColumns;iColumn++) {
109        double dj = weight[iColumn];
110        double value = solution[iColumn];
111        if (model.getStatus(iColumn)==ClpSimplex::basic)
112          dj = -1.0e50;
113        else if (dj<0.0&&value<columnUpper[iColumn])
114          dj = dj;
115        else if (dj>0.0&&value>columnLower[iColumn])
116          dj = -dj;
117        else if (columnUpper[iColumn]>columnLower[iColumn])
118          dj = fabs(dj);
119        else
120          dj = 1.0e50;
121        weight[iColumn] = dj;
122        sort[iColumn] = iColumn;
123      }
124      // sort
125      CoinSort_2(weight,weight+numberColumns,sort);
126      // and fix others
127      for (int iColumn=smallNumberColumns;iColumn<numberColumns;iColumn++) {
128        int kColumn = sort[iColumn];
129        double value = solution[kColumn];
130        columnLower[kColumn] = value;
131        columnUpper[kColumn] = value;
132      }
133    }
134  }
135  delete [] weight;
136  delete [] sort;
137  delete [] saveLower;
138  delete [] saveUpper;
139  model.primal(1);
140  return 0;
141}   
Note: See TracBrowser for help on using the repository browser.