00001
00002
00003
00004 #include "ClpSimplex.hpp"
00005 #include "CoinSort.hpp"
00006 #include <iomanip>
00007
00008 int main (int argc, const char *argv[])
00009 {
00010 ClpSimplex model;
00011 int status;
00012
00013 if (argc<2) {
00014 status=model.readMps("small.mps",true);
00015 } else {
00016 status=model.readMps(argv[1],true);
00017 }
00018 if (status)
00019 exit(10);
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 int originalNumberColumns = model.numberColumns();
00035 int numberRows = model.numberRows();
00036
00037
00038 double * weight = new double [numberRows+originalNumberColumns];
00039 int * sort = new int [numberRows+originalNumberColumns];
00040 int numberSort=0;
00041
00042
00043 bool addSlacks = true;
00044
00045 if (addSlacks) {
00046
00047
00048 int iColumn;
00049 const double * columnLower = model.columnLower();
00050 const double * columnUpper = model.columnUpper();
00051 double * columnSolution = model.primalColumnSolution();
00052
00053 for (iColumn=0;iColumn<originalNumberColumns;iColumn++) {
00054 double value =0.0;
00055 if (columnLower[iColumn]>0.0)
00056 value = columnLower[iColumn];
00057 else if (columnUpper[iColumn]<0.0)
00058 value = columnUpper[iColumn];
00059 columnSolution[iColumn]=value;
00060 }
00061
00062 double * rowSolution = model.primalRowSolution();
00063 memset (rowSolution,0,numberRows*sizeof(double));
00064 model.times(1.0,columnSolution,rowSolution);
00065
00066 int * addStarts = new int [numberRows+1];
00067 int * addRow = new int[numberRows];
00068 double * addElement = new double[numberRows];
00069 const double * lower = model.rowLower();
00070 const double * upper = model.rowUpper();
00071 addStarts[0]=0;
00072 int numberArtificials=0;
00073 double * addCost = new double [numberRows];
00074 const double penalty=1.0e8;
00075 int iRow;
00076 for (iRow=0;iRow<numberRows;iRow++) {
00077 if (lower[iRow]>rowSolution[iRow]) {
00078 addRow[numberArtificials]=iRow;
00079 addElement[numberArtificials]=1.0;
00080 addCost[numberArtificials]=penalty;
00081 numberArtificials++;
00082 addStarts[numberArtificials]=numberArtificials;
00083 } else if (upper[iRow]<rowSolution[iRow]) {
00084 addRow[numberArtificials]=iRow;
00085 addElement[numberArtificials]=-1.0;
00086 addCost[numberArtificials]=penalty;
00087 numberArtificials++;
00088 addStarts[numberArtificials]=numberArtificials;
00089 }
00090 }
00091 model.addColumns(numberArtificials,NULL,NULL,addCost,
00092 addStarts,addRow,addElement);
00093 delete [] addStarts;
00094 delete [] addRow;
00095 delete [] addElement;
00096 delete [] addCost;
00097
00098 numberSort=numberArtificials;
00099 int i;
00100 for (i=0;i<numberSort;i++)
00101 sort[i] = i+originalNumberColumns;
00102 } else {
00103
00104
00105 abort();
00106 }
00107
00108 int numberColumns = model.numberColumns();
00109 const double * columnLower = model.columnLower();
00110 const double * columnUpper = model.columnUpper();
00111 double * fullSolution = model.primalColumnSolution();
00112
00113
00114 int maxPass=100;
00115 int iPass;
00116 double lastObjective=1.0e31;
00117
00118
00119 int smallNumberColumns = min(3*numberRows,numberColumns);
00120 smallNumberColumns = max(smallNumberColumns,3000);
00121
00122 int * whichRows = new int [numberRows];
00123 for (int iRow=0;iRow<numberRows;iRow++)
00124 whichRows[iRow]=iRow;
00125 double originalOffset;
00126 model.getDblParam(ClpObjOffset,originalOffset);
00127
00128 for (iPass=0;iPass<maxPass;iPass++) {
00129 printf("Start of pass %d\n",iPass);
00130
00131 CoinSort_2(sort,sort+numberSort,weight);
00132
00133 ClpSimplex small(&model,numberRows,whichRows,numberSort,sort);
00134
00135 double * rowSolution = model.primalRowSolution();
00136 memset (rowSolution,0,numberRows*sizeof(double));
00137 int iRow,iColumn;
00138
00139 for (iColumn=0;iColumn<numberSort;iColumn++) {
00140 int kColumn = sort[iColumn];
00141 fullSolution[kColumn]=0.0;
00142 }
00143
00144 double offset=0.0;
00145 const double * objective = model.objective();
00146 for (iColumn=0;iColumn<originalNumberColumns;iColumn++)
00147 offset += fullSolution[iColumn]*objective[iColumn];
00148 small.setDblParam(ClpObjOffset,originalOffset-offset);
00149 model.times(1.0,fullSolution,rowSolution);
00150
00151 double * lower = small.rowLower();
00152 double * upper = small.rowUpper();
00153 for (iRow=0;iRow<numberRows;iRow++) {
00154 if (lower[iRow]>-1.0e50)
00155 lower[iRow] -= rowSolution[iRow];
00156 if (upper[iRow]<1.0e50)
00157 upper[iRow] -= rowSolution[iRow];
00158 }
00159
00160
00161
00162
00163
00164
00165 small.primal();
00166
00167 const double * solution = small.primalColumnSolution();
00168 for (iColumn=0;iColumn<numberSort;iColumn++) {
00169 int kColumn = sort[iColumn];
00170 model.setColumnStatus(kColumn,small.getColumnStatus(iColumn));
00171 fullSolution[kColumn]=solution[iColumn];
00172 }
00173 for (iRow=0;iRow<numberRows;iRow++)
00174 model.setRowStatus(iRow,small.getRowStatus(iRow));
00175 memcpy(model.primalRowSolution(),small.primalRowSolution(),
00176 numberRows*sizeof(double));
00177 if ((small.objectiveValue()>lastObjective-1.0e-7&&iPass>5)||
00178 !small.numberIterations()||
00179 iPass==maxPass-1) {
00180
00181 break;
00182 } else {
00183 lastObjective = small.objectiveValue();
00184
00185
00186 memcpy(weight,model.objective(),numberColumns*sizeof(double));
00187 model.transposeTimes(-1.0,small.dualRowSolution(),weight);
00188
00189 for (iColumn=0;iColumn<numberColumns;iColumn++) {
00190 double dj = weight[iColumn];
00191 double value = fullSolution[iColumn];
00192 if (model.getColumnStatus(iColumn)==ClpSimplex::basic)
00193 dj = -1.0e50;
00194 else if (dj<0.0&&value<columnUpper[iColumn])
00195 dj = dj;
00196 else if (dj>0.0&&value>columnLower[iColumn])
00197 dj = -dj;
00198 else if (columnUpper[iColumn]>columnLower[iColumn])
00199 dj = fabs(dj);
00200 else
00201 dj = 1.0e50;
00202 weight[iColumn] = dj;
00203 sort[iColumn] = iColumn;
00204 }
00205
00206 CoinSort_2(weight,weight+numberColumns,sort);
00207 numberSort = smallNumberColumns;
00208 }
00209 }
00210 if (addSlacks) {
00211 int i;
00212 int numberArtificials = numberColumns-originalNumberColumns;
00213 for (i=0;i<numberArtificials;i++)
00214 sort[i] = i + originalNumberColumns;
00215 model.deleteColumns(numberArtificials,sort);
00216 }
00217 delete [] weight;
00218 delete [] sort;
00219 delete [] whichRows;
00220 model.primal(1);
00221 return 0;
00222 }