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 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 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 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 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 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 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_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 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 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 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']
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']
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_removeVar2(self): s = CyClpSimplex() fp = os.path.join(currentFilePath, '../../input/p0033.mps') s.extractCyLPModel(fp) y = s.addVariable('y', 3) s.primal() x = s.getVarByName('x') s.addConstraint(x[1] + y[1] >= 1.2) #s.primal() s.removeVariable('x') s.primal() s = s.primalVariableSolution self.assertTrue((s['y'] - np.array([0, 1.2, 0]) <= 10**-6).all())
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 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_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())
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 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 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())
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())
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
class TestCyClpSimplex(unittest.TestCase): def setUp(self): self.s = CyClpSimplex() self.s.readMps(join(currentFilePath, '../input/p0033.mps')) def test_PE(self): #pivot = PositiveEdgePivot(self.s) self.s.setPivotMethod(PositiveEdgePivot(self.s)) self.s.primal() self.assertEqual(round(self.s.objectiveValue, 4), 2520.5717) def test_Dantzig(self): #pivot = DantzigPivot(self.s) self.s.setPivotMethod(DantzigPivot(self.s)) self.s.primal() self.assertEqual(round(self.s.objectiveValue, 4), 2520.5717) def test_LIFO(self): #pivot = LIFOPivot(self.s) self.s.setPivotMethod(LIFOPivot(self.s)) self.s.primal() self.assertEqual(round(self.s.objectiveValue, 4), 2520.5717) def test_MostFrequent(self): #pivot = MostFrequentPivot(self.s) self.s.setPivotMethod(MostFrequentPivot(self.s)) self.s.primal() self.assertEqual(round(self.s.objectiveValue, 4), 2520.5717) def test_initialSolve(self): self.s.initialSolve() self.assertEqual(round(self.s.objectiveValue, 4), 2520.5717) def test_initialPrimalSolve(self): self.s.initialPrimalSolve() self.assertEqual(round(self.s.objectiveValue, 4), 2520.5717) def test_initialDualSolve(self): self.s.initialDualSolve() self.assertEqual(round(self.s.objectiveValue, 4), 2520.5717) def test_direction(self): self.assertEqual(self.s.optimizationDirection, 'min') self.s.optimizationDirection = 'max' self.assertEqual(self.s.optimizationDirection, 'max')
x = lp.addVariable('x', LP.numVars) if LP.sense[0] == '>=': lp += A * x >= b else: lp += A * x <= b #lp += x >= 0 c = CyLPArray(LP.c) # We are maximizing, so negate objective if LP.sense[1] == 'Min': lp.objective = c * x else: lp.objective = -c * x lp.logLevel = 0 lp.primal(startFinishOptions = 'x') np.set_printoptions(precision = 2, linewidth = 200) print('Basic variables: ', lp.basicVariables) print("Current tableaux and reduced costs:") print(lp.reducedCosts) print(np.around(lp.tableau, decimals = 3)) print('Right-hand side of optimal tableaux:') #There is a bug in CyLP and this is wrong #print lp.rhs if LP.sense[0] == '<=': print(np.dot(lp.basisInverse, lp.constraintsUpper)) else: print(np.dot(lp.basisInverse, lp.constraintsLower)) print('Inverse of optimal basis:') print(np.around(lp.basisInverse, 3)) if LP.sense[1] == 'Min':
def computePriceSweep(thisSlice): ###### BEGINNING OF MULTIPROCESSING FUNCTION ########### myLength = thisSlice.shape[1] # Simulation parameters - set these! storagePriceSet = np.arange(1.0,20.1,0.25) # storagePriceSet = np.arange(1.0,3.1,1) eff_round = 0.9 # Round-trip efficiency E_min = 0 E_max = 1 # Endogenous parameters; calculated automatically (eff_in, eff_out) = [np.sqrt(eff_round)] *2 # Properly account for the round trip efficiency of storage P_max = E_max/eff_in # Max discharge power at grid intertie, e.g max limit for C_i P_min = -1*E_max/eff_out # Max charge power at grid intertie, e.g. min D_i # Create a set of zero-filled dataframes for storing results resultIndex = pd.MultiIndex.from_product([thisSlice.index,['size','kwhPassed','profit']]) results = pd.DataFrame(index = resultIndex, columns=storagePriceSet) # Create clean problem matrices - needs efficiency and length! (A, b, A_eq, b_eq) = createABMatrices(myLength, delta_T, eff_in, eff_out, P_min, P_max, E_min, E_max) # Define model: coolStart = CyClpSimplex() coolStart.logLevel = 0 x_var = coolStart.addVariable('x',myLength*3+2) # Add constraints to model: coolStart += A * x_var <= b.toarray() coolStart += A_eq * x_var == b_eq.toarray() # print("Finished with problem setup") # sys.stdout.flush() # everythingStarts = time.time() # startTime = time.time() for myNodeName in thisSlice.index: ## Set up prices # myNodeName = thisSlice.index[i] energyPrice = thisSlice.loc[myNodeName,:] / 1000.0 # Price $/kWh as array c = np.concatenate([[0.0],[0.0]*(myLength+1),energyPrice,energyPrice],axis=0) #placeholder; No cost for storage state; charged for what we consume, get paid for what we discharge #[[storagePricePlaceholder],[0]*(myLength+1),myPrice,myPrice],axis=1) c_clp = CyLPArray(c) sweepStartTime = time.time() for myStoragePrice in storagePriceSet: c_clp[0] = myStoragePrice * simulationYears coolStart.objective = c_clp * x_var # Run the model coolStart.primal() # Results- Rows are Nodes, indexed by name. Columns are Storage price, indexed by price x_out = coolStart.primalVariableSolution['x'] results.loc[(myNodeName,'size'), myStoragePrice] = x_out[0] results.loc[(myNodeName,'profit'), myStoragePrice] = np.dot(-c, x_out) results.loc[(myNodeName,'kwhPassed'),myStoragePrice] = sum(x_out[2+myLength : 2+myLength*2]) * eff_in # Note: this is the net power pulled from the grid, not the number of cycles when the system is unconstrained storagePriceSet = storagePriceSet[::-1] # Reverse the price set so that we start from the same price for the next node to make warm-start more effective # if ((i+1) % reportFrequency == 0): # Save our progress along the way # elapsedTime = time.time()-startTime # print("Finished node %s; \t%s computations in \t%.4f s \t(%.4f s/solve)" # % (i, scenariosPerReport,elapsedTime,elapsedTime/scenariosPerReport)) # sys.stdout.flush() # sizeDf.to_csv('Data/VaryingPrices_StorageSizing_v2.csv') # profitDf.to_csv('Data/VaryingPrices_StorageProfits_v2.csv') # cycleDf.to_csv('Data/VaryingPrices_StorageCycles_v2.csv') # print("Done in %.3f s"%(time.time()-everythingStarts)) return results
import numpy as np from cylp.cy import CyClpSimplex from cylp.py.modeling.CyLPModel import CyLPArray s = CyClpSimplex() # Add variables x = s.addVariable('x', 3) y = s.addVariable('y', 2) # Create coefficients and bounds A = CyLPArray([[1., 2., 0], [1., 0, 1.]]) B = CyLPArray([[1., 0, 0], [0, 0, 1.]]) D = CyLPArray([[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 test_cylp(self): s = CyClpSimplex() numStates = 5 # Add variables x = s.addVariable('x', numStates, isInt=True) sw_on = s.addVariable('sw_on', numStates, isInt=True) sw_off = s.addVariable('sw_off', numStates, isInt=True) sw_stay_on = s.addVariable('sw_stay_on', numStates, isInt=True) sw_stay_off = s.addVariable('sw_stay_off', numStates, isInt=True) # Add constraints # make bools for b in [x,sw_on,sw_off,sw_stay_off,sw_stay_on]: s += b <= 1 s += b >= 0 # must be one of the transitions s += sw_on + sw_off + sw_stay_on + sw_stay_off == 1 # if sw_on for i in range(numStates): # must be on now s += x[i] - sw_on[i] >=0 # was off last time if i>0: s += (1-x[i-1] ) - sw_on[i] >= 0 # if sw_off for i in range(numStates): # must be off now s += (1-x[i]) - sw_off[i] >= 0 # was on last time if i>0: s += x[i-1] - sw_on[i] >= 0 # if sw_stay_on for i in range(numStates): s += x[i] - sw_stay_on[i] >= 0 if i > 0: s += x[i-1] - sw_stay_on[i] >= 0 # if sw_stay_off for i in range(numStates): s += (1-x[i]) - sw_stay_off[i] >= 0 if i > 0: s += (1-x[i-1]) - sw_stay_off[i] >= 0 s += x[1] == 1 s += x[2] == 0 # Set the objective function s.objective = x[0] - x[1] + x[2] # Solve using primal Simplex s.primal() print(' | '.join(['i','x','on','off','stay on','stay off'])) for i in range(numStates): row=' | '.join([ '%d' % i, '%1d' % s.primalVariableSolution['x'][i], '%2d' % s.primalVariableSolution['sw_on'][i], '%3d' % s.primalVariableSolution['sw_off'][i], '%7d' % s.primalVariableSolution['sw_stay_on'][i], '%8d' % s.primalVariableSolution['sw_stay_off'][i] ]) print(row) print('cylp ran (not necessarily go a solution)')
class ClpSolver(AbstractSolver): """ Implements the IConcreteSolver class and wraps CyLP. Note that the ClpSolver may require special attention when it comes to removing variables because the implementation of CyLP is not particularly stable. See open GitHub issues: https://github.com/coin-or/CyLP/issues. """ 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 _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) 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) def add_variable(self, var): self.var_to_clp_var[var.id] = self.model.addVariable( "var{}".format(var.id), var.dim) self.var_to_nconstr[var.id] = 0 if var.lb is not None: self.var_to_lower[var.id] = var >= var.lb self.add_constraint(self.var_to_lower[var.id]) if var.ub is not None: self.var_to_upper[var.id] = var <= var.ub self.add_constraint(self.var_to_upper[var.id]) def add_constraint(self, constraint, name=None): # Compute clp constraint constr = self._to_clp_constr(constraint) # Map LP constraint to corresponding clp constraint self.constr_to_clp_constr[constraint] = constr # Generate name for constraint self.clp_constr_to_name[constr] = ( "c" + str(self.constraint_counter)) if name is None else name # Memorize which variables are present in the given constraint self.constr_to_vars[self.clp_constr_to_name[constr]] = constraint.vars for var in constraint.vars: self.var_to_nconstr[var.id] += 1 # Add constraint to CLP model self.model.addConstraint(constr, name=self.clp_constr_to_name[constr]) self.constraint_counter += 1 def variable_solution(self, var): clp_var = self.var_to_clp_var[var.id] return HIPSArray(self.model.primalVariableSolution[clp_var.name]) def optimize(self): # Set objective function with corresponding sense self.model.objective = self.lp_sense.value * self._to_clp_lin_expr( self.objective) self.model.primal() clp_status = self.model.getStatusCode() if clp_status == -1: self.status = LPStatus.UNKNOWN elif clp_status == 0: self.status = LPStatus.OPTIMAL elif clp_status == 1: self.status = LPStatus.INFEASIBLE elif clp_status == 2: self.status = LPStatus.UNBOUNDED else: self.status = LPStatus.ERROR def remove_constraint(self, name=None, constraint=None): try: name = name if name else self.clp_constr_to_name[ self._to_clp_constr(constraint)] variables = self.constr_to_vars[name] if not variables.intersection(set(self.var_to_clp_var.keys())): for var in variables: self.var_to_nconstr[var.id] -= 1 self.model.removeConstraint(name) except: warnings.warn("Constraint {} could not be removed".format(name)) def get_status(self): return self.status def get_objective_value(self): return self.model.objectiveValue * self.lp_sense.value def remove_variable(self, var): if var.id not in self.var_to_clp_var: return if self.var_to_nconstr[var.id] == 0: del self.var_to_clp_var[var.id] del self.var_to_nconstr[var.id] return clp_var = self.var_to_clp_var[var.id] self.model.removeVariable(clp_var.name) del self.var_to_clp_var[var.id] def set_variable_bound(self, var: Variable, bound: VariableBound, value: HIPSArray): if bound == VariableBound.LB: if var.id in self.var_to_lower: self.remove_constraint(self.var_to_lower[var.id]) self.var_to_lower[var.id] = var >= value self.add_constraint(self.var_to_lower[var.id]) if bound == VariableBound.UB: if var.id in self.var_to_upper: self.remove_constraint(self.var_to_upper[var.id]) self.var_to_upper[var.id] = var <= value self.add_constraint(self.var_to_upper[var.id])
l_neg = s_neg.addVariable('l', dim_d) 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() print(s_pos.primalVariableSolution) print(s_pos.dualVariableSolution) cond_pos = s_pos.primalVariableSolution['u'] x1_pos = np.dot(cond_pos, x) y1_pos = np.dot(cond_pos, y_pos) cond_neg = s_neg.primalVariableSolution['u'] x1_neg = np.dot(cond_neg, x) y1_neg = np.dot(cond_neg, y_neg) # print(x1_pos, x1_neg, y1_pos, y1_neg)
def disjunctionToCut(m, pi, pi0, debug_print=False, use_cylp=True, eps=EPS): '''Generate the most violated valid inequality from a given disjunction''' me = "cglp_cuts: " lp = m.lp sol = lp.primalVariableSolution['x'] if debug_print: print(me, "constraints sense = ", m.sense) print(me, "matrix = ") print(m.A) print(me, "rhs = ", m.b) print(me, "vars lower bounds = ", lp.variablesLower) print(me, "vars upper bounds = ", lp.variablesUpper) print(me, "objective = ", lp.objective) print(me, "current solution = ", sol) print(me, "pi = ", pi) print(me, "pi0 = ", pi0) ############################################################################ ## 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. ############################################################################ pi = CyLPArray(pi) Atran = m.A.transpose() b = CyLPArray(m.b) numRows, numCols = m.A.shape if use_cylp: sp = CyLPModel() u = sp.addVariable('u', numRows, isInt=False) v = sp.addVariable('v', numRows, 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) #This should be as simple as this, but it doesn't work. #Maybe a bug in CyLP? #sp += alpha - Atran*u - pi*u0 == 0 #sp += alpha - Atran*v + pi*v0 == 0 for i in range(numCols): sp += alpha[i] - sum(Atran[i, j] * u[j] for j in range(numRows)) - pi[i] * u0 == 0 for i in range(numCols): sp += alpha[i] - sum(Atran[i, j] * v[j] for j in range(numRows)) + pi[i] * v0 == 0 if m.sense == '<=': sp += beta - b * u - pi0 * u0 >= 0 sp += beta - b * v + (pi0 + 1) * v0 >= 0 else: sp += beta - b * u - pi0 * u0 <= 0 sp += beta - b * v + (pi0 + 1) * v0 <= 0 sp += u0 + v0 == 1 sp += u >= 0 sp += v >= 0 sp += u0 >= 0 sp += v0 >= 0 if m.sense == '<=': sp.objective = sum(-sol[i] * alpha[i] for i in range(numCols)) + beta else: #This direction is not debugged sp.objective = sum(sol[i] * alpha[i] for i in range(numCols)) - beta cglp = CyClpSimplex(sp) # If we want to solve it as an MILP # cglp = CyClpSimplex(sp).getCbcModel() #cglp.writeLp('lp.lp') cglp.logLevel = 0 cglp.primal(startFinishOptions='x') # Solve as MILP # cglp.solve() beta = cglp.primalVariableSolution['beta'][0] alpha = cglp.primalVariableSolution['alpha'] u = cglp.primalVariableSolution['u'] v = cglp.primalVariableSolution['v'] u0 = cglp.primalVariableSolution['u0'][0] v0 = cglp.primalVariableSolution['v0'][0] if debug_print: print(me, 'Objective Value: ', cglp.objectiveValue) if debug_print: print(me, 'u: ', u) print(me, 'v: ', v) print(me, 'u0: ', u0) print(me, 'v0: ', v0) else: CG = AbstractModel() CG.u = Var(list(range(numRows)), domain=NonNegativeReals, bounds=(0.0, None)) CG.v = Var(list(range(numRows)), 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(numRows)), 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(numRows)) - x * CG.u0 - CG.alpha[i] == 0.0) CG.pi_rule_left = Constraint(list(range(numCols)), 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(numRows)) + x * CG.v0 - CG.alpha[i] == 0.0) CG.pi_rule_right = Constraint(list(range(numCols)), rule=pi_rule_right) if m.sense == '<=': def pi0_rule_left(CG): return (sum(b[j] * CG.u[j] for j in range(numRows)) - 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(numRows)) + (pi0 + 1) * CG.v0 - CG.beta <= 0.0) CG.pi0_rule_right = Constraint(rule=pi0_rule_right) else: def pi0_rule_left(CG): return (sum(b[j] * CG.u[j] for j in range(numRows)) - 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(numRows)) + (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(numCols)) - CG.beta) if m.sense == '<=': CG.objective = Objective(sense=maximize, rule=objective_rule) else: 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 np.abs(violation) > 10**(-eps): return [(alpha, beta)] print('No violated cuts found solving CGLP', violation) return []
x = lp.addVariable('x', LP.numVars) if LP.sense[0] == '>=': lp += A * x >= b else: lp += A * x <= b #lp += x >= 0 c = CyLPArray(LP.c) # We are maximizing, so negate objective if LP.sense[1] == 'Min': lp.objective = c * x else: lp.objective = -c * x lp.logLevel = 0 lp.primal(startFinishOptions='x') np.set_printoptions(precision=2, linewidth=200) print 'Basic variables: ', lp.basicVariables print "Current tableaux and reduced costs:" print lp.reducedCosts print np.around(lp.tableau, decimals=3) print 'Right-hand side of optimal tableaux:' #There is a bug in CyLP and this is wrong #print lp.rhs if LP.sense[0] == '<=': print np.dot(lp.basisInverse, lp.constraintsUpper) else: print np.dot(lp.basisInverse, lp.constraintsLower) print 'Inverse of optimal basis:' print np.around(lp.basisInverse, 3) if LP.sense[1] == 'Min':
def solve(formula, display=True, export=False, params={}): try: if formula.qmat: warnings.warn('SOC constriants are ignored in the LP solver. ') except AttributeError: pass obj = formula.obj.flatten() linear = formula.linear sense = formula.sense const = formula.const ub = formula.ub lb = formula.lb vtype = formula.vtype eq_linear = linear[sense == 1, :] eq_const = const[sense == 1] ineq_linear = linear[sense == 0, :] ineq_const = const[sense == 0] is_con = vtype == 'C' is_int = vtype == 'I' is_bin = vtype == 'B' s = CyClpSimplex() obj_expr = 0 ncv = sum(is_con) if ncv: cv = s.addVariable('cv', ncv) s += cv <= ub[is_con] s += cv >= lb[is_con] obj_expr += CyLPArray(obj[is_con]) * cv niv = sum(is_int) if niv: iv = s.addVariable('iv', niv, isInt=True) s += iv <= ub[is_int] s += iv >= lb[is_int] obj_expr += CyLPArray(obj[is_int]) * iv nbv = sum(is_bin) if nbv: bv = s.addVariable('bv', nbv) s += bv <= 1 s += bv >= 0 obj_expr += CyLPArray(obj[is_bin]) * bv s.objective = obj_expr if eq_linear.shape[0] > 0: left = 0 if ncv: left += eq_linear[:, is_con] * cv if niv: left += eq_linear[:, is_int] * iv if nbv: left += eq_linear[:, is_bin] * bv s += left == eq_const if ineq_linear.shape[0] > 0: left = 0 if ncv: left += ineq_linear[:, is_con] * cv if niv: left += ineq_linear[:, is_int] * iv if nbv: left += ineq_linear[:, is_bin] * bv s += left <= ineq_const if display: print('Being solved by CyLP...', flush=True) time.sleep(0.2) t0 = time.time() status = s.primal() stime = time.time() - t0 if display: print('Solution status: {0}'.format(status)) print('Running time: {0:0.4f}s'.format(stime)) try: x_sol = np.zeros(linear.shape[1]) if ncv: x_sol[is_con] = s.primalVariableSolution['cv'] if niv: x_sol[is_int] = s.primalVariableSolution['iv'].round() if nbv: x_sol[is_bin] = s.primalVariableSolution['bv'].round() solution = Solution(s.objectiveValue, x_sol, status) except AttributeError: warnings.warn('No feasible solution can be found.') solution = None return solution
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 # 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] # 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 computePriceSweep(thisSlice,chunkNum, qpid, qresult): myLength = thisSlice.shape[1] myPID = multiprocessing.current_process().pid # Add our process id to the list of process ids while qpid.empty(): time.sleep(0.01) pidList = qpid.get() pidList.append(myPID) qpid.put(pidList) storagePriceSet = np.arange(1.0,20.1,0.25) storagePriceSet = np.arange(1.0,3.1,1) eff_round = 0.9 # Round-trip efficiency E_min = 0 E_max = 1 # Endogenous parameters; calculated automatically (eff_in, eff_out) = [np.sqrt(eff_round)] *2 # Properly account for the round trip efficiency of storage P_max = E_max/eff_in # Max discharge power at grid intertie, e.g max limit for C_i P_min = -1*E_max/eff_out # Max charge power at grid intertie, e.g. min D_i # Create a set of zero-filled dataframes for storing results resultIndex = pd.MultiIndex.from_product([thisSlice.index,['size','kwhPassed','profit']]) results = pd.DataFrame(index = resultIndex, columns=storagePriceSet) # Create clean problem matrices - needs efficiency and length! (A, b, A_eq, b_eq) = createABMatrices(myLength, delta_T, eff_in, eff_out, P_min, P_max, E_min, E_max) # Define model: coolStart = CyClpSimplex() coolStart.logLevel = 0 x_var = coolStart.addVariable('x',myLength*3+2) # Add constraints to model: coolStart += A * x_var <= b.toarray() coolStart += A_eq * x_var == b_eq.toarray() newIDs = [] # this holds the names of nodes which we've recently processed def dumpResults(): results.dropna(axis=0,how='all').to_csv('Data/priceSweepResults_pid'+str(myPID)+'temp.csv' ) # Make sure that the results queue hasn't been checked out by somebody else while qresult.empty(): time.sleep(0.01) resultList = qresult.get() resultList[chunkNum] = resultList[chunkNum] + newIDs qresult.put(resultList) for i in range(thisSlice.shape[0]): ## Set up prices myNodeName = thisSlice.index[i] energyPrice = thisSlice.loc[myNodeName,:] / 1000.0 # Price $/kWh as array # if (np.random.random(1)[0] < 0.05): # sys.exit(1) # Randomly kill the process c = np.concatenate([[0.0],[0.0]*(myLength+1),energyPrice,energyPrice],axis=0) #placeholder; No cost for storage state; charged for what we consume, get paid for what we discharge #[[storagePricePlaceholder],[0]*(myLength+1),myPrice,myPrice],axis=1) c_clp = CyLPArray(c) sweepStartTime = time.time() for myStoragePrice in storagePriceSet: c_clp[0] = myStoragePrice * simulationYears coolStart.objective = c_clp * x_var # Run the model coolStart.primal() # Results- Rows are Nodes, indexed by name. Columns are Storage price, indexed by price x_out = coolStart.primalVariableSolution['x'] results.loc[(myNodeName,'size'), myStoragePrice] = x_out[0] results.loc[(myNodeName,'profit'), myStoragePrice] = np.dot(-c, x_out) results.loc[(myNodeName,'kwhPassed'),myStoragePrice] = sum(x_out[2+myLength : 2+myLength*2]) * eff_in # Note: this is the net power pulled from the grid, not the number of cycles when the system is unconstrained storagePriceSet = storagePriceSet[::-1] # Reverse the price set so that we start from the same price for the next node to make warm-start more effective newIDs.append(myNodeName) if (i+1)%5==0: dumpResults() # Write the results to file, and then also update the process Queue with the newIDs = [] # The results should now be all done! dumpResults()
#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 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)