/* $Id: iis.cpp 2278 2017-10-02 09:51:14Z forrest $ */ /* Copyright (C) 2003, International Business Machines Corporation and others. All Rights Reserved. This sample program is designed to illustrate programming techniques using CoinLP, has not been thoroughly tested and comes without any warranty whatsoever. You may copy, modify and distribute this sample program without any restrictions whatsoever and without any payment to anyone. */ /* Find an irreducible infeasible subsytem. This is not trying to be fast - this implementation is really trying to find the maximum feasible subsystem */ #include "ClpSimplex.hpp" #include "CoinSort.hpp" #include "CoinHelperFunctions.hpp" #include "CoinTime.hpp" #include int main(int argc, const char *argv[]) { ClpSimplex model; int status; if (argc < 2) { printf("please give a model\n"); status=1; } else { status = model.readMps(argv[1], true); } if (status) exit(10); // check infeasible model.initialSolve(); if (model.problemStatus()==0) { printf("Problem is feasible - nothing to do\n"); exit(11); } double * rowLower = model.rowLower(); double * rowUpper = model.rowUpper(); int numberColumns = model.numberColumns(); int numberRows = model.numberRows(); if (model.numberPrimalInfeasibilities()==1) { const double * rowActivity = model.primalRowSolution(); for (int iRow = 0; iRow < numberRows; iRow++) { if (rowActivity[iRow]rowUpper[iRow]+1.0e-5) { printf("The following one row is the IIS\n"); printf("%d %s\n",iRow,model.getRowName(iRow).c_str()); return 0; } } } // This example only looks at constraints // add infeasibility slacks ClpSimplex model2(model); double time1 = CoinCpuTime(); int nAdded=0; CoinBigIndex * starts = new CoinBigIndex [2*numberRows+1]; int * rows = new int [2*numberRows+1]; double * elements = new double [2*numberRows]; double * newObjective = new double [2*numberRows]; memset(model2.objective(),0,numberColumns*sizeof(double)); for (int iRow = 0; iRow < numberRows; iRow++) { if (rowLower[iRow]>-1.0e30) { rows[nAdded]=iRow; elements[nAdded++]=1.0; } if (rowUpper[iRow]<1.0e30) { rows[nAdded]=iRow; elements[nAdded++]=-1.0; } } rows[nAdded]=-1; // so can test if two slacks for a row starts[0]=0; #define OBJ 10000.0 for (int i=0;i1.0e-5) nextRows[nCandidate++]=iRow; } assert (nCandidate); /* save basis info - we could reduce problem size each time but normally not many passes needed */ unsigned char * statusArray = new unsigned char [numberColumns2+numberRows]; double * solution = new double[numberColumns2]; memcpy(statusArray,model2.statusArray(),numberColumns2+numberRows); memcpy(solution,model2.primalColumnSolution(),numberColumns2*sizeof(double)); double lastObjectiveValue = model2.objectiveValue(); double * objective = model2.objective(); int nSolves=0; int nPass=0; while (outRow>=0) { memcpy(candidateRows,nextRows,nCandidate*sizeof(int)); double sumInf=COIN_DBL_MAX; int nInf=numberColumns2; bool badAccuracy=false; outRow=-1; nPass++; for (int j=0;jlastObjectiveValue+1.0e-1) { if (!badAccuracy) printf("Sum infeasibilities increased from %g to %g! - problems with accuracy\n", lastObjectiveValue/OBJ,model2.objectiveValue()/OBJ); badAccuracy=true; } nSolves++; objective[iColumn0]=OBJ; if (iColumn1>=0) objective[iColumn1]=OBJ; #else // delete and solve double lower=rowLower[iRow]; double upper=rowUpper[iRow]; rowLower[iRow]=-COIN_DBL_MAX; rowUpper[iRow]=COIN_DBL_MAX; model2.primal(1); if (model2.objectiveValue()>lastObjectiveValue+1.0e-1) { if (!badAccuracy) printf("Sum infeasibilities increased from %g to %g! - problems with accuracy\n", lastObjectiveValue/OBJ,model2.objectiveValue()/OBJ); badAccuracy=true; } nSolves++; rowLower[iRow]=lower; rowUpper[iRow]=upper; #endif double objectiveValue = model2.objectiveValue(); if (objectiveValue1.0e-5) n++; } if (objectiveValue>1.0e-6) { if (objectiveValue=0) { #ifdef ZAP_COSTS int iColumn0=-1; int iColumn1=-1; for (int i=0;ilastObjectiveValue+1.0e-1) { if (!badAccuracy) printf("Sum infeasibilities increased from %g to %g on cover solve! - problems with accuracy\n", lastObjectiveValue/OBJ,model2.objectiveValue()/OBJ); badAccuracy=true; } lastObjectiveValue=model2.objectiveValue(); memcpy(statusArray,model2.statusArray(),numberColumns2+numberRows); memcpy(solution,model2.primalColumnSolution(),numberColumns2*sizeof(double)); nCandidate=0; for (int iRow=0;iRow1.0e-6) nextRows[nCandidate++]=iRow; } printf("Pass %d (%d solves, %.2f seconds) - candidate %d (%s) added - infeasibility %g (%d)\n", nPass,nSolves,CoinCpuTime()-time1,outRow, model2.getRowName(outRow).c_str(), model2.objectiveValue()/OBJ,nInf); } } model2=model; model2.deleteRows(nCover,coverRows); // make sure not unbounded memset(model2.objective(),0,numberColumns*sizeof(double)); model2.dual(); printf("The following %d rows cover the IIS\n",nCover); for (int i=0;i