Esempio n. 1
0
    def test_cylp_packaging(self):

        # https://github.com/coin-or/CyLP#modeling-example
        s = CyClpSimplex()

        # Add variables
        x = s.addVariable('x', 3)
        y = s.addVariable('y', 2)

        # Create coefficients and bounds
        A = np.matrix([[1., 2., 0],[1., 0, 1.]])
        B = np.matrix([[1., 0, 0], [0, 0, 1.]])
        D = np.matrix([[1., 2.],[0, 1]])
        a = CyLPArray([5, 2.5])
        b = CyLPArray([4.2, 3])
        x_u= CyLPArray([2., 3.5])

        # Add constraints
        s += A * x <= a
        s += 2 <= B * x + D * y <= b
        s += y >= 0
        s += 1.1 <= x[1:3] <= x_u

        # Set the objective function
        c = CyLPArray([1., -2., 3.])
        s.objective = c * x + 2 * y.sum()

        # Solve using primal Simplex
        s.primal()
        print s.primalVariableSolution['x']
def classical_exactcover_solver(A, w=None, num_threads=4):
    nrows, ncolumns = np.shape(A)
    if w is None:
        w = np.ones(ncolumns)
    assert(len(w) == ncolumns)
    assert(sum(w >= 0))
    model = CyLPModel()
    # Decision variables, one for each cover
    x = model.addVariable('x', ncolumns, isInt=True)
    # Adding the box contraints
    model += 0 <= x <= 1
    # Adding the cover constraints
    # Sum_j x_ij ==  1
    for i in range(nrows):
        model += CyLPArray(A[i,:]) * x == 1
    # Adding the objective function
    model.objective = CyLPArray(w) * x
    lp = CyClpSimplex(model)
    lp.logLevel = 0
    lp.optimizationDirection = 'min'
    mip = lp.getCbcModel()
    mip.logLevel = 0
    # Setting number of threads
    mip.numberThreads = num_threads
    mip.solve()

    return mip.objectiveValue, [int(i) for i in mip.primalVariableSolution['x']]
Esempio n. 3
0
    def test_write(self):
        self.model = CyLPModel()
        model = self.model

        x = model.addVariable('x', 3, isInt=True)
        y = model.addVariable('y', 2)

        A = np.matrix([[1., 2., 0], [1., 0, 1.]])
        B = np.matrix([[1., 0, 0], [0, 0, 1.]])
        D = np.matrix([[1., 2.], [0, 1]])
        a = CyLPArray([5, 2.5])
        b = CyLPArray([4.2, 3])
        x_u = CyLPArray([2., 3.5])

        model.addConstraint(A * x <= a)
        model.addConstraint(2 <= B * x + D * y <= b)
        model.addConstraint(y >= 0)
        model.addConstraint(1.1 <= x[1:3] <= x_u)

        c = CyLPArray([1., -2., 3.])
        model.objective = c * x + 2 * y.sum()

        self.s = CyClpSimplex(model)
        s = self.s

        s.writeMps("cylptest.mps")
        os.remove("cylptest.mps")
        s.writeMps("cylptest.lp")
        os.remove("cylptest.lp")
Esempio n. 4
0
    def test_isInt(self):
        self.model = CyLPModel()
        model = self.model

        x = model.addVariable('x', 3, isInt=True)
        y = model.addVariable('y', 2)

        A = np.matrix([[1., 2., 0], [1., 0, 1.]])
        B = np.matrix([[1., 0, 0], [0, 0, 1.]])
        D = np.matrix([[1., 2.], [0, 1]])
        a = CyLPArray([5, 2.5])
        b = CyLPArray([4.2, 3])
        x_u = CyLPArray([2., 3.5])

        model.addConstraint(A * x <= a)
        model.addConstraint(2 <= B * x + D * y <= b)
        model.addConstraint(y >= 0)
        model.addConstraint(1.1 <= x[1:3] <= x_u)

        c = CyLPArray([1., -2., 3.])
        model.objective = c * x + 2 * y.sum()

        self.s = CyClpSimplex(model)
        s = self.s

        cbcModel = s.getCbcModel()

        cbcModel.branchAndBound()

        sol_x = cbcModel.primalVariableSolution['x']
        self.assertTrue((abs(sol_x - np.array([0, 2, 2])) <= 10**-6).all())
        sol_y = cbcModel.primalVariableSolution['y']
        self.assertTrue((abs(sol_y - np.array([0, 1])) <= 10**-6).all())
