Example usage for org.apache.commons.math3.optimization.linear SimplexSolver optimize

List of usage examples for org.apache.commons.math3.optimization.linear SimplexSolver optimize

Introduction

In this page you can find the example usage for org.apache.commons.math3.optimization.linear SimplexSolver optimize.

Prototype

public PointValuePair optimize(final LinearObjectiveFunction f, final Collection<LinearConstraint> constraints,
        final GoalType goalType, final boolean restrictToNonNegative) throws MathIllegalStateException 

Source Link

Usage

From source file:edu.byu.nlp.util.Matrices.java

/**
 * Finds an ordering that minimizes the passed-in loss function.
 * Formulates the problem as an instance of the 'assignment problem' 
 * and solves using a linear solver./* w w  w .ja  v a  2 s. c  om*/
 * 
 * @param lossfunction takes as an argument a matrix row, and outputs the 
 * loss associated 
 * 
 * @return a vectors of new row assignments. For example, [0,1,2,3] indicate the trivial re-ordering. 
 */
public static int[] getRowReordering(double[][] mat, RowReorderingLossFunction lossFunction) {
    // In the assignment problem formulation, there will be one variable associated with 
    // each possible row->dst assignment. We calculate the coefficient of each of 
    // these using the passed-in loss function. Our coefficients are therefore a 
    // vectorized form of the loss matrix.
    int n = mat.length;
    double[] objCoeff = new double[n * n];
    for (int src = 0; src < n; src++) {
        for (int dst = 0; dst < n; dst++) {
            double loss = lossFunction.rowAssignmentLoss(mat[src], dst);
            objCoeff[n * src + dst] = loss;
            if (Double.isInfinite(loss) || Double.isNaN(loss)) {
                throw new IllegalArgumentException("loss function returned an invalid number (" + loss + ") "
                        + "when asked to consider \n\trow " + DoubleArrays.toString(mat[src])
                        + " \n\tin position " + dst);
            }
        }
    }

    // objective function
    double offset = 0;
    LinearObjectiveFunction f = new LinearObjectiveFunction(objCoeff, offset);

    // constraints
    Collection<LinearConstraint> constraints = Lists.newArrayList();
    // each src must have exactly one dst 
    for (int src = 0; src < n; src++) {
        double[] constCoeff = DoubleArrays.of(0, n * n);
        Arrays.fill(constCoeff, n * src, n * (src + 1), 1); // single row of 1s
        constraints.add(new LinearConstraint(constCoeff, Relationship.EQ, 1));
    }
    // each dst must have exactly one src
    for (int dst = 0; dst < n; dst++) {
        double[] constCoeff = DoubleArrays.of(0, n * n);
        for (int src = 0; src < n; src++) {
            constCoeff[n * src + dst] = 1; // single col of 1s
        }
        constraints.add(new LinearConstraint(constCoeff, Relationship.EQ, 1));
    }

    // solve
    boolean restrictToNonNegative = true;
    SimplexSolver solver = new SimplexSolver();
    solver.setMaxIterations(10000);
    PointValuePair solution = solver.optimize(f, constraints, GoalType.MINIMIZE, restrictToNonNegative);
    double[] assignmentMatrix = solution.getPoint();

    // the assignment matrix should be very simple; each x is either 0 or 1, 
    // and there is a single 1 per row and column
    // we can deterministically convert this to an int[]
    int[] result = new int[n];
    for (int src = 0; src < n; src++) {
        int rowNonZeroCount = 0;
        for (int dst = 0; dst < n; dst++) {
            double val = assignmentMatrix[n * src + dst];
            if (Math.abs(val - 1) < 1e-6) {
                result[src] = dst;
                rowNonZeroCount++;
            }
        }
        if (rowNonZeroCount != 1) {
            throw new IllegalStateException(
                    "The assignment problem linear solver returned an assignment matrix with "
                            + "invalid entries. This should never happen! Here is the matrix encoded as a vector "
                            + "with rows of length " + n + ":\n\t" + DoubleArrays.toString(assignmentMatrix));
        }
    }
    return result;
}