| |||||||||||
Repairing infeasibility Description Demonstrates the repairinfeas utility,
prints a relaxation summary and
creates the relaxed subproblem.
Source Files By clicking on a file name, a preview is opened at the bottom of this page.
Repair.java /*********************************************************************** Xpress Optimizer Examples ========================= file repair.c ````````````` Demonstrates the FICO repairinfeas utility. Prints a relaxation summary and creates the relaxed subproblem. (c) 2020-2024 Fair Isaac Corporation ***********************************************************************/ import com.dashoptimization.DefaultMessageListener; import com.dashoptimization.XPRS; import com.dashoptimization.XPRSprob; import java.util.Arrays; public final class Repair { public static void main(String[] args) { if ( args.length > 1 ) throw new IllegalArgumentException("syntax: repair <filename>"); String problem = args.length > 0 ? args[0] : "../data/iisexample"; // Initialize Optimizer try (XPRSprob prob = new XPRSprob(null)) { // Forward messages to screen prob.addMessageListener(DefaultMessageListener::console); // Load problem file and query dimensions prob.readProb(problem, ""); int rows = prob.attributes().getRows(); int cols = prob.attributes().getCols(); // Allocate and set the preference arrays (we give the same // preference to all potential violations) double[] rowPref = new double[rows]; // row preferences double[] groupPref = new double[rows]; // group preferences double[] lbPref = new double[cols]; // lower bound preferences double[] ubPref = new double[cols]; // upper bound preferences Arrays.fill(rowPref, 1.0); Arrays.fill(groupPref, 1.0); Arrays.fill(lbPref, 1.0); Arrays.fill(ubPref, 1.0); // Allocate memory for the infeasibility breakers double[] boundviolations = new double[cols]; double[] rowviolations = new double[rows]; // Call repairinfeas int status = prob.repairWeightedInfeas(rowPref, groupPref, lbPref, ubPref, 'n', 0.001, ""); System.out.printf("Repairinfeas return code (%d): ", status); switch (status) { case 0: System.out.printf("relaxed optimum found%n"); break; case 1: System.out.printf("relaxed problem is infeasible%n"); break; case 2: System.out.printf("relaxed problem is unbounded%n"); break; case 3: System.out.printf("solution of the relaxed problem regarding the original objective is nonoptimal%n"); break; case 4: System.out.printf("error%n"); break; case 5: System.out.printf("numerical instability%n"); break; } int nSets = prob.attributes().getSets(); int nEnts = prob.attributes().getMIPEnts(); // Get solution double[] x = prob.getSolution(); double[] slacks = prob.getSlacks(); // Get the values of the breaker variables generateInfeasibilityBreakers(prob, x, slacks, rowviolations, boundviolations, 1.0e-6); // Print report generateInfeasilityReport(prob, rowviolations, boundviolations); // Repair and save problem applyRepairInfeasResult(prob, rowviolations, boundviolations); prob.writeProb("repaired.lp","lp"); System.out.printf("Repaired problem is written as repaired.lp.%n"); System.out.printf("(Please note that this matrix might show slightly different behaviour then the repairinfeas problem)%n%n"); } } /** This function returns the lower bound for a row. */ private static double getRowLB(XPRSprob prob, int i) { double rhs = prob.getRHS(i); double range = prob.getRHSrange(i); byte type = prob.getRowType(i); switch (type) { case 'L': return XPRS.MINUSINFINITY; case 'E': return rhs; case 'G': return rhs; case 'R': return rhs - range; default: return XPRS.MINUSINFINITY; } } /** This function returns the upper bound for a row. */ private static double getRowUB(XPRSprob prob, int i) { double rhs = prob.getRHS(i); double range = prob.getRHSrange(i); byte type = prob.getRowType(i); switch (type) { case 'L': return rhs; case 'E': return rhs; case 'G': return XPRS.PLUSINFINITY; case 'R': return rhs; default: return XPRS.PLUSINFINITY; } } /** This function sets new lower and upper bounds for a row. */ private static void setRowBounds(XPRSprob prob, int i, double rowLB, double rowUB) { double lb, ub; // Normalize bounds for range constraints (we assume that we // do not attempt to set contradictory bounds). if (rowLB <= rowUB) { lb = rowLB; ub = rowUB; } else { lb = rowUB; ub = rowLB; } // determine row type and set bounds if (lb <= XPRS.MINUSINFINITY && ub >= XPRS.PLUSINFINITY) { prob.chgRowType(i, (byte)'N'); } else if (lb <= XPRS.MINUSINFINITY) { prob.chgRowType(i, (byte)'L'); prob.chgRHS(i, ub); } else if (ub >= XPRS.PLUSINFINITY) { prob.chgRowType(i, (byte)'G'); prob.chgRHS(i, lb); } else if (lb == ub) { prob.chgRowType(i, (byte)'E'); prob.chgRHS(i, ub); } else { prob.chgRowType(i, (byte)'R'); prob.chgRHS(i, ub); prob.chgRHSrange(i, ub - lb); } } /** This function calculates the infeasibilities of a solution * (i.e. the values of the feasibility breakers after a repairinfeas * call) */ private static void generateInfeasibilityBreakers(XPRSprob prob, double[] x, double[] slacks, double[] constraints, double[] bounds, double tolarence) { // Get problem dimensions int rows = prob.attributes().getInputRows(); int cols = prob.attributes().getInputCols(); // Check constraints for (int i = 0; i < rows; i++) { double rhs = prob.getRHS(i); double activity = rhs - slacks[i]; double lb = getRowLB(prob, i); double ub = getRowUB(prob, i); if (activity < lb - tolarence) { // a negative value indicates that the lower bound is relaxed constraints[i] = activity - lb; } else if (activity > ub+tolarence) { // a positive value indicates that the upper bound is relaxed constraints[i] = activity - ub; } else { constraints[i] = 0.0; } } // Check bounds for (int j = 0; j < cols; j++) { double lb = prob.getLB(j); double ub = prob.getUB(j); if (x[j] < lb - tolarence) { // a negative value indicates that the lower bound is relaxed bounds[j] = x[j] - lb; } else if (x[j] > ub + tolarence) { // a positive value indicates that the upper bound is relaxed bounds[j] = x[j] - ub; } else { bounds[j] = 0.0; } } } /** This function just converts a double to a string for reporting, * converting infinity values as "NONE" */ private static String boundToString(double bound) { if (bound > XPRS.MINUSINFINITY && bound < XPRS.PLUSINFINITY) { if (bound >= 0) return String.format(" %.5e", bound); else return String.format("%.5e", bound); } else return " NONE "; } /** Prints a summary of the infeasibily breakers using the already * calculated infeasibities */ private static void generateInfeasilityReport(XPRSprob prob, double[] constraintviolations, double []boundviolations) { double suminf = 0; // Sum if infeasibility int ninf = 0; // Number of violateed rows and columns int rows = prob.attributes().getInputRows(); int cols = prob.attributes().getInputCols(); System.out.printf("%n"); System.out.printf("%n"); System.out.printf("XPRESS-MP FEASIBILITY REPAIR REPORT.%n"); System.out.printf("%n"); System.out.printf("The following constraints were repaired.%n"); System.out.printf("%n"); System.out.printf("Index Name%4s Lower bound Repaired Upper bound Repaired %n", ""); for (int i = 0; i < rows; i++) { if (constraintviolations[i] != 0) { // Get constraint name String name = prob.getRowName(i); double lb = getRowLB(prob, i); double ub = getRowUB(prob, i); suminf += Math.abs(constraintviolations[i]); ninf++; String lbShift, ubShift; if (constraintviolations[i] < 0) { lbShift = boundToString(lb + constraintviolations[i]); ubShift = boundToString(ub); } else { lbShift = boundToString(lb); ubShift = boundToString(ub + constraintviolations[i]); } System.out.printf("%5d %8s %7s %7s %7s %7s%n", i, name, boundToString(lb), lbShift, boundToString(ub), ubShift); } } System.out.printf("%n"); System.out.printf("The following bound constraints were repaired.%n"); System.out.printf("%n"); System.out.printf("Index Name%4s Lower bound Repaired Upper bound Repaired %n", ""); for (int j = 0; j < cols; j++) { if (boundviolations[j] != 0) { // Get column name String name = prob.getColumnName(j); double lb = prob.getLB(j); double ub = prob.getUB(j); suminf += Math.abs(boundviolations[j]); ninf++; String lbShift, ubShift; if (constraintviolations[j] < 0) { lbShift = boundToString(boundviolations[j]); ubShift = boundToString(ub); } else { lbShift = boundToString(lb); ubShift = boundToString(boundviolations[j]); } System.out.printf("%5d %8s %7s %7s %7s %7s%n", j, name, boundToString(lb), lbShift, boundToString(ub), ubShift); } } System.out.printf("%n"); System.out.printf("Sum of Violations %f%n", suminf); System.out.printf("Number of corrections: %d%n", ninf); System.out.printf("%n"); } /** Relaxes the problem given the values of the feasibility breakers. */ private static void applyRepairInfeasResult(XPRSprob prob, double[] constraintviolations, double[] boundviolations) { int rows = prob.attributes().getInputRows(); int cols = prob.attributes().getInputCols(); // Apply changes to rows for (int i = 0; i < rows; i++) { if (constraintviolations[i] != 0) { double lb = getRowLB(prob, i); double ub = getRowUB(prob, i); // Apply relaxation if (constraintviolations[i] > 0) ub += constraintviolations[i]; else lb += constraintviolations[i]; setRowBounds(prob, i, lb, ub); } } // Apply changes to columns for (int j = 0; j < cols; j++) { if (boundviolations[j] != 0) { double lb = prob.getLB(j); double ub = prob.getUB(j); if (boundviolations[j] > 0) prob.chgUB(j, ub + boundviolations[j]); else prob.chgLB(j, lb + boundviolations[j]); } } System.out.printf("%n"); System.out.printf("Problem repaired."); System.out.printf("%n"); } } | |||||||||||
© Copyright 2024 Fair Isaac Corporation. |