Esempio n. 5
0
    def setUp(self):
        'Test remove constraint'

        model = CyLPModel()

        x = model.addVariable('x', 3)
        y = model.addVariable('y', 2)

        A = csc_matrixPlus(([1, 2, 1, 1], ([0, 0, 1, 1], [0, 1, 0, 2])),
                           shape=(2, 3))
        B = csc_matrixPlus(([1, 1], ([0, 1], [0, 2])), shape=(2, 3))
        D = np.matrix([[1., 2.], [0, 1]])
        a = CyLPArray([3, 2.5])
        b = CyLPArray([4.2, 3])
        x_u = CyLPArray([2., 3.5])

        model.addConstraint(A * x <= a, 'res1')
        model.addConstraint(2 <= B * x + D * y <= b, 'res2')
        model.addConstraint(y >= 0)
        model.addConstraint(1.1 <= x[1:3] <= x_u)
        model.addConstraint(x[0] >= 0.1)

        c = CyLPArray([1., -2., 3.])
        model.objective = c * x + 2 * y[0] + 2 * y[1]

        s = CyClpSimplex(model)
        self.s = s
        self.x = x
        self.y = y
    def test_Sparse(self):
        model = CyLPModel()

        x = model.addVariable('x', 3)
        y = model.addVariable('y', 2)

        A = csc_matrixPlus(([1, 2, 1, 1], ([0, 0, 1, 1], [0, 1, 0, 2])),
                           shape=(2, 3))
        B = csc_matrixPlus(([1, 1], ([0, 1], [0, 2])), shape=(2, 3))
        D = np.matrix([[1., 2.], [0, 1]])
        a = CyLPArray([5, 2.5])
        b = CyLPArray([4.2, 3])
        x_u = CyLPArray([2., 3.5])

        model.addConstraint(A * x <= a)
        model.addConstraint(2 <= B * x + D * y <= b)
        model.addConstraint(y >= 0)
        model.addConstraint(1.1 <= x[1:3] <= x_u)

        c = CyLPArray([1., -2., 3.])
        model.objective = c * x + 2 * y[0] + 2 * y[1]

        s = CyClpSimplex(model)

        s.primal()
        sol = np.concatenate(
            (s.primalVariableSolution['x'], s.primalVariableSolution['y']))
        self.assertTrue(
            (abs(sol - np.array([0.2, 2, 1.1, 0, 0.9])) <= 10**-6).all())
Esempio n. 7
0
def f(x, z, y_pos, y_neg, x_0, z_0, x_b=1, z_b=1):
    dim_p = len(x)
    rhs_p = np.array([x_0, z_0, 1], dtype=np.double)
    dim_d = len(rhs_p)

    s_pos = CyClpSimplex()
    u_pos = s_pos.addVariable('u', dim_p)
    l_pos = s_pos.addVariable('l', dim_d)

    s_neg = CyClpSimplex()
    u_neg = s_neg.addVariable('u', dim_p)
    l_neg = s_neg.addVariable('l', dim_d)

    A_p_pos = np.vstack([y_pos, x, z, np.ones(dim_p)])
    A_p_neg = np.vstack([y_neg, x, z, np.ones(dim_p)])

    A_p_pos = np.matrix(A_p_pos)
    A_p_neg = np.matrix(A_p_neg)

    b_p = CyLPArray(np.hstack([0, rhs_p]))
    b_d_pos = CyLPArray(y_pos)
    b_d_neg = CyLPArray(y_neg)

    A_d = np.hstack(
        [x.reshape(-1, 1),
         z.reshape(-1, 1),
         np.ones(len(x)).reshape(-1, 1)])
    A_d = np.matrix(A_d)

    # A_d1 = np.matrix(np.vstack([-rhs_p,np.zeros((3,3))]))
    t = np.array([x_b, z_b, 1], dtype=np.double)
    A_d1 = np.matrix(np.vstack([-t, np.zeros((3, 3))]))

    s_pos += A_p_pos * u_pos + A_d1 * l_pos == b_p
    s_neg += A_p_neg * u_neg + A_d1 * l_neg == b_p

    for i in range(dim_p):
        s_pos += u_pos[i] >= 0
        s_neg += u_neg[i] >= 0

    s_pos += A_d * l_pos <= b_d_pos
    s_neg += A_d * l_neg >= b_d_neg

    s_pos.objective = u_pos[0]
    s_neg.objective = u_neg[0]

    s_pos.primal()
    s_neg.primal()

    cond_pos = s_pos.primalVariableSolution['u']
    yr_pos = np.dot(cond_pos, y_pos)

    cond_neg = s_neg.primalVariableSolution['u']
    yr_neg = np.dot(cond_neg, y_neg)
    return yr_pos + yr_neg, x_0 * z_0, s_pos.getStatusString(
    ), s_neg.getStatusString(
    ), s_pos.primalVariableSolution['l'], s_neg.primalVariableSolution['l']
Esempio n. 8
0
def main():
    if len(sys.argv) != 2:
        print "Invalid number of arguments!\nUsage: \npython ", sys.argv[
            0], " <INPUT_FILE>\n"
        quit()
    infile = sys.argv[1]
    with open(infile) as f:
        m, n = [int(x) for x in next(f).split()
                ]  # m = number of points in X, n = number of points in Y
        e = int(next(f))  # e = number of edges
        incidence_matrix = np.zeros((m, n))
        edge_matrix = np.zeros((m + n, e))
        weights = []
        i = 1
        for line in f:
            a, b, weight = [int(x) for x in line.split()]
            if a > m or b > n:
                print "Invalid vertex id. Aborting!"
                quit()
            incidence_matrix[a - 1][b - 1] = weight
            edge_matrix[a - 1][i - 1] = 1
            edge_matrix[m + b - 1][i - 1] = 1
            weights.append(weight)
            i += 1
        print "Adjacency Matrix:"
        print incidence_matrix
        print "Edge Matrix:"
        print edge_matrix
        print "Weights:"
        print weights
        s = CyClpSimplex()

        # Add variables
        x = s.addVariable('x', e)

        # Create coefficients and bounds
        A = np.matrix(
            edge_matrix[0:m])  # vertices corresponding to the set X (Left)
        B = np.matrix(
            edge_matrix[m:])  # vertices corresponding to the set Y (Right)
        a = CyLPArray(np.ones(m))
        b = CyLPArray(np.ones(n))

        # Add constraints
        s += A * x <= a  # all vertices in set X must be perfectly matched
        s += B * x <= b  # matching should be valid
        s += 0 <= x <= 1

        # Set the objective function
        s.objective = CyLPArray(np.array(weights) * -1) * x

        # Solve using primal Simplex
        s.primal()
        print s.primalVariableSolution['x']
        for i in range(len(s.primalVariableSolution['x'])):
            if s.primalVariableSolution['x'][i] > 1e-3:
                print "Edge ", 1 + i, ": Weight ", weights[i]
