int main(int argc, const char *argv[]) { int numberColumns; int numberRows; FILE * fp; if (argc > 1) { fp = fopen(argv[1], "r"); if (!fp) { fprintf(stderr, "Unable to open file %s\n", argv[1]); exit(1); } } else { fp = fopen("input.130", "r"); if (!fp) { fprintf(stderr, "Unable to open file input.l30 in Samples directory\n"); exit(1); } } int problem; char temp[100]; // read and skip fscanf(fp, "%s", temp); assert(!strcmp(temp, "BEGIN")); fscanf(fp, "%*s %*s %d %d %*s %*s %d %*s", &problem, &numberRows, &numberColumns); // scan down to SUPPLY while (fgets(temp, 100, fp)) { if (!strncmp(temp, "SUPPLY", 6)) break; } if (strncmp(temp, "SUPPLY", 6)) { fprintf(stderr, "Unable to find SUPPLY\n"); exit(2); } // get space for rhs double * lower = new double[numberRows]; double * upper = new double[numberRows]; int i; for (i = 0; i < numberRows; i++) { lower[i] = 0.0; upper[i] = 0.0; } // ***** Remember to convert to C notation while (fgets(temp, 100, fp)) { int row; int value; if (!strncmp(temp, "ARCS", 4)) break; sscanf(temp, "%d %d", &row, &value); upper[row-1] = -value; lower[row-1] = -value; } if (strncmp(temp, "ARCS", 4)) { fprintf(stderr, "Unable to find ARCS\n"); exit(2); } // number of columns may be underestimate int * head = new int[2*numberColumns]; int * tail = new int[2*numberColumns]; int * ub = new int[2*numberColumns]; int * cost = new int[2*numberColumns]; // ***** Remember to convert to C notation numberColumns = 0; while (fgets(temp, 100, fp)) { int iHead; int iTail; int iUb; int iCost; if (!strncmp(temp, "DEMAND", 6)) break; sscanf(temp, "%d %d %d %d", &iHead, &iTail, &iCost, &iUb); iHead--; iTail--; head[numberColumns] = iHead; tail[numberColumns] = iTail; ub[numberColumns] = iUb; cost[numberColumns] = iCost; numberColumns++; } if (strncmp(temp, "DEMAND", 6)) { fprintf(stderr, "Unable to find DEMAND\n"); exit(2); } // ***** Remember to convert to C notation while (fgets(temp, 100, fp)) { int row; int value; if (!strncmp(temp, "END", 3)) break; sscanf(temp, "%d %d", &row, &value); upper[row-1] = value; lower[row-1] = value; } if (strncmp(temp, "END", 3)) { fprintf(stderr, "Unable to find END\n"); exit(2); } printf("Problem %d has %d rows and %d columns\n", problem, numberRows, numberColumns); fclose(fp); ClpSimplex model; // now build model - we have rhs so build columns - two elements // per column double * objective = new double[numberColumns]; double * lowerColumn = new double[numberColumns]; double * upperColumn = new double[numberColumns]; double * element = new double [2*numberColumns]; int * start = new int[numberColumns+1]; int * row = new int[2*numberColumns]; start[numberColumns] = 2 * numberColumns; for (i = 0; i < numberColumns; i++) { start[i] = 2 * i; element[2*i] = -1.0; element[2*i+1] = 1.0; row[2*i] = head[i]; row[2*i+1] = tail[i]; lowerColumn[i] = 0.0; upperColumn[i] = ub[i]; objective[i] = cost[i]; } // Create Packed Matrix CoinPackedMatrix matrix; int * lengths = NULL; matrix.assignMatrix(true, numberRows, numberColumns, 2 * numberColumns, element, row, start, lengths); ClpNetworkMatrix network(matrix); // load model model.loadProblem(network, lowerColumn, upperColumn, objective, lower, upper); delete [] lower; delete [] upper; delete [] head; delete [] tail; delete [] ub; delete [] cost; delete [] objective; delete [] lowerColumn; delete [] upperColumn; delete [] element; delete [] start; delete [] row; /* The confusing flow below is in to exercise both dual and primal when ClpNetworkMatrix storage used. For practical use just one call e.g. model.dual(); would be used. If network then factorization scheme is changed to be much faster. Still not as fast as a real network code, but more flexible */ model.factorization()->maximumPivots(200 + model.numberRows() / 100); model.factorization()->maximumPivots(1000); //model.factorization()->maximumPivots(1); if (model.numberRows() < 50) model.messageHandler()->setLogLevel(63); model.dual(); model.setOptimizationDirection(-1); //model.messageHandler()->setLogLevel(63); model.primal(); model.setOptimizationDirection(1); model.primal(); return 0; }
static int solve(EKKModel * model, int startup, int algorithm, int presolve) { // values pass or not if (startup) startup = 1; // if scaled then be careful bool scaled = ekk_scaling(model) == 1; if (scaled) ekk_scaleRim(model, 1); void * compressInfo = NULL; ClpSimplex * clp; if (!presolve || !presolveInfo) { // no presolve or osl presolve - compact columns compressInfo = ekk_compressModel(model); clp = clpmodel(model, startup);; } else { // pick up clp model clp = presolveInfo->model(); } // don't scale if alreday scaled if (scaled) clp->scaling(false); if (clp->numberRows() > 10000) clp->factorization()->maximumPivots(100 + clp->numberRows() / 100); if (algorithm > 0) clp->primal(startup); else clp->dual(); int numberIterations = clp->numberIterations(); if (presolve && presolveInfo) { // very wasteful - create a clp copy of osl model ClpSimplex * clpOriginal = clpmodel(model, 0); presolveInfo->setOriginalModel(clpOriginal); // do postsolve presolveInfo->postsolve(true); delete clp; delete presolveInfo; presolveInfo = NULL; clp = clpOriginal; if (presolve == 3 || (presolve == 2 && clp->status())) { printf("Resolving from postsolved model\n"); clp->primal(1); numberIterations += clp->numberIterations(); } } // put back solution double * rowDual = (double *) ekk_rowduals(model); int numberRows = ekk_getInumrows(model); int numberColumns = ekk_getInumcols(model); int * rowStatus = (int *) ekk_rowstat(model); double * rowSolution = (double *) ekk_rowacts(model); int i; int * columnStatus = (int *) ekk_colstat(model); double * columnSolution = (double *) ekk_colsol(model); memcpy(rowSolution, clp->primalRowSolution(), numberRows * sizeof(double)); memcpy(rowDual, clp->dualRowSolution(), numberRows * sizeof(double)); for (i = 0; i < numberRows; i++) { if (clp->getRowStatus(i) == ClpSimplex::basic) rowStatus[i] = 0x80000000; else rowStatus[i] = 0; } double * columnDual = (double *) ekk_colrcosts(model); memcpy(columnSolution, clp->primalColumnSolution(), numberColumns * sizeof(double)); memcpy(columnDual, clp->dualColumnSolution(), numberColumns * sizeof(double)); for (i = 0; i < numberColumns; i++) { if (clp->getColumnStatus(i) == ClpSimplex::basic) columnStatus[i] = 0x80000000; else columnStatus[i] = 0; } ekk_setIprobstat(model, clp->status()); ekk_setRobjvalue(model, clp->objectiveValue()); ekk_setInumpinf(model, clp->numberPrimalInfeasibilities()); ekk_setInumdinf(model, clp->numberDualInfeasibilities()); ekk_setIiternum(model, numberIterations); ekk_setRsumpinf(model, clp->sumPrimalInfeasibilities()); ekk_setRsumdinf(model, clp->sumDualInfeasibilities()); delete clp; if (compressInfo) ekk_decompressModel(model, compressInfo); if (scaled) ekk_scaleRim(model, 2); return 0; }
int main(int argc, const char *argv[]) { ClpSimplex model; int status; if (argc < 2) { #if defined(SAMPLEDIR) status = model.readMps(SAMPLEDIR "/p0033.mps", true); #else fprintf(stderr, "Do not know where to find sample MPS files.\n"); exit(1); #endif } else status = model.readMps(argv[1], true); if( status != 0 ) { printf("Error %d reading MPS file\n", status); return status; } /* This driver uses volume algorithm then does dual - after adjusting costs then solves real problem */ // do volume for a bit VOL_problem volprob; const CoinPackedMatrix* mat = model.matrix(); const int psize = mat->getNumCols(); const int dsize = mat->getNumRows(); char * sense = new char[dsize]; double * rhs = new double[dsize]; const double * rowLower = model.rowLower(); const double * rowUpper = model.rowUpper(); // Set the lb/ub on the duals volprob.dsize = dsize; volprob.psize = psize; volprob.dual_lb.allocate(dsize); volprob.dual_ub.allocate(dsize); volprob.dsol.allocate(dsize); int i; for (i = 0; i < dsize; ++i) { if (rowUpper[i] == rowLower[i]) { // 'E': volprob.dual_lb[i] = -1.0e31; volprob.dual_ub[i] = 1.0e31; rhs[i] = rowUpper[i]; sense[i] = 'E'; } else if (rowLower[i] < -0.99e10 && rowUpper[i] < 0.99e10) { // 'L': volprob.dual_lb[i] = -1.0e31; volprob.dual_ub[i] = 0.0; rhs[i] = rowUpper[i]; sense[i] = 'L'; } else if (rowLower[i] > -0.99e10 && rowUpper[i] > 0.99e10) { // 'G': volprob.dual_lb[i] = 0.0; volprob.dual_ub[i] = 1.0e31; rhs[i] = rowLower[i]; sense[i] = 'G'; } else { printf("Volume Algorithm can't work if there is a non ELG row\n"); abort(); } } // Can't use read_param as private // anyway I want automatic use - so maybe this is problem #if 0 FILE* infile = fopen("parameters", "r"); if (!infile) { printf("Failure to open parameter file\n"); } else { volprob.read_params("parameters"); } #endif #if 0 // should save and restore bounds model.tightenPrimalBounds(); #else double * colUpper = model.columnUpper(); for (i = 0; i < psize; i++) colUpper[i] = 1.0; #endif lpHook myHook(model.getColLower(), model.getColUpper(), model.getObjCoefficients(), rhs, sense, *mat); // move duals double * pi = model.dualRowSolution(); memcpy(volprob.dsol.v, pi, dsize * sizeof(double)); volprob.solve(myHook, false /* not warmstart */); // For now stop as not doing any good exit(77); // create objectives int numberRows = model.numberRows(); int numberColumns = model.numberColumns(); memcpy(pi, volprob.dsol.v, numberRows * sizeof(double)); #define MODIFYCOSTS #ifdef MODIFYCOSTS double * saveObj = new double[numberColumns]; memcpy(saveObj, model.objective(), numberColumns * sizeof(double)); memcpy(model.dualColumnSolution(), model.objective(), numberColumns * sizeof(double)); model.clpMatrix()->transposeTimes(-1.0, pi, model.dualColumnSolution()); memcpy(model.objective(), model.dualColumnSolution(), numberColumns * sizeof(double)); const double * rowsol = model.primalRowSolution(); //const double * rowLower = model.rowLower(); //const double * rowUpper = model.rowUpper(); double offset = 0.0; for (i = 0; i < numberRows; i++) { offset += pi[i] * rowsol[i]; } double value2; model.getDblParam(ClpObjOffset, value2); printf("Offset %g %g\n", offset, value2); model.setRowObjective(pi); // zero out pi memset(pi, 0, numberRows * sizeof(double)); #endif // Could put some in basis - only partially tested model.allSlackBasis(); model.factorization()->maximumPivots(1000); //model.setLogLevel(63); // solve model.dual(1); //model.primal(1); #ifdef MODIFYCOSTS memcpy(model.objective(), saveObj, numberColumns * sizeof(double)); // zero out pi memset(pi, 0, numberRows * sizeof(double)); model.setRowObjective(pi); delete [] saveObj; model.primal(); #endif return 0; }