def test(self): m = CyCoinModel() m.addVariable(3, np.array( [0, 1, 2], np.int32), np.array([1., 1., 1.], np.double), 0, 10, 5) m.addVariable(2, np.array( [1,2], np.int32), np.array([5, 2.], np.double), 0, 10, 2) # Add bound for the three constraints (we have two variables) m.setConstraintLower(0, 2.3) m.setConstraintLower(1, 4.5) m.setConstraintLower(0, 1.5) # Add a 4th constraint m.addConstraint(2, np.array([0, 1], np.int32), np.array([1., 1.], np.double), 2, 7) s = CyClpSimplex() # Load the problem from the CyCoinModel s.loadProblemFromCyCoinModel(m) s.primal() self.assertAlmostEqual(s.objectiveValue, 8.7, 7)
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())
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())
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']]
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())
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']
def solve(filename, method): s = CyClpSimplex() s.readMps(filename) s.preSolve(feasibilityTolerance=10 ** -8) #s.useCustomPrimal(1) if method == 'd': pivot = DantzigPivot(s) elif method == 'l': pivot = LIFOPivot(s) elif method == 'm': pivot = MostFrequentPivot(s) elif method == 'p': pivot = PositiveEdgePivot(s) else: print('Unkown solution method.') sys.exit(1) s.setPivotMethod(pivot) #s.setPerturbation(50) start = clock() s.primal() print('Problem solved in %g seconds.' % (clock() - start)) return s.objectiveValue
def solve(filename, method): s = CyClpSimplex() s.readMps(filename) s.preSolve(feasibilityTolerance=10 ** -8) #s.useCustomPrimal(1) if method == 'd': pivot = DantzigPivot(s) elif method == 'l': pivot = LIFOPivot(s) elif method == 'm': pivot = MostFrequentPivot(s) elif method == 'p': pivot = PositiveEdgePivot(s) else: print 'Unkown solution method.' sys.exit(1) s.setPivotMethod(pivot) #s.setPerturbation(50) start = clock() s.primal() print 'Problem solved in %g seconds.' % (clock() - start) return s.objectiveValue
def model(self): A = self.A c = self.c s = CyClpSimplex() x = s.addVariable('x', self.nCols) s += A * x >= 1 s += 0 <= x <= 1 s.objective = c * x return s
def initializeSolver(self): """ Initialize linear solver to compute the step and the projection """ self.LP_solver = CyClpSimplex() self.LP_solver.logLevel = 0 self.LP_solver.maxNumIteration = self.minor_iter A = CyCoinPackedMatrix(colOrdered=True, rowIndices=self.LinearModel.Asparse.row, colIndices=self.LinearModel.Asparse.col, elements=self.LinearModel.Asparse.data) self.LP_solver.loadProblem(A, self.LinearModel.Lvar, self.LinearModel.Uvar, self.LinearModel.c, self.LinearModel.Lcon, self.LinearModel.Ucon) # Initialisation de la projection self.proj = CyClpSimplex() self.proj.logLevel = 0 ci = np.concatenate((np.ones(self.model.n), np.zeros(self.model.n))) I = np.eye(self.model.n) if self.nlin > 0: A = np.vstack((np.hstack((-I, I)), np.hstack( (-I, -I)), np.hstack((np.zeros(self.J_L.shape), self.J_L)))) Lcon = np.hstack((-np.inf * np.ones(2 * self.model.n), self.model.Lcon[self.model.lin])) Ucon = np.hstack( (self.x_k, -self.x_k, self.model.Ucon[self.model.lin])) else: A = np.vstack((np.hstack((-I, I)), np.hstack((-I, -I)))) Lcon = -np.inf * np.ones(2 * self.model.n) Ucon = np.hstack((self.x_k, -self.x_k)) Asparse = coo_matrix(A) Ai = CyCoinPackedMatrix(colOrdered=True, rowIndices=Asparse.row, colIndices=Asparse.col, elements=Asparse.data) self.proj.loadProblem( Ai, np.hstack((np.zeros(self.model.n), self.model.Lvar)), np.hstack((np.inf * np.ones(self.model.n), self.model.Uvar)), ci, Lcon, Ucon)
def test_removeVar(self): m = self.model x = self.x A = self.A B = self.B D = self.D b = self.b y = m.addVariable('y', 4) z = m.addVariable('z', 5) m.addConstraint(x >= 0) m.addConstraint(y >= -10) m.addConstraint(z >= -10) m.addConstraint(A * x + D * y + B * z <= b) m += x[0] + y[0] + z[0] >= 1.12 m.objective = x.sum() + y.sum() + z.sum() s = CyClpSimplex(m) s.primal() self.assertTrue('y' in s.primalVariableSolution.keys()) m.removeVariable('y') s = CyClpSimplex(m) s.primal() self.assertTrue('y' not in s.primalVariableSolution.keys())
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(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)
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_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())
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")
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']]
class TestCyCoinIndexedVector(unittest.TestCase): def setUp(self): self.a = np.array([1, 10.5, -11.3, 100, -50.5, 20], dtype=np.double) self.a2 = np.array([1000, 10.5, -11.3, 100, -50.5, 20], dtype=np.double) self.s = CyClpSimplex() # def test_gen(self): # w = np.array([3], dtype=np.int32) # self.assertEqual(self.s.argWeightedMax(self.a, w, 0.1), 5) # # def test_empty(self): # w = np.array([], dtype=np.int32) # self.assertEqual(self.s.argWeightedMax(np.array([]), w, 0.1), 0) # # def test_first(self): # w = np.array([0, 2], dtype=np.int32) # self.assertEqual(self.s.argWeightedMax(self.a, w, 99), 3) # self.assertEqual(self.s.argWeightedMax(self.a, w, 100), 0) def test_argMax4_1(self): w_ind = np.array([0, 2, 5], dtype=np.int32) self.assertEqual(self.s.argWeightedMax(self.a, 0, 100, w_ind), 5) def test_argMax4_2(self): w_ind = np.array([0, 2, 5], dtype=np.int32) w = np.array([1.5, -10, 4], dtype=np.double) self.assertEqual(self.s.argWeightedMax(self.a, 0, w, w_ind), 2) def test_argMax4_3(self): w_ind = np.array([0, 8, 21], dtype=np.int32) a_ind = np.array([2, 5, 8, 10, 20, 21], dtype=np.int32) self.assertEqual(self.s.argWeightedMax(self.a, a_ind, 5.1, w_ind), 5) def test_argMax4_4(self): w_ind = np.array([0, 8, 21], dtype=np.int32) w = np.array([100, -10, 4], dtype=np.double) a_ind = np.array([2, 5, 8, 10, 20, 21], dtype=np.int32) self.assertEqual(self.s.argWeightedMax(self.a, a_ind, w, w_ind), 2) def test_argMax_5(self): w_ind = np.array([2, 7, 100], dtype=np.int32) w = np.array([100, -10, 4], dtype=np.double) a_ind = np.array([2, 5, 8, 10, 20, 21], dtype=np.int32) self.assertEqual(self.s.argWeightedMax(self.a2, a_ind, 10, w_ind), 0)
class TestCyCoinIndexedVector(unittest.TestCase): def setUp(self): self.a = np.array([1, 10.5, -11.3, 100, -50.5, 20], dtype=np.double) self.a2 = np.array([1000, 10.5, -11.3, 100, -50.5, 20], dtype=np.double) self.s = CyClpSimplex() # def test_gen(self): # w = np.array([3], dtype=np.int32) # self.assertEqual(self.s.argWeightedMax(self.a, w, 0.1), 5) # # def test_empty(self): # w = np.array([], dtype=np.int32) # self.assertEqual(self.s.argWeightedMax(np.array([]), w, 0.1), 0) # # def test_first(self): # w = np.array([0, 2], dtype=np.int32) # self.assertEqual(self.s.argWeightedMax(self.a, w, 99), 3) # self.assertEqual(self.s.argWeightedMax(self.a, w, 100), 0) def test_argMax4_1(self): w_ind = np.array([0, 2, 5], dtype=np.int32) self.assertEqual(self.s.argWeightedMax(self.a, 0, 100, w_ind), 5) def test_argMax4_2(self): w_ind = np.array([0, 2, 5], dtype=np.int32) w = np.array([1.5, -10, 4], dtype=np.double) self.assertEqual(self.s.argWeightedMax(self.a, 0, w, w_ind), 2) def test_argMax4_3(self): w_ind = np.array([0, 8, 21], dtype=np.int32) a_ind = np.array([2, 5, 8, 10, 20, 21] , dtype=np.int32) self.assertEqual(self.s.argWeightedMax(self.a, a_ind, 5.1, w_ind), 5) def test_argMax4_4(self): w_ind = np.array([0, 8, 21], dtype=np.int32) w = np.array([100, -10, 4], dtype=np.double) a_ind = np.array([2, 5, 8, 10, 20, 21] , dtype=np.int32) self.assertEqual(self.s.argWeightedMax(self.a, a_ind, w, w_ind), 2) def test_argMax_5(self): w_ind = np.array([2, 7, 100], dtype=np.int32) w = np.array([100, -10, 4], dtype=np.double) a_ind = np.array([2, 5, 8, 10, 20, 21] , dtype=np.int32) self.assertEqual(self.s.argWeightedMax(self.a2, a_ind, 10, w_ind), 0)
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 __init__(self): super().__init__() self.status = LPStatus.UNKNOWN self.constraint_counter = 0 self.model = CyClpSimplex() # Maps a variable to a Clp variable self.var_to_clp_var = {} # Maps a HIPS constraint to a Clp constraint self.constr_to_clp_constr = {} # Maps a CLP constraint to a name self.clp_constr_to_name = {} # Maps vars to the number of constraints it is contained in self.var_to_nconstr = {} # Maps constr to variables self.constr_to_vars = {} # Map vars to lower/upper bound constraint self.var_to_lower = {} self.var_to_upper = {}
def test_onlyBounds(self): model = CyLPModel() x = model.addVariable('x', 3) y = model.addVariable('y', 2) model += y >= 1 model += 2 <= x <= 4 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([2, 4, 2, 1, 1])) <= 10**-6).all())
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())
def generateQP(self): m = self.m n = self.n s = CyClpSimplex() iNonZero = set(random.randint(n, size=self.nnzPerCol)) iZero = [i for i in range(n) if i not in iNonZero] x_star = np.matrix(np.zeros((n, 1))) z_star = np.matrix(np.zeros((n, 1))) for i in iNonZero: x_star[i, 0] = 1 for i in iZero: z_star[i, 0] = 0 if random.randint(2) else random.random() G = getG(n) A = getA(m, n, self.nnzPerCol) y_star = np.matrix(random.random((m, 1))) c = -(G * x_star - A.T * y_star - z_star) obj = 0.5 * ((x_star.T * G) * x_star) + c.T * x_star print(obj) c = CyLPArray((c.T)[0]) b = CyLPArray(((A * x_star).T)[0]) b = np.squeeze(np.asarray(b)) x = s.addVariable('x', n) s += A * x == b s += x >= 0 c = CyLPArray(c) s.objective = c * x s.Hessian = G self.model = s return s
def __init__(self: T, lp: CyClpSimplex, integerIndices: List[int], lower_bound: Union[float, int] = -float('inf'), b_idx: int = None, b_dir: str = None, b_val: float = None, depth=0): """ :param lp: model object simplex is run against :param integerIndices: indices of variables we aim to find integer solutions :param lower_bound: starting lower bound on optimal objective value for the minimization problem in this node :param b_idx: index of the branching variable :param b_dir: direction of branching :param b_val: initial value of the branching variable :param depth: how deep in the tree this node is """ assert isinstance(lp, CyClpSimplex), 'lp must be CyClpSimplex instance' assert all(0 <= idx < lp.nVariables and isinstance(idx, int) for idx in integerIndices), 'indices must match variables' assert len(set(integerIndices)) == len(integerIndices), \ 'indices must be distinct' assert isinstance(lower_bound, float) or isinstance(lower_bound, int), \ 'lower bound must be a float or an int' assert (b_dir is None) == (b_idx is None) == (b_val is None), \ 'none are none or all are none' assert b_idx in integerIndices or b_idx is None, \ 'branch index corresponds to integer variable if it exists' assert b_dir in ['up', 'down'] or b_dir is None, \ 'we can only round a variable up or down when branching' if b_val is not None: good_down = 0 < b_val - lp.variablesUpper[b_idx] < 1 good_up = 0 < lp.variablesLower[b_idx] - b_val < 1 assert (b_dir == 'down' and good_down) or \ (b_dir == 'up' and good_up), 'branch val should be within 1 of both bounds' assert isinstance(depth, int) and depth >= 0, 'depth is a positive integer' lp.logLevel = 0 self._lp = lp self._integerIndices = integerIndices self.lower_bound = lower_bound self.objective_value = None self.solution = None self.lp_feasible = None self.unbounded = None self.mip_feasible = None self._epsilon = .0001 self._b_dir = b_dir self._b_idx = b_idx self._b_val = b_val self.depth = depth self.search_method = 'best first' self.branch_method = 'most fractional'
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"]
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 QPModel(self, addW=False): A = self.A c = self.c s = CyClpSimplex() x = s.addVariable('x', self.nCols) if addW: w = s.addVariable('w', self.nCols) s += A * x >= 1 n = self.nCols if not addW: s += 0 <= x <= 1 else: s += x + w == 1 s += 0 <= w <= 1 ## s += -1 <= x <= 1 s.objective = c * x if addW: G = sparse.lil_matrix((2*n, 2*n)) for i in xrange(n/2, n): #xrange(n-1): G[i, i] = 1 G[2*n-1, 2*n-1] = 10**-10 else: G = sparse.lil_matrix((n, n)) for i in xrange(n/2, n): #xrange(n-1): G[i, i] = 1 s.Hessian = G return s
def test_variableBoundSubset(self): m = self.model x = self.x y = m.addVariable('y', 4) z = m.addVariable('z', 5) A = self.A b = self.b k = m.addVariable('k', 2) s = CyClpSimplex(m) s.setColumnLowerSubset(np.array([1, 2], np.int32), np.array([3, 5, 8], np.int32), np.array([3.2, 3.1, 2.2])) self.assertTrue(s.variablesLower[3] != 3.2) self.assertTrue(s.variablesLower[5] == 3.1) self.assertTrue(s.variablesLower[8] == 2.2) s.setColumnUpperSubset(np.array([0, 2], np.int32), np.array([0, 4, 10], np.int32), np.array([3.2, 3.1, 2.2])) self.assertTrue(s.variablesUpper[0] == 3.2) self.assertTrue(s.variablesUpper[4] != 3.1) self.assertTrue(s.variablesUpper[10] == 2.2)
def test_1(self): """simplest QP test""" s = CyClpSimplex() s.readMps(join(currentFilePath, '../input/hs35.qps')) #self.assertTrue(abs(cbcModel.objectiveValue - 3089.0) < 10 ** -6) #print s.Hessian.todense() p = WolfePivot(s) s.setPivotMethod(p) s.primal() print s.primalVariableSolution print s.objectiveValue
def test(self): m = CyCoinModel() m.addVariable(3, np.array([0, 1, 2], np.int32), np.array([1., 1., 1.], np.double), 0, 10, 5) m.addVariable(2, np.array([1, 2], np.int32), np.array([5, 2.], np.double), 0, 10, 2) # Add bound for the three constraints (we have two variables) m.setConstraintLower(0, 2.3) m.setConstraintLower(1, 4.5) m.setConstraintLower(0, 1.5) # Add a 4th constraint m.addConstraint(2, np.array([0, 1], np.int32), np.array([1., 1.], np.double), 2, 7) s = CyClpSimplex() # Load the problem from the CyCoinModel s.loadProblemFromCyCoinModel(m) s.primal() self.assertAlmostEqual(s.objectiveValue, 8.7, 7)
def read_instance(module_name = True, file_name = None): if module_name: lp = CyClpSimplex() mip = ilib.import_module(module_name) A = np.matrix(mip.A) #print np.linalg.cond(A) b = CyLPArray(mip.b) #We assume variables have zero lower bounds x_l = CyLPArray([0 for _ in range(mip.numVars)]) x = lp.addVariable('x', mip.numVars) lp += x >= x_l try: x_u = CyLPArray(getattr(mip, 'x_u')) lp += x <= x_u except: pass lp += (A * x <= b if mip.sense[1] == '<=' else A * x >= b) c = CyLPArray(mip.c) lp.objective = -c * x if mip.sense[0] == 'Max' else c * x return lp, x, mip.A, mip.b, mip.sense, mip.integerIndices else: #TODO Change sense of inequalities so they are all the same # by explicitly checking lp.constraintsUpper and lp.constraintsLower #Warning: Reading MP not well tested lp.extractCyLPModel(file_name) x = lp.cyLPModel.getVarByName('x') sense = ('Min', '>=') return lp, x, None, None, sense, integerIndices
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]
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 test_init_fails_asserts(self): lp = CyClpSimplex() bb = BranchAndBound(small_branch) queue = PriorityQueue() # model asserts self.assertRaisesRegex(AssertionError, 'model must be cuppy MILPInstance', BranchAndBound, lp) # Node asserts self.assertRaisesRegex(AssertionError, 'Node must be a class', BranchAndBound, small_branch, 'Node') for attribute in bb._node_attributes: class BadNode(BaseNode): def __init__(self, **kwargs): super().__init__(**kwargs) delattr(self, attribute) self.assertRaisesRegex(AssertionError, f'Node needs a {attribute}', BranchAndBound, small_branch, BadNode) for func in bb._node_funcs: class BadNode(BaseNode): def __init__(self, **kwargs): super().__init__(**kwargs) self.__dict__[func] = 5 self.assertRaisesRegex(AssertionError, f'Node needs a {func}', BranchAndBound, small_branch, BadNode) # node_queue asserts for func in reversed(bb._queue_funcs): queue.__dict__[func] = 5 self.assertRaisesRegex(AssertionError, f'node_queue needs a {func} function', BranchAndBound, small_branch, BaseNode, queue) # strong branch iters asserts self.assertRaisesRegex( AssertionError, 'strong branching iterations must be positive integer', BranchAndBound, small_branch, strong_branch_iters=-1)
def read_instance(module_name = None, file_name = None): if module_name is not None: lp = CyClpSimplex() mip = ilib.import_module(module_name) A = np.matrix(mip.A) #print np.linalg.cond(A) b = CyLPArray(mip.b) #Warning: At the moment, you must put bound constraints in explicitly for split cuts x_l = CyLPArray([0 for _ in range(mip.numVars)]) x = lp.addVariable('x', mip.numVars) lp += x >= x_l try: x_u = CyLPArray(getattr(mip, 'x_u')) lp += x <= x_u except: pass lp += (A * x <= b if mip.sense[1] == '<=' else A * x >= b) c = CyLPArray(mip.c) lp.objective = -c * x if mip.sense[0] == 'Max' else c * x return lp, x, mip.A, mip.b, mip.sense[1], mip.integerIndices elif file_name is not None: lp = CyClpSimplex() m = lp.extractCyLPModel(file_name) x = m.getVarByName('x') integerIndices = [i for (i, j) in enumerate(lp.integerInformation) if j == True] infinity = lp.getCoinInfinity() sense = None for i in range(lp.nRows): if lp.constraintsLower[i] > -infinity: if sense == '<=': print "Function does not support mixed constraint..." break else: sense = '>=' b = lp.constraintsLower if lp.constraintsUpper[i] < infinity: if sense == '>=': print "Function does not support mixed constraint..." break else: sense = '<=' b = lp.constraintsUpper return lp, x, lp.coefMatrix, b, sense, integerIndices else: print "No file or module name specified..." return None, None, None, None, None, None
def test_init_fails_asserts(self): lp = CyClpSimplex() # model asserts self.assertRaisesRegex(AssertionError, 'model must be cuppy MILPInstance', Utils, lp, BaseNode, self._node_funcs, self._node_attributes) # Node asserts self.assertRaisesRegex(AssertionError, 'Node must be a class', Utils, small_branch, 'Node', self._node_funcs, self._node_attributes) for attribute in self._node_attributes: class BadNode(BaseNode): def __init__(self, **kwargs): super().__init__(**kwargs) delattr(self, attribute) self.assertRaisesRegex(AssertionError, f'Node needs a {attribute}', Utils, small_branch, BadNode, self._node_attributes, self._node_funcs) for func in self._node_funcs: class BadNode(BaseNode): def __init__(self, **kwargs): super().__init__(**kwargs) self.__dict__[func] = 5 self.assertRaisesRegex(AssertionError, f'Node needs a {func}', Utils, small_branch, BadNode, self._node_attributes, self._node_funcs) # kwarg asserts self.assertRaisesRegex(AssertionError, 'next_node_idx is reserved', Utils, small_branch, BaseNode, self._node_attributes, self._node_funcs, next_node_idx=1)
def test_removeConst(self): m = self.model x = self.x A = self.A b = self.b m.addConstraint(x >= 0) m.addConstraint(A * x == b) m.addConstraint(x[1:3].sum() >= 1, 'rr') m.objective = x.sum() s = CyClpSimplex(m) s.primal() self.assertAlmostEqual(s.primalVariableSolution['x'][1], 1, 7) s.removeConstraint('rr') s.primal() self.assertAlmostEqual(s.primalVariableSolution['x'][1], 0, 7)
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)
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)
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(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)
def test_NodeCompare(self): s = CyClpSimplex() s.readMps(join(currentFilePath, '../input/p0033.mps')) s.copyInIntegerInformation(np.array(s.nCols * [True], np.uint8)) print "Solving relaxation" cbcModel = s.getCbcModel() n = SimpleNodeCompare() cbcModel.setNodeCompare(n) gom = CyCglGomory(limit=150) #gom.limit = 150 cbcModel.addCutGenerator(gom, name="Gomory") #clq = CyCglClique() #cbcModel.addCutGenerator(clq, name="Clique") knap = CyCglKnapsackCover(maxInKnapsack=50) cbcModel.addCutGenerator(knap, name="Knapsack") cbcModel.branchAndBound() self.assertTrue(abs(cbcModel.objectiveValue - 3089.0) < 10 ** -6)
model.solution[basicVarInds[rowNumbers]] -= change changeObj = -np.dot(change, cost) primalUpdate.clear() objectiveChange[0] += changeObj return changeObj def getMpsExample(): import os import inspect import sys cylpDir = os.environ['CYLP_SOURCE_DIR'] return os.path.join(cylpDir, 'cylp', 'input', 'p0033.mps') if __name__ == "__main__": print sys.argv if len(sys.argv) == 1: import doctest doctest.testmod() else: from cylp.cy import CyClpSimplex from cylp.py.pivots import DualDantzigPivot s = CyClpSimplex() s.readMps(sys.argv[1]) # Returns 0 if OK pivot = DualDantzigPivot(s) s.setDualPivotMethod(pivot) s.dual()
def maxViolationSplitCuts(lp, integerIndices = None, sense = '>=', sol = None, max_coeff = 1): #Warning: At the moment, you must put bound constraints in explicitly for split cuts A = lp.coefMatrix if sense == '<=': b = CyLPArray(lp.constraintsUpper) else: b = CyLPArray(lp.constraintsLower) if integerIndices is None: integerIndices = range(lp.nVariables) if sol is None: sol = lp.primalVariableSolution['x'] s = A*sol - b best = lp.getCoinInfinity() best_theta = None for theta in [0.01, 0.02, 0.03, 0.04, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5]: sp = CyLPModel() u = sp.addVariable('u', lp.nConstraints, isInt = False) v = sp.addVariable('v', lp.nConstraints, isInt = False) pi = sp.addVariable('pi', lp.nVariables, isInt = True) pi0 = sp.addVariable('pi0', 1, isInt = True) sp += pi + A.transpose()*u - A.transpose()*v == 0 sp += pi0 + b*u - b*v == theta - 1 if sense == '<=': sp += u >= 0 sp += v >= 0 else: #TODO this direction is not debugged # Is this all we need? sp += u <= 0 sp += v <= 0 sp.objective = (theta-1)*s*u - theta*s*v for i in xrange(lp.nVariables): if i in integerIndices: sp += -max_coeff <= pi[i] <= max_coeff else: sp[i] += pi[i] == 0 cbcModel = CyClpSimplex(sp).getCbcModel() cbcModel.logLevel = 0 #cbcModel.maximumSeconds = 5 cbcModel.solve() if debug_print: #print 'Theta: ', theta, #print 'Objective Value: ', cbcModel.objectiveValue - theta*(1-theta) #print 'pi: ', cbcModel.primalVariableSolution['pi'] #print 'pi0: ', cbcModel.primalVariableSolution['pi0'] multu = cbcModel.primalVariableSolution['u'] disjunction = cbcModel.primalVariableSolution['pi'] rhs = cbcModel.primalVariableSolution['pi0'] alpha = A.transpose()*multu + theta*disjunction beta = np.dot(b, multu) + theta*rhs #print 'alpha: ', alpha, 'alpha*sol: ', np.dot(alpha, sol) #print 'beta: ', beta #print 'Violation of cut: ', np.dot(alpha, sol) - beta if cbcModel.objectiveValue - theta*(1-theta) < best: best = cbcModel.objectiveValue - theta*(1-theta) best_multu = cbcModel.primalVariableSolution['u'] best_multv = cbcModel.primalVariableSolution['v'] best_disjunction = cbcModel.primalVariableSolution['pi'] best_rhs = cbcModel.primalVariableSolution['pi0'] best_theta = theta if best_theta is not None: alpha = A.transpose()*best_multu + best_theta*best_disjunction beta = np.dot(b, best_multu) + best_theta*best_rhs if debug_print: print 'Violation of cut: ', np.dot(alpha, sol) - beta print 'pi: ', best_disjunction print 'pi0: ', best_rhs print 'theta: ', best_theta if (abs(alpha) > 1e-6).any(): return [(alpha, beta)] return []
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())
m = CyLPModel() firstExample = False if (firstExample): x = m.addVariable('x', 2, isInt=True) A = np.matrix([[7., -2.],[0., 1], [2., -2]]) b = CyLPArray([14, 3, 3]) m += A * x <= b m += x >= 0 c = CyLPArray([-4, 1]) m.objective = c * x s = CyClpSimplex(m) else: s = CyClpSimplex() cylpDir = os.environ['CYLP_SOURCE_DIR'] inputFile = os.path.join(cylpDir, 'cylp', 'input', 'p0033.mps') m = s.extractCyLPModel(inputFile) x = m.getVarByName('x') s.setInteger(x) cbcModel = s.getCbcModel() gc = GomoryCutGenerator(m) cbcModel.addPythonCutGenerator(gc, name='PyGomory') cbcModel.branchAndBound()
#del rc2 return indicesToConsider[ind] return -1 def saveWeights(self, model, mode): self.clpModel = model def isPivotAcceptable(self): return True def getMpsExample(): import os import inspect cylpDir = os.environ['CYLP_SOURCE_DIR'] return os.path.join(cylpDir, 'cylp', 'input', 'p0033.mps') if __name__ == "__main__": if len(sys.argv) == 1: import doctest doctest.testmod() else: from cylp.cy import CyClpSimplex from cylp.py.pivots import DantzigPivot s = CyClpSimplex() s.readMps(sys.argv[1]) pivot = DantzigPivot(s) s.setPivotMethod(pivot) s.primal()
def Single_Year_Stage_II(puf, Stage_I_factors, Stage_II_targets, year, tol): length = len(puf.s006) print("Preparing coefficient matrix...") s006 = np.where(puf.e02400>0, puf.s006*Stage_I_factors[year]["APOPSNR"]/100, puf.s006*Stage_I_factors[year]["ARETS"]/100) single_return = np.where(puf.mars==1, s006, 0) joint_return = np.where((puf.mars==2)|(puf.mars==3), s006, 0) hh_return = np.where(puf.mars==4,s006,0) return_w_SS = np.where(puf.e02400>0,s006,0) dependent_exempt_num = (puf.xocah+puf.xocawh+puf.xoodep+puf.xopar)*s006 interest = puf.e00300*s006 dividend = puf.e00600*s006 biz_income = np.where(puf.e00900>0, puf.e00900, 0)*s006 biz_loss = np.where(puf.e00900<0, -puf.e00900, 0)*s006 cap_gain = np.where(puf.e01000>0, puf.e01000, 0)*s006 annuity_pension = puf.e01700*s006 sch_e_income = np.where(puf.e02000>0, puf.e02000, 0)*s006 sch_e_loss = np.where(puf.e02000<0, -puf.e02000, 0)*s006 ss_income = puf.e02400*s006 unemployment_comp = puf.e02300*s006 # Wage distribution wage_1 = np.where(puf.e00100<=0, puf.e00200,0)*s006 wage_2 = np.where((puf.e00100>0)&(puf.e00100<=10000), puf.e00200,0)*s006 wage_3 = np.where((puf.e00100>10000)&(puf.e00100<=20000), puf.e00200,0)*s006 wage_4 = np.where((puf.e00100>20000)&(puf.e00100<=30000), puf.e00200,0)*s006 wage_5 = np.where((puf.e00100>30000)&(puf.e00100<=40000), puf.e00200,0)*s006 wage_6 = np.where((puf.e00100>40000)&(puf.e00100<=50000), puf.e00200,0)*s006 wage_7 = np.where((puf.e00100>50000)&(puf.e00100<=75000), puf.e00200,0)*s006 wage_8 = np.where((puf.e00100>75000)&(puf.e00100<=100000), puf.e00200,0)*s006 wage_9 = np.where((puf.e00100>100000)&(puf.e00100<=200000), puf.e00200,0)*s006 wage_10 = np.where((puf.e00100>200000)&(puf.e00100<=500000), puf.e00200,0)*s006 wage_11 = np.where((puf.e00100>500000)&(puf.e00100<=1000000), puf.e00200,0)*s006 wage_12 = np.where((puf.e00100>1000000), puf.e00200,0)*s006 # Set up the matrix One_half_LHS = np.vstack((single_return, joint_return, hh_return, return_w_SS, dependent_exempt_num, interest, dividend, biz_income,biz_loss, cap_gain, annuity_pension, sch_e_income, sch_e_loss, ss_income, unemployment_comp, wage_1, wage_2, wage_3, wage_4, wage_5, wage_6, wage_7, wage_8, wage_9, wage_10, wage_11, wage_12)) # Coefficients for r and s A1 = np.matrix(One_half_LHS) A2 = np.matrix(-One_half_LHS) print("Preparing targets for ", year) APOPN = Stage_I_factors[year]["APOPN"] b = [] b.append(Stage_II_targets[year]['Single']-single_return.sum()) b.append(Stage_II_targets[year]['Joint']-joint_return.sum()) b.append(Stage_II_targets[year]['HH']-hh_return.sum()) b.append(Stage_II_targets[year]['SS_return']-return_w_SS.sum()) b.append(Stage_II_targets[year]['Dep_return'] - dependent_exempt_num.sum()) AINTS = Stage_I_factors[year]["AINTS"] INTEREST = Stage_II_targets[year]['INTS']*APOPN/AINTS*1000-interest.sum() ADIVS = Stage_I_factors[year]["ADIVS"] DIVIDEND = Stage_II_targets[year]['DIVS']*APOPN/ADIVS*1000 - dividend.sum() ASCHCI = Stage_I_factors[year]["ASCHCI"] BIZ_INCOME = Stage_II_targets[year]['SCHCI']*APOPN/ASCHCI*1000 - biz_income.sum() ASCHCL = Stage_I_factors[year]["ASCHCL"] BIZ_LOSS = Stage_II_targets[year]['SCHCL']*APOPN/ASCHCL*1000 - biz_loss.sum() ACGNS = Stage_I_factors[year]["ACGNS"] CAP_GAIN = Stage_II_targets[year]['CGNS']*APOPN/ACGNS*1000 - cap_gain.sum() ATXPY = Stage_I_factors[year]["ATXPY"] ANNUITY_PENSION = Stage_II_targets[year]['Pension']*APOPN/ATXPY*1000 - annuity_pension.sum() ASCHEI = Stage_I_factors[year]["ASCHEI"] SCH_E_INCOME = Stage_II_targets[year]["SCHEI"]*APOPN/ASCHEI*1000 - sch_e_income.sum() ASCHEL = Stage_I_factors[year]["ASCHEL"] SCH_E_LOSS = Stage_II_targets[year]["SCHEL"]*APOPN/ASCHEL*1000 - sch_e_loss.sum() ASOCSEC = Stage_I_factors[year]["ASOCSEC"] APOPSNR = Stage_I_factors[year]["APOPSNR"] SS_INCOME = Stage_II_targets[year]["SS"]*APOPSNR/ASOCSEC*1000 - ss_income.sum() AUCOMP = Stage_I_factors[year]["AUCOMP"] UNEMPLOYMENT_COMP = Stage_II_targets[year]["UCOMP"]*APOPN/AUCOMP*1000 - unemployment_comp.sum() AWAGE = Stage_I_factors[year]["AWAGE"] WAGE_1 = Stage_II_targets[year]["WAGE_1"]*APOPN/AWAGE*1000 - wage_1.sum() WAGE_2 = Stage_II_targets[year]["WAGE_2"]*APOPN/AWAGE*1000 - wage_2.sum() WAGE_3 = Stage_II_targets[year]["WAGE_3"]*APOPN/AWAGE*1000 - wage_3.sum() WAGE_4 = Stage_II_targets[year]["WAGE_4"]*APOPN/AWAGE*1000 - wage_4.sum() WAGE_5 = Stage_II_targets[year]["WAGE_5"]*APOPN/AWAGE*1000 - wage_5.sum() WAGE_6 = Stage_II_targets[year]["WAGE_6"]*APOPN/AWAGE*1000 - wage_6.sum() WAGE_7 = Stage_II_targets[year]["WAGE_7"]*APOPN/AWAGE*1000 - wage_7.sum() WAGE_8 = Stage_II_targets[year]["WAGE_8"]*APOPN/AWAGE*1000 - wage_8.sum() WAGE_9 = Stage_II_targets[year]["WAGE_9"]*APOPN/AWAGE*1000 - wage_9.sum() WAGE_10 = Stage_II_targets[year]["WAGE_10"]*APOPN/AWAGE*1000 - wage_10.sum() WAGE_11 = Stage_II_targets[year]["WAGE_11"]*APOPN/AWAGE*1000 - wage_11.sum() WAGE_12 = Stage_II_targets[year]["WAGE_12"]*APOPN/AWAGE*1000 - wage_12.sum() temp = [INTEREST,DIVIDEND, BIZ_INCOME, BIZ_LOSS, CAP_GAIN, ANNUITY_PENSION, SCH_E_INCOME, SCH_E_LOSS, SS_INCOME, UNEMPLOYMENT_COMP, WAGE_1,WAGE_2, WAGE_3,WAGE_4, WAGE_5, WAGE_6, WAGE_7,WAGE_8,WAGE_9, WAGE_10, WAGE_11, WAGE_12] for m in temp: b.append(m) targets = CyLPArray(b) print("Targets for year ", year, " is ", targets) LP = CyLPModel() r = LP.addVariable('r', length) s = LP.addVariable('s', length) print("Adding constraints") LP.addConstraint(r >=0, "positive r") LP.addConstraint(s >=0, "positive s") LP.addConstraint(r + s <= tol, "abs upperbound") c = CyLPArray((np.ones(length))) LP.objective = c * r + c * s LP.addConstraint(A1 * r + A2 * s == targets, "Aggregates") print("Setting up the LP model") model = CyClpSimplex(LP) print("Solving LP......") model.initialSolve() print("DONE!!") z = np.empty([length]) z = (1+model.primalVariableSolution['r'] - model.primalVariableSolution['s'])*s006 return z
def __setitem__(self, key, val): #if isinstance(key, tuple): if val == 0: # See if necessary to use a tolerance return self.sol[key] = val def __repr__(self): return repr(self.sol) def getCoinInfinity(): return 1.79769313486e+308 if __name__ == '__main__': 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(range(18)) s.objective = c * x[2, :, :] + c * x[0, :, :] s.writeMps('/Users/mehdi/Desktop/test.mps') s.primal() sol = s.primalVariableSolution print sol #model = CyLPModel() # #x = model.addVariable('x', 5)
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 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] n = c.shape[0] solver_cache = cached_data[self.name()] # Problem model = CyClpSimplex() # Variables x = model.addVariable('x', n) if self.is_mip(data): for i in data[s.BOOL_IDX]: model.setInteger(x[i]) for i in data[s.INT_IDX]: model.setInteger(x[i]) # Constraints # eq model += A[0:dims[s.EQ_DIM], :] * x == 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 <= b[leq_start:leq_end] # no boolean vars available in cbc -> model as int + restrict to [0,1] if self.is_mip(data): for i in data[s.BOOL_IDX]: model += 0 <= x[i] <= 1 # Objective model.objective = c # Build model & solve status = None if self.is_mip(data): cbcModel = model.getCbcModel() # need to convert model if not verbose: cbcModel.logLevel = 0 # Add cut-generators (optional) for cut_name, cut_func in six.iteritems(self.SUPPORTED_CUT_GENERATORS): if cut_name in solver_opts and solver_opts[cut_name]: module = importlib.import_module("cylp.cy.CyCgl") funcToCall = getattr(module, cut_func) cut_gen = funcToCall() cbcModel.addCutGenerator(cut_gen, name=cut_name) # solve status = cbcModel.branchAndBound() else: if not verbose: model.logLevel = 0 status = model.primal() # solve 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)
def splitCuts(lp, integerIndices = None, sense = '>=', sol = None, max_coeff = 1): A = lp.coefMatrix b = CyLPArray(lp.constraintsUpper) if integerIndices is None: integerIndices = range(lp.nVariables) if sol is None: sol = lp.primalVariableSolution['x'] s = A*sol - b best = lp.getCoinInfinity() best_theta = None for theta in [0.1, 0.2, 0.3, 0.4, 0.5]: sp = CyLPModel() u = sp.addVariable('u', lp.nConstraints, isInt = False) v = sp.addVariable('v', lp.nConstraints, isInt = False) pi = sp.addVariable('pi', lp.nVariables, isInt = True) pi0 = sp.addVariable('pi0', 1, isInt = True) sp += pi + A.transpose()*u - A.transpose()*v == 0 sp += pi0 + b*u - b*v == theta - 1 if sense == '<=': sp += u >= 0 sp += v >= 0 else: #TODO this direction is not debugged # Is this all we need? sp += u <= 0 sp += v <= 0 sp.objective = (theta-1)*s*u - theta*s*v for i in xrange(lp.nVariables): if i in integerIndices: sp += -max_coeff <= pi[i] <= max_coeff else: sp[i] += pi[i] == 0 cbcModel = CyClpSimplex(sp).getCbcModel() cbcModel.logLevel = 0 #cbcModel.maximumSeconds = 5 cbcModel.solve() if debug_print: print theta, cbcModel.objectiveValue print cbcModel.primalVariableSolution['pi'], print cbcModel.primalVariableSolution['pi0'] if cbcModel.objectiveValue < best: best = cbcModel.objectiveValue multu = cbcModel.primalVariableSolution['u'] disjunction = cbcModel.primalVariableSolution['pi'] rhs = cbcModel.primalVariableSolution['pi0'] best_theta = theta if best_theta is not None: alpha = A.transpose()*multu + best_theta*disjunction if sense == '<=': beta = np.dot(lp.constraintsUpper, multu) + best_theta*rhs else: beta = np.dot(lp.constraintsLower, multu) + best_theta*rhs if (abs(alpha) > 1e-6).any(): return [(alpha, beta)] return []
f.add_text(loc, r'$x^* = %s$' % str(opt)) f.show() try: p = Polyhedron2D(A = LP.A, b = LP.b) except AttributeError: try: p = Polyhedron2D(points = LP.points, rays = LP.rays) except AttributeError: print('Error: Must specify either A and b or points and rays') p = None if p is not None: if CYLP_INSTALLED: lp = CyClpSimplex() A = np.matrix(p.hrep.A) b = CyLPArray(p.hrep.b) print(A) print(b) if LP.numVars == 2: disp_polyhedron(A = A, b = b) x = lp.addVariable('x', LP.numVars) if LP.sense[0] == '>=': lp += A * x >= b else:
def disjunctionToCut(lp, pi, pi0, integerIndices = None, sense = '>=', sol = None, debug_print = False, use_cylp = True): me = "cglp_cuts: " if sol is None: sol = lp.primalVariableSolution['x'] infinity = lp.getCoinInfinity() if debug_print: print(me, "constraints sense = ", sense) print(me, "con lower bounds = ", lp.constraintsLower) print(me, "con upper bounds = ", lp.constraintsUpper) print(me, "con matrix = ", lp.coefMatrix.toarray()) print(me, "vars lower bounds = ", lp.variablesLower) print(me, "vars upper bounds = ", lp.variablesUpper) print(me, "Assuming objective is to minimize") print(me, "objective = ", lp.objective) print(me, "infinity = ", infinity) print(me, "current point = ", sol) print(me, "pi = ", pi) print(me, "pi0 = ", pi0) A = lp.coefMatrix.toarray() #c = lp.objective ## Convert to >= if the problem is in <= form. if sense == '<=': b = deepcopy(lp.constraintsUpper) b = -1.0*b A = -1.0*A else: b = deepcopy(lp.constraintsLower) #Add bounds on variables as explicit constraints for i in range(lp.nCols): e = np.zeros((1, lp.nCols)) if lp.variablesUpper[i] < infinity: b.resize(b.size+1, refcheck = False) e[0, i] = -1.0 b[-1] = -1.0*lp.variablesUpper[i] A = np.vstack((A, e)) if lp.variablesLower[i] > -infinity: b.resize(b.size+1, refcheck = False) e[0, i] = 1.0 b[-1] = lp.variablesLower[i] A = np.vstack((A, e)) A = csc_matrixPlus(A) ############################################################################ ## There are two given LPs: ## s.t. Ax >= b s.t. Ax >= b ## -pi.x >= -pi_0 pi.x >= pi_0+1 ## A, b, c, pi, pi_0 are given ## ## CGLP: alpha.x >= beta should be valid for both LPs above ## ## min alpha.x* - beta ## uA - u0.pi = alpha ## vA + v0.pi = alpha ## ub - u0.pi_0 >= beta ## vb + v0.(pi_0 + 1) >= beta ## u0 + v0 = 1 ## u, v, u0, v0 >= 0 ## if min value comes out < 0, then (alpha.x >= beta) is a cut. ############################################################################ b = CyLPArray(b) pi = CyLPArray(pi) Atran = A.transpose() if use_cylp: sp = CyLPModel() u = sp.addVariable('u', A.shape[0], isInt = False) v = sp.addVariable('v', A.shape[0], isInt = False) u0 = sp.addVariable('u0', 1, isInt = False) v0 = sp.addVariable('v0', 1, isInt = False) alpha = sp.addVariable('alpha', lp.nVariables, isInt = False) beta = sp.addVariable('beta', 1, isInt = False) for i in range(A.shape[1]): sp += alpha[i] - sum(Atran[i,j]*u[j] for j in range(A.shape[0])) + pi[i]*u0 == 0 for i in range(A.shape[1]): sp += alpha[i] - sum(Atran[i,j]*v[j] for j in range(A.shape[0])) - pi[i]*v0 == 0 sp += beta - b*u + pi0*u0 <= 0 sp += beta - b*v - (pi0 + 1)*v0 <= 0 sp += u0 + v0 == 1 if sense == '<=': sp += u >= 0 sp += v >= 0 sp += u0 >= 0 sp += v0 >= 0 else: #TODO this direction is not debugged # Is this all we need? sp += u <= 0 sp += v <= 0 sp += u0 <= 0 sp += v0 <= 0 sp.objective = sum(sol[i]*alpha[i] for i in range(A.shape[1])) - beta cbcModel = CyClpSimplex(sp).getCbcModel() cbcModel.logLevel = 0 #cbcModel.maximumSeconds = 5 cbcModel.solve() beta = cbcModel.primalVariableSolution['beta'][0] alpha = cbcModel.primalVariableSolution['alpha'] u = cbcModel.primalVariableSolution['u'] v = cbcModel.primalVariableSolution['v'] u0 = cbcModel.primalVariableSolution['u0'][0] v0 = cbcModel.primalVariableSolution['v0'][0] if debug_print: print('Objective Value: ', cbcModel.objectiveValue) print('alpha: ', alpha, 'alpha*sol: ', np.dot(alpha, sol)) print('beta: ', beta) print('Violation of cut: ', np.dot(alpha, sol) - beta) else: CG = AbstractModel() CG.u = Var(list(range(A.shape[0])), domain=NonNegativeReals, bounds = (0.0, None)) CG.v = Var(list(range(A.shape[0])), domain=NonNegativeReals, bounds = (0.0, None)) CG.u0 = Var(domain=NonNegativeReals, bounds = (0.0, None)) CG.v0 = Var(domain=NonNegativeReals, bounds = (0.0, None)) CG.alpha = Var(list(range(A.shape[0])), domain=Reals, bounds = (None, None)) CG.beta = Var(domain=Reals, bounds = (None, None)) ## Constraints def pi_rule_left(CG, i): x = float(pi[i]) return(sum(Atran[i, j]*CG.u[j] for j in range(A.shape[0])) - x*CG.u0 - CG.alpha[i] == 0.0) CG.pi_rule_left = Constraint(list(range(A.shape[1])), rule=pi_rule_left) def pi_rule_right(CG, i): x = float(pi[i]) return(sum(Atran[i, j]*CG.v[j] for j in range(A.shape[0])) + x*CG.v0 - CG.alpha[i] == 0.0) CG.pi_rule_right = Constraint(list(range(A.shape[1])), rule=pi_rule_right) def pi0_rule_left(CG): return(sum(b[j]*CG.u[j] for j in range(A.shape[0])) - pi0*CG.u0 - CG.beta >= 0.0) CG.pi0_rule_left = Constraint(rule=pi0_rule_left) def pi0_rule_right(CG): return(sum(b[j]*CG.v[j] for j in range(A.shape[0])) + (pi0 + 1)*CG.v0 - CG.beta >= 0.0) CG.pi0_rule_right = Constraint(rule=pi0_rule_right) def normalization_rule(CG): return(CG.u0 + CG.v0 == 1.0) CG.normalization_rule = Constraint(rule=normalization_rule) def objective_rule(CG): return(sum(sol[i]*CG.alpha[i] for i in range(A.shape[1])) - CG.beta) CG.objective = Objective(sense=minimize, rule=objective_rule) opt = SolverFactory("cbc") instance = CG.create_instance() #instance.pprint() #instance.write("foo.nl", format = "nl") #opt.options['bonmin.bb_log_level'] = 5 #opt.options['bonmin.bb_log_interval'] = 1 results = opt.solve(instance, tee=False) #results = opt.solve(instance) instance.solutions.load_from(results) beta = instance.beta.value alpha = np.array([instance.alpha[i].value for i in range(lp.nVariables)]) violation = beta - np.dot(alpha, sol) if debug_print: print(me, 'Beta: ', beta) print(me, 'alpha: ', alpha) print(me, 'Violation of cut: ', violation) if violation > 0.001: if (sense == ">="): return [(alpha, beta)] else: return [(-alpha, -beta)] return []
def setUp(self): self.a = np.array([1, 10.5, -11.3, 100, -50.5, 20], dtype=np.double) self.a2 = np.array([1000, 10.5, -11.3, 100, -50.5, 20], dtype=np.double) self.s = CyClpSimplex()