Esempio n. 9
0
def solve(A, rhs, ct=None, logLevel=0):
    s = CyClpSimplex()
    s.logLevel = logLevel
    lp_dim = A.shape[1]

    x = s.addVariable('x', lp_dim)
    A = np.matrix(A)
    rhs = CyLPArray(rhs)

    s += A * x >= rhs

    s += x[lp_dim - 1] >= 0
    s.objective = x[lp_dim - 1]
    nnz = np.count_nonzero(A)
    logging.debug(f"TASK SIZE XCOUNT: {lp_dim} GXCOUNT: {len(rhs)}")

    s.primal()
    k = list(s.primalConstraintSolution.keys())[0]
    k2 = list(s.dualConstraintSolution.keys())[0]
    q = s.dualConstraintSolution[k2]
    logging.debug(f"{s.getStatusString()} objective: {s.objectiveValue}")
    logging.debug(
        f"nonzeros rhs: {np.count_nonzero(s.primalConstraintSolution[k])}")
    logging.debug(
        f"nonzeros dual: {np.count_nonzero(s.dualConstraintSolution[k2])}")

    basis = s.getBasisStatus()
    print("Basis[0]")
    print(basis[0])
    print("basis[1]")
    print(basis[1])
    np.savetxt("out", basis[1])

    print("#" * 100)

    s = CyClpSimplex()
    s.logLevel = logLevel
    lp_dim = A.shape[1]

    x = s.addVariable('x', lp_dim)
    A = np.matrix(A)
    rhs = CyLPArray(rhs)

    s += A * x >= rhs

    s += x[lp_dim - 1] >= 0
    s.objective = x[lp_dim - 1]
    nnz = np.count_nonzero(A)
    logging.debug(f"TASK SIZE XCOUNT: {lp_dim} GXCOUNT: {len(rhs)}")

    s.setBasisStatus(*basis)
    s.primal()

    return s.primalVariableSolution['x']
Esempio n. 10
0
 def _to_clp_constr(self, constraint):
     """
     Converts a constraint to a CLP constraint
     """
     if constraint.comparator == Comparator.GREATER_EQUALS:
         return self._to_clp_lin_expr(constraint.lhs) >= CyLPArray(
             constraint.rhs.array)
     elif constraint.comparator == Comparator.EQUALS:
         return self._to_clp_lin_expr(constraint.lhs) == CyLPArray(
             constraint.rhs.array)
     else:
         return self._to_clp_lin_expr(constraint.lhs) <= CyLPArray(
             constraint.rhs.array)
Esempio n. 11
0
    def test_SetInt_CopyIn(self):
        self.model = CyLPModel()
        model = self.model

        x = model.addVariable('x', 3)
        y = model.addVariable('y', 2)

        A = np.matrix([[1., 2., 0],[1., 0, 1.]])
        B = np.matrix([[1., 0, 0], [0, 0, 1.]])
        D = np.matrix([[1., 2.],[0, 1]])
        a = CyLPArray([5, 2.5])
        b = CyLPArray([4.2, 3])
        x_u= CyLPArray([2., 3.5])

        model.addConstraint(A*x <= a)
        model.addConstraint(2 <= B * x + D * y <= b)
        model.addConstraint(y >= 0)
        model.addConstraint(1.1 <= x[1:3] <= x_u)

        c = CyLPArray([1., -2., 3.])
        model.objective = c * x + 2 * y.sum()


        self.s = CyClpSimplex(model)
        s = self.s
        s.setInteger(x[1:3])

        cbcModel = s.getCbcModel()
        cbcModel.branchAndBound()

        sol_x = cbcModel.primalVariableSolution['x']
        self.assertTrue((abs(sol_x -
                        np.array([0.5, 2, 2]) ) <= 10**-6).all())
        sol_y = cbcModel.primalVariableSolution['y']
        self.assertTrue((abs(sol_y -
                        np.array([0, 0.75]) ) <= 10**-6).all())


        s.copyInIntegerInformation(np.array(
                            [True, False, False, False, True], np.uint8))
        cbcModel = s.getCbcModel()
        cbcModel.branchAndBound()

        sol_x = cbcModel.primalVariableSolution['x']
        self.assertTrue((abs(sol_x -
                        np.array([0, 2, 1.1]) ) <= 10**-6).all())
        sol_y = cbcModel.primalVariableSolution['y']
        self.assertTrue((abs(sol_y -
                        np.array([0, 1]) ) <= 10**-6).all())
    def test2(self):
        'Same as test1, but use cylp indirectly.'
        s = CyClpSimplex()

        x = s.addVariable('x', 3)

        A = np.matrix([[1, 2, 3], [1, 1, 1]])
        b = CyLPArray([5, 3])

        s += A * x == b
        s += x >= 0

        s.objective = 1 * x[0] + 1 * x[1] + 1.1 * x[2]

        # Solve it a first time
        s.primal()
        sol = s.primalVariableSolution['x']
        self.assertTrue((abs(sol - np.array([1, 2, 0])) <= 10**-6).all())
        # Add a cut
        s.addConstraint(x[0] >= 1.1)
        s.primal()
        sol = s.primalVariableSolution['x']
        self.assertTrue((abs(sol - np.array([1.1, 1.8, 0.1])) <= 10**-6).all())

        # Change the objective function
        c = csr_matrixPlus([[1, 10, 1.1]]).T
        s.objective = c.T * x
        s.primal()
        sol = s.primalVariableSolution['x']
        self.assertTrue((abs(sol - np.array([2, 0, 1])) <= 10**-6).all())
    def test(self):
        model = CyLPModel()

        x = model.addVariable('x', 3)

        A = np.matrix([[1, 2, 3], [1, 1, 1]])
        b = CyLPArray([5, 3])

        model.addConstraint(A * x == b)
        model.addConstraint(x >= 0)

        model.objective = 1 * x[0] + 1 * x[1] + 1.1 * x[2]

        # Solve it a first time
        s = CyClpSimplex(model)
        s.primal()
        sol = s.primalVariableSolution['x']
        self.assertTrue((abs(sol - np.array([1, 2, 0])) <= 10**-6).all())
        # Add a cut
        s.addConstraint(x[0] >= 1.1)
        s.primal()
        sol = s.primalVariableSolution['x']
        self.assertTrue((abs(sol - np.array([1.1, 1.8, 0.1])) <= 10**-6).all())

        # Change the objective function
        c = csr_matrixPlus([[1, 10, 1.1]]).T
        s.objective = c.T * x
        s.primal()
        sol = s.primalVariableSolution['x']
        self.assertTrue((abs(sol - np.array([2, 0, 1])) <= 10**-6).all())
Esempio n. 14
0
 def _to_clp_lin_expr(self, lin_expr):
     """
     Converts a HIPS linear expression to a CLP linear expression
     """
     return sum(
         CyLPArray(lin_expr.coefficients[var].to_numpy()) *
         self.var_to_clp_var[var.id] for var in lin_expr.vars)
Esempio n. 15
0
def solve(A, rhs, ct=None, logLevel=0, extnd=False, basis=False, mps_file=None):
    s = CyClpSimplex()
    s.logLevel = logLevel
    lp_dim = A.shape[1]

    x = s.addVariable('x', lp_dim)
    A = np.matrix(A)
    rhs = CyLPArray(rhs)

    s += A * x >= rhs

    s += x[lp_dim - 1] >= 0
    s.objective = x[lp_dim - 1]
    nnz = np.count_nonzero(A)
    if not mps_file is None:
        s.writeMps(mps_file)
        return None
    logging.debug(f"TASK SIZE XCOUNT: {lp_dim} GXCOUNT: {len(rhs)}")

    s.primal()
    k = list(s.primalConstraintSolution.keys())[0]
    k2 =list(s.dualConstraintSolution.keys())[0]
    q = s.dualConstraintSolution[k2]
    logging.debug(f"{s.getStatusString()} objective: {s.objectiveValue}")
    logging.debug(f"nonzeros rhs: {np.count_nonzero(s.primalConstraintSolution[k])}")
    logging.debug(f"nonzeros dual: {np.count_nonzero(s.dualConstraintSolution[k2])}")

    if extnd and not basis:
        return s.primalVariableSolution['x'],s.primalConstraintSolution[k],s.dualConstraintSolution[k2]
    elif not extnd and basis:
        basis = s.getBasisStatus()
        return s.primalVariableSolution['x'],*basis
    else:
        return s.primalVariableSolution['x']
Esempio n. 16
0
    def test_add_optimized_gomory_cuts(self):
        node = CuttingPlaneBoundNode(self.cut2_std.lp,
                                     self.cut2_std.integerIndices)
        # check function calls
        with patch.object(node, '_find_gomory_cuts') as fgb, \
                patch.object(node, '_optimize_cut') as oc:
            fgb.return_value = [(CyLPArray([-3.3, -1.2]), -24.1),
                                (CyLPArray([-1.2, -1.8]), -15.4)]
            oc.return_value = -50
            node._add_optimized_gomory_cuts()
            self.assertTrue(fgb.called)
            self.assertTrue(oc.call_count == 2)
            self.assertTrue(len(node.lp.constraints) == 3)

        # check returns
        rtn = super(CuttingPlaneBoundNode, node).bound()
        self.assertTrue(isinstance(rtn, dict), 'should return dict')
Esempio n. 17
0
    def solve_cylp(self, verbose: bool = True, **kwargs):
        """ Inspired by the cvxpy cbc layer, ty :) """
        from cylp.cy import CyClpSimplex
        from cylp.py.modeling.CyLPModel import CyLPModel, CyLPArray

        cons = self.combine_cons()
        n = int(self.next_var_idx - 1)  # Number of variables.

        # Maximize c@x s.t. A@x <= b  (variable bounds done by constraints)
        c = self.objective.rawdense().squeeze()[
            1:n + 1]  # Objective coefficients, no constants.
        A = cons.raw()[:, 1:n + 1]  # Constraint coefficients.
        b = cons[:, 0].rawdense().squeeze() * -1.0  # Constraint constants.

        model = CyLPModel()
        x = model.addVariable("x", n)  # Variables
        model.objective = c

        # I hate this so much. Casting A to a matrix causes A.__mul__ to be
        # be called, which raises NotImplemented, so then x.__rmul__ is called
        # which gets the job done. Using np.matmul or np.dot doesn't
        # trigger x.__rmul__
        # model.addConstraint(np.matrix(A) * x <= CyLPArray(b))  # Works
        model.addConstraint(x.__rmul__(A) <= CyLPArray(b))

        model = CyClpSimplex(model)  # Convert model

        model.logLevel = 0 if not verbose else model.logLevel

        is_integer_model = not np.isclose(self.int_vars.sum(), 0)
        if is_integer_model:
            model.setInteger(x[np.argwhere(self.int_vars)])
            cbcModel = model.getCbcModel()
            cbcModel.solve()
            status = cbcModel.status
            solmodel = cbcModel
        else:
            status = model.initialSolve()
            solmodel = model

        sol_x = np.hstack(  # Pad back to original shape
            (
                [1.0],  # Special constant 1.0 variable.
                solmodel.primalVariableSolution["x"],  # Actual solution
                np.zeros(self.max_vars - n - 1),  # Unused vars
            ))

        solution = {
            "status": status,
            "primal": sol_x,
            "value": solmodel.objectiveValue
        }
        return solution, solution["primal"]
Esempio n. 18
0
    def _find_split_inequality(self: G, idx: int, **kwargs: Any):
        assert idx in self._integer_indices, 'must lift and project on integer index'
        x_idx = self.solution[idx]
        assert self._is_fractional(
            x_idx), "must lift and project on index with fractional value"

        # build the CGLP model from ISE 418 Lecture 15 Slide 7 but for LP with >= constraints
        lp = CyClpSimplex()

        # declare variables
        pi = lp.addVariable('pi', self.lp.nVariables)
        pi0 = lp.addVariable('pi0', 1)
        u1 = lp.addVariable('u1', self.lp.nConstraints)
        u2 = lp.addVariable('u2', self.lp.nConstraints)
        w1 = lp.addVariable('w1', self.lp.nVariables)
        w2 = lp.addVariable('w2', self.lp.nVariables)

        # set bounds
        lp += u1 >= CyLPArray(np.zeros(self.lp.nConstraints))
        lp += u2 >= CyLPArray(np.zeros(self.lp.nConstraints))

        w_ub = CyLPArray(np.zeros(self.lp.nVariables))
        w_ub[idx] = float('inf')
        lp += w_ub >= w1 >= CyLPArray(np.zeros(self.lp.nVariables))
        lp += w_ub >= w2 >= CyLPArray(np.zeros(self.lp.nVariables))

        # set constraints
        # (pi, pi0) must be valid for both parts of the disjunction
        lp += 0 >= -pi + self.lp.coefMatrix.T * u1 - w1
        lp += 0 >= -pi + self.lp.coefMatrix.T * u2 + w2
        lp += 0 <= -pi0 + CyLPArray(
            self.lp.constraintsLower) * u1 - floor(x_idx) * w1.sum()
        lp += 0 <= -pi0 + CyLPArray(
            self.lp.constraintsLower) * u2 + ceil(x_idx) * w2.sum()
        # normalize variables
        lp += u1.sum() + u2.sum() + w1.sum() + w2.sum() == 1

        # set objective: find the deepest cut
        # since pi * x >= pi0 for all x in disjunction, we want min pi * x_star - pi0
        lp.objective = CyLPArray(self.solution) * pi - pi0

        # solve
        lp.primal(startFinishOptions='x')
        assert lp.getStatusCode() == 0, 'we should get optimal solution'
        assert lp.objectiveValue <= 0, 'pi * x >= pi -> pi * x - pi >= 0 -> ' \
                                       'negative objective at x^* since it gets cut off'

        # get solution
        return lp.primalVariableSolution['pi'], lp.primalVariableSolution[
            'pi0']
Esempio n. 19
0
def generate_random_MILPInstance(numVars=40,
                                 numCons=20,
                                 density=0.2,
                                 maxObjCoeff=10,
                                 maxConsCoeff=10,
                                 tightness=2,
                                 rand_seed=2):
    cs, vs, objective, A, b = GenerateRandomMIP(numVars=numVars,
                                                numCons=numCons,
                                                density=density,
                                                maxObjCoeff=maxObjCoeff,
                                                maxConsCoeff=maxConsCoeff,
                                                tightness=tightness,
                                                rand_seed=rand_seed)
    A = np.asmatrix(pd.DataFrame.from_dict(A).to_numpy())
    objective = CyLPArray(list(objective.values()))
    b = CyLPArray(b)
    l = CyLPArray([0] * len(vs))
    u = CyLPArray([maxObjCoeff] * len(vs))
    return MILPInstance(A=A,
                        b=b,
                        c=objective,
                        l=l,
                        u=u,
                        sense=['Max', '<='],
                        integerIndices=list(range(len(vs))),
                        numVars=len(vs))
Esempio n. 20
0
def create_problem(cobra_model, objective_sense="maximize", **kwargs):
    m = cobra_model.to_array_based_model()
    lp = Coin()
    v = lp.addVariable("v", len(m.reactions))
    for i, rxn in enumerate(m.reactions):
        if rxn.variable_kind == "integer":
            lp.setInteger(v[i])
    S = m.S
    v.lower = CyLPArray(m.lower_bounds)
    v.upper = CyLPArray(m.upper_bounds)
    inf = float("inf")
    cons = zip(m.b, m.constraint_sense)
    b_l = CyLPArray([-inf if s == "L" else b for b, s in cons])
    b_u = CyLPArray([inf if s == "G" else b for b, s in cons])
    lp.addConstraint(b_u >= S * v >= b_l, "b")
    lp.objectiveCoefficients = CyLPArray(m.objective_coefficients)
    set_parameter(lp, "objective_sense", objective_sense)
    set_parameter(lp, "tolerance_feasibility", 1e-9)
    lp.logLevel = 0
    for key, value in kwargs.items():
        set_parameter(lp, key, value)
    return lp
def plpd2d(xs, zs, ys, x_0, z_0):
    x, z, y = xs, zs, ys
    dim_p = len(x)
    rhs_p = np.array([x_0, z_0, 1], dtype=np.double)
    dim_d = len(rhs_p)

    s = CyClpSimplex()
    u = s.addVariable('u', dim_p)
    l = s.addVariable('l', dim_d)

    A_p = np.vstack([y, x, z, np.ones(dim_p)])

    A_p = np.matrix(A_p)
    b_p = CyLPArray([0, x_0, z_0, 1])

    A_d = np.hstack(
        [x.reshape(-1, 1),
         z.reshape(-1, 1),
         np.ones(len(x)).reshape(-1, 1)])
    A_d = np.matrix(A_d)
    b_d = CyLPArray(y)

    A_d1 = np.matrix(np.vstack([-rhs_p, np.zeros((3, 3))]))

    s += A_p * u + A_d1 * l == b_p

    s += A_d * l <= b_d

    for i in range(dim_p):
        s += u[i] >= 0

    s.optimizationDirection = 'max'
    s.objective = u[0]
    s.primal()
    cond = s.primalVariableSolution['u']
    y_res = np.dot(cond, y)

    return y_res
Esempio n. 22
0
    def _find_gomory_cuts(self: G) -> List[Tuple[CyLPArray, float]]:
        """Find Gomory Mixed Integer Cuts (GMICs) for this node's solution.
        Defined in Lehigh University ISE 418 lecture 14 slide 18 and 5.31
        in Conforti et al Integer Programming. Assumes Ax >= b and x >= 0.

        Warning: this method does not currently work. It creates some cuts that
        are invalid. Stuck on debugging because I can't spot the difference between
        this and what is referenced above.

        :return: cuts, a list of tuples (pi, pi0) that represent the cut pi*x >= pi0
        """
        cuts = []
        for row_idx in self._row_indices:
            basic_idx = self.lp.basicVariables[row_idx]
            if basic_idx in self._integer_indices and \
                    self._is_fractional(self.solution[basic_idx]):
                f0 = self._get_fraction(self.solution[basic_idx])
                # 0 for basic variables avoids getting small numbers that should be zero
                f = {
                    i: 0 if i in self.lp.basicVariables else
                    self._get_fraction(self.lp.tableau[row_idx, i])
                    for i in self._var_indices
                }
                a = {
                    i: 0 if i in self.lp.basicVariables else
                    self.lp.tableau[row_idx, i]
                    for i in self._var_indices
                }
                # primary variable coefficients in GMI cut
                pi = CyLPArray([
                    f[j] / f0 if f[j] <= f0 and j in self._integer_indices else
                    (1 - f[j]) /
                    (1 - f0) if j in self._integer_indices else a[j] /
                    f0 if a[j] > 0 else -a[j] / (1 - f0)
                    for j in self._var_indices
                ])
                # slack variable coefficients in GMI cut
                pi_slacks = np.array([
                    x / f0 if x > 0 else -x / (1 - f0)
                    for x in self.lp.tableau[row_idx, self.lp.nVariables:]
                ])
                # sub out slack variables for primary variables. Ax >= b =>'s
                # Ax - s = b => s = Ax - b. gomory is pi^T * x + pi_s^T * s >= 1, thus
                # pi^T * x + pi_s^T * (Ax - b) >= 1 => (pi + A^T * pi_s)^T * x >= 1 + pi_s^T * b
                pi += self.lp.coefMatrix.T * pi_slacks
                pi0 = 1 + np.dot(pi_slacks, self.lp.constraintsLower)
                # append pi >= pi0
                cuts.append((pi, pi0))
        return cuts
    def test_multiDim(self):
        from cylp.cy import CyClpSimplex
        from cylp.py.modeling.CyLPModel import CyLPArray
        s = CyClpSimplex()
        x = s.addVariable('x', (5, 3, 6))
        s += 2 * x[2, :, 3].sum() + 3 * x[0, 1, :].sum() >= 5

        s += 0 <= x <= 1
        c = CyLPArray(list(range(18)))

        s.objective = c * x[2, :, :] + c * x[0, :, :]
        s.primal()
        sol = s.primalVariableSolution['x']
        self.assertTrue(abs(sol[0, 1, 0] - 1) <= 10**-6)
        self.assertTrue(abs(sol[2, 0, 3] - 1) <= 10**-6)
Esempio n. 24
0
 def test_init_fails_asserts(self):
     self.assertRaisesRegex(AssertionError, 'must have Ax >= b',
                            CuttingPlaneBoundNode, cut1.lp,
                            cut1.integerIndices)
     l = self.cut1_std.lp.variablesLower.copy()
     l[0] = -10
     self.cut1_std.lp.variablesLower = l
     self.assertRaisesRegex(AssertionError,
                            'must have x >= 0 for all variables',
                            CuttingPlaneBoundNode, self.cut1_std.lp,
                            self.cut1_std.integerIndices)
     s = self.cut2_std.lp.addVariable('s', 1)
     self.cut2_std.lp += s >= CyLPArray([0])
     self.assertRaisesRegex(AssertionError, 'x must be our only variable',
                            CuttingPlaneBoundNode, self.cut2_std.lp,
                            self.cut2_std.integerIndices)
def branch_and_bound(G, num_threads=4):
    N = len(G)
    model = CyLPModel()
    # Decision variables, one for each node
    x = model.addVariable('x', N, isInt=True)
    # Adjacency matrix (possibly weighted)
    W = nx.to_numpy_matrix(G)
    z_ind = dict()
    ind = 0
    w = []
    for i in range(N):
        j_range = range(N)
        if (not nx.is_directed(G)):
            # Reduced range for undirected graphs
            j_range = range(i, N)
        for j in j_range:
            if (W[i,j] == 0):
                continue
            if (i not in z_ind):
                z_ind[i] = dict()  
            z_ind[i][j] = ind
            w.append(W[i,j])
            ind += 1
    # Aux variables, one for each edge
    z = model.addVariable('z', len(w), isInt=True)
    # Adding the box contraints
    model += 0 <= x <= 1
    model += 0 <= z <= 1
    # Adding the cutting constraints
    # If x_i == x_j then z_ij = 0
    # If x_i != x_j then z_ij = 1
    for i in z_ind:
        for j in z_ind[i]:
            model += z[z_ind[i][j]] - x[i] - x[j] <= 0
            model += z[z_ind[i][j]] + x[i] + x[j] <= 2
    # Adding the objective function
    model.objective = CyLPArray(w) * z
    lp = CyClpSimplex(model)
    lp.logLevel = 0
    lp.optimizationDirection = 'max'
    mip = lp.getCbcModel()
    mip.logLevel = 0
    # Setting number of threads
    mip.numberThreads = num_threads
    mip.solve()

    return mip.objectiveValue, [int(i) for i in mip.primalVariableSolution['x']]
    def test_ArrayIndexing(self):
        from cylp.cy import CyClpSimplex
        from cylp.py.modeling.CyLPModel import CyLPArray
        s = CyClpSimplex()
        x = s.addVariable('x', (5, 3, 6))
        s += 2 * x[2, :, 3].sum() + 3 * x[0, 1, :].sum() >= 5

        s += x[1, 2, [0, 3, 5]] - x[2, 1, np.array([1, 2, 4])] == 1
        s += 0 <= x <= 1
        c = CyLPArray(range(18))

        s.objective = c * x[2, :, :] + c * x[0, :, :]
        s.primal()
        sol = s.primalVariableSolution['x']
        self.assertTrue(abs(sol[1, 2, 0] - 1) <= 10**-6)
        self.assertTrue(abs(sol[1, 2, 3] - 1) <= 10**-6)
        self.assertTrue(abs(sol[1, 2, 5] - 1) <= 10**-6)
    def test_onlyBounds2(self):
        s = CyClpSimplex()

        x = s.addVariable('x', 3)
        y = s.addVariable('y', 2)

        s += y >= 1
        s += 2 <= x <= 4

        c = CyLPArray([1., -2., 3.])
        s.objective = c * x + 2 * y[0] + 2 * y[1]

        s.primal()

        sol = np.concatenate(
            (s.primalVariableSolution['x'], s.primalVariableSolution['y']))
        self.assertTrue((abs(sol - np.array([2, 4, 2, 1, 1])) <= 10**-6).all())
Esempio n. 28
0
    def test_multiDim_Cbc_solve(self):
        from cylp.cy import CyClpSimplex
        from cylp.py.modeling.CyLPModel import CyLPArray
        s = CyClpSimplex()
        x = s.addVariable('x', (5, 3, 6))
        s += 2 * x[2, :, 3].sum() + 3 * x[0, 1, :].sum() >= 5.5
        s += 0 <= x <= 2.2
        c = CyLPArray(list(range(18)))
        s.objective = c * x[2, :, :] + c * x[0, :, :]

        s.setInteger(x)

        cbcModel = s.getCbcModel()
        cbcModel.solve()

        sol_x = cbcModel.primalVariableSolution['x']
        self.assertTrue(abs(sol_x[0, 1, 0] - 1) <= 10**-6)
        self.assertTrue(abs(sol_x[2, 0, 3] - 2) <= 10**-6)
Esempio n. 29
0
def generate_random_value_functions(num_probs=40, num_evals=40):
    for prob_num in range(num_probs):
        num_vars = 4
        num_constrs = 2
        density = np.random.uniform(.2, .8)
        max_obj_coef = np.random.randint(10, 100)
        max_const_coef = np.random.randint(10, 100)
        tightness = 15

        # get a random A and objective
        cs, vs, objective, A, b = GenerateRandomMIP(
            numVars=num_vars,
            numCons=num_constrs,
            density=density,
            maxObjCoeff=max_obj_coef,
            maxConsCoeff=max_const_coef,
            tightness=15)
        A = np.asmatrix(pd.DataFrame.from_dict(A).to_numpy())
        objective = CyLPArray(list(objective.values()))
        l = CyLPArray([0] * len(vs))
        u = CyLPArray([max_obj_coef] * len(vs))

        # make a new directory to save all these instances
        fldr = f'example_value_functions/instance_{prob_num}'
        os.mkdir(fldr)

        for eval_num in range(num_evals):
            # make a random b for each evaluation of this instance
            b = CyLPArray([
                np.random.randint(
                    int(num_vars * density * max_const_coef / tightness),
                    int(num_vars * density * max_const_coef / 1.5))
                for i in range(num_constrs)
            ])
            instance = MILPInstance(A=A,
                                    b=b,
                                    c=objective,
                                    l=l,
                                    u=u,
                                    sense=['Max', '<='],
                                    integerIndices=list(range(len(vs))),
                                    numVars=len(vs))
            for i in instance.integerIndices:
                instance.lp.setInteger(i)
            file = f'evaluation_{eval_num}'
            instance.lp.writeMps(f'{os.path.join(fldr, file)}.mps')
Esempio n. 30
0
    def solve(self, objective, constraints, cached_data,
              warm_start, verbose, solver_opts):
        """Returns the result of the call to the solver.

        Parameters
        ----------
        objective : LinOp
            The canonicalized objective.
        constraints : list
            The list of canonicalized cosntraints.
        cached_data : dict
            A map of solver name to cached problem data.
        warm_start : bool
            Not used.
        verbose : bool
            Should the solver print output?
        solver_opts : dict
            Additional arguments for the solver.

        Returns
        -------
        tuple
            (status, optimal value, primal, equality dual, inequality dual)
        """
        # Import basic modelling tools of cylp
        from cylp.cy import CyClpSimplex
        from cylp.py.modeling.CyLPModel import CyLPModel, CyLPArray

        # Get problem data
        data = self.get_problem_data(objective, constraints, cached_data)

        c = data[s.C]
        b = data[s.B]
        A = data[s.A]
        dims = data[s.DIMS]
        data[s.BOOL_IDX] = solver_opts[s.BOOL_IDX]
        data[s.INT_IDX] = solver_opts[s.INT_IDX]

        n = c.shape[0]

        # Problem
        model = CyLPModel()

        # Variables
        x = model.addVariable('x', n)

        # Constraints
        # eq
        model += A[0:dims[s.EQ_DIM], :] * x == CyLPArray(b[0:dims[s.EQ_DIM]])

        # leq
        leq_start = dims[s.EQ_DIM]
        leq_end = dims[s.EQ_DIM] + dims[s.LEQ_DIM]
        model += A[leq_start:leq_end, :] * x <= CyLPArray(b[leq_start:leq_end])

        # Objective
        model.objective = c

        # Convert model
        model = CyClpSimplex(model)

        # No boolean vars available in Cbc -> model as int + restrict to [0,1]
        if self.is_mip(data):
            # Mark integer- and binary-vars as "integer"
            model.setInteger(x[data[s.BOOL_IDX]])
            model.setInteger(x[data[s.INT_IDX]])

            # Restrict binary vars only
            idxs = data[s.BOOL_IDX]
            n_idxs = len(idxs)

            model.setColumnLowerSubset(np.arange(n_idxs, dtype=np.int32),
                                       np.array(idxs, np.int32),
                                       np.zeros(n_idxs))

            model.setColumnUpperSubset(np.arange(n_idxs, dtype=np.int32),
                                       np.array(idxs, np.int32),
                                       np.ones(n_idxs))

        # Verbosity Clp
        if not verbose:
            model.logLevel = 0

        # Build model & solve
        status = None
        if self.is_mip(data):
            # Convert model
            cbcModel = model.getCbcModel()

            # Verbosity Cbc
            if not verbose:
                cbcModel.logLevel = 0

            # cylp: /cylp/cy/CyCbcModel.pyx#L134
            # Call CbcMain. Solve the problem using the same parameters used by
            # CbcSolver. Equivalent to solving the model from the command line
            # using cbc's binary.
            cbcModel.solve()
            status = cbcModel.status
        else:
            # cylp: /cylp/cy/CyClpSimplex.pyx
            # Run CLP's initialSolve. It does a presolve and uses primal or dual
            # Simplex to solve a problem.
            status = model.initialSolve()

        results_dict = {}
        results_dict["status"] = status

        if self.is_mip(data):
            results_dict["x"] = cbcModel.primalVariableSolution['x']
            results_dict["obj_value"] = cbcModel.objectiveValue
        else:
            results_dict["x"] = model.primalVariableSolution['x']
            results_dict["obj_value"] = model.objectiveValue

        return self.format_results(results_dict, data, cached_data)