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 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 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(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 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_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(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 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 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 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 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_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_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_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_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_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 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 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
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 __init__(self, module_name=None, file_name=None, A=None, b=None, c=None, points=None, rays=None, sense=None, integerIndices=None, numVars=None): if file_name is not None: # We got a file name, so ignore everything else and read in the instance lp = CyClpSimplex() lp.extractCyLPModel(file_name) self.integerIndices = [ i for (i, j) in enumerate(lp.integerInformation) if j == True ] infinity = lp.getCoinInfinity() A = lp.coefMatrix b = CyLPArray([0 for _ in range(lp.nRows)]) for i in range(lp.nRows): if lp.constraintsLower[i] > -infinity: if lp.constraintsUpper[i] < infinity: raise Exception('Cannot handle ranged constraints') b[i] = -lp.constraintsLower[i] for j in range(lp.nCols): A[i, j] = -A[i, j] elif lp.constraintsUpper[i] < infinity: b[i] = lp.constraintsUpper[i] else: raise Exception('Constraint with no bounds detected') x = lp.addVariable('x', lp.nCols) lp += A * x <= b lp += x <= lp.variablesUpper lp += x >= lp.variablesLower lp.objective = lp.objective self.sense = '<=' numVars = lp.nCols else: min_or_max = None if module_name is not None: # We got a module name, read the data from there mip = ilib.import_module(module_name) self.A = mip.A if hasattr(mip, 'A') else None self.b = mip.b if hasattr(mip, 'b') else None points = mip.points if hasattr(mip, 'points') else None rays = mip.rays if hasattr(mip, 'rays') else None self.c = mip.c if hasattr(mip, 'c') else None self.sense = mip.sense[1] if hasattr(mip, 'sense') else None min_or_max = mip.sense[0] if hasattr(mip, 'sense') else None self.integerIndices = mip.integerIndices if hasattr( mip, 'integerIndices') else None x_u = CyLPArray(mip.x_u) if hasattr(mip, 'x_u') else None numVars = mip.numVars if hasattr(mip, 'numVars') else None self.x_sep = mip.x_sep if hasattr(mip, 'x_sep') else None if numVars is None and mip.A is not None: numVars = len(mip.A) if numVars is None: raise "Must specify number of variables when problem is not" else: self.A = A self.b = b self.c = c self.points = points self.rays = rays if sense is not None: self.sense = sense[1] min_or_max = sense[0] self.integerIndices = integerIndices x_u = None lp = CyClpSimplex() if self.A is not None: A = np.matrix(self.A) b = CyLPArray(self.b) elif numVars <= 2 and GRUMPY_INSTALLED: p = Polyhedron2D(points=points, rays=rays) A = np.matrix(p.hrep.A) b = np.matrix(p.hrep.b) else: raise "Must specify problem in inequality form with more than two variables\n" #Warning: At the moment, you must put bound constraints in explicitly for split cuts x_l = CyLPArray([0 for _ in range(numVars)]) x = lp.addVariable('x', numVars) lp += x >= x_l if x_u is not None: lp += x <= x_u lp += (A * x <= b if self.sense == '<=' else A * x >= b) c = CyLPArray(self.c) if min_or_max == 'Max': lp.objective = -c * x else: lp.objective = c * x self.lp = lp self.x = x
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 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
s= CyClpSimplex() u = s.addVariable('u',dim_p) l = s.addVariable('l',dim_d) print(s.variableScale) v = s.variables s += A_p*u+A_d1*l == b_p for i in range(dim_p): s+=u[i] >= 0 s += A_d*l <= b_d s.objective = u[0] s.primal() print(s.primalVariableSolution) print(s.dualVariableSolution) print(s.dualConstraintSolution) print(s.primalConstraintSolution) cond = s.primalVariableSolution['u'] x1 = np.dot(cond, x) y1 = np.dot(cond, y) print(x1, y1)
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)')
u_pos = s_pos.addVariable('u', dim_p) l_pos = s_pos.addVariable('l', dim_d) u_neg = s_neg.addVariable('u', dim_p) 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)
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)
from cylp.cy import CyClpSimplex from cylp.py.modeling.CyLPModel import CyLPArray import numpy as np model = CyClpSimplex() x_var = model.addVariable('x',3) A = np.matrix([[1.,2.,0],[1.,0,1.]]) c = np.array([1.,2.,3.]) c_clp = CyLPArray([1.,2.,3.]) print(x_var.value) print(c_clp.value) model.objective = c_clp * x_var
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()
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: 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:
def solve_ilp(self): """ Solves problem exactly using MIP/ILP approach Used solver: CoinOR CBC Incidence-matrix Q holds complete information needed for opt-process """ if self.verbose: print('Solve: build model') if self.condorcet_red: condorcet_red_mat = extended_condorcet_simple(self.votes_arr) n = self.Q.shape[0] x_n = n * n model = CyClpSimplex() # MODEL x = model.addVariable('x', x_n, isInt=True) # VARS model.objective = self.Q.ravel() # OBJ # x_ab = boolean (already int; need to constrain to [0,1]) model += sp.eye(x_n) * x >= np.zeros(x_n) model += sp.eye(x_n) * x <= np.ones(x_n) idx = lambda i, j: np.ravel_multi_index((i, j), (n, n)) # constraints for every pair start_time = time() n_pairwise_constr = n * (n - 1) // 2 if self.verbose: print(' # pairwise constr: ', n_pairwise_constr) # Somewhat bloated just to get some vectorization / speed ! combs_ = combs(range(n), 2) inds_a = np.ravel_multi_index(combs_.T, (n, n)) inds_b = np.ravel_multi_index(combs_.T[::-1], (n, n)) row_inds = np.tile(np.arange(n_pairwise_constr), 2) col_inds = np.hstack((inds_a, inds_b)) pairwise_constraints = sp.coo_matrix( (np.ones(n_pairwise_constr * 2), (row_inds, col_inds)), shape=(n_pairwise_constr, n * n)) end_time = time() if self.verbose: print(" Took {:.{prec}f} secs".format(end_time - start_time, prec=3)) # and for every cycle of length 3 start_time = time() n_triangle_constrs = n * (n - 1) * (n - 2) if self.verbose: print(' # triangle constr: ', n_triangle_constrs) # Somewhat bloated just to get some vectorization / speed ! perms_ = perms(range(n), 3) inds_a = np.ravel_multi_index(perms_.T[(0, 1), :], (n, n)) inds_b = np.ravel_multi_index(perms_.T[(1, 2), :], (n, n)) inds_c = np.ravel_multi_index(perms_.T[(2, 0), :], (n, n)) row_inds = np.tile(np.arange(n_triangle_constrs), 3) col_inds = np.hstack((inds_a, inds_b, inds_c)) triangle_constraints = sp.coo_matrix( (np.ones(n_triangle_constrs * 3), (row_inds, col_inds)), shape=(n_triangle_constrs, n * n)) end_time = time() if self.verbose: print(" Took {:.{prec}f} secs".format(end_time - start_time, prec=3)) model += pairwise_constraints * x == np.ones(n_pairwise_constr) model += triangle_constraints * x >= np.ones(n_triangle_constrs) if self.condorcet_red and condorcet_red_mat != None: I, J, V = sp.find(condorcet_red_mat) indices_pos = np.ravel_multi_index([J, I], (n, n)) indices_neg = np.ravel_multi_index([I, J], (n, n)) nnz = len(indices_pos) if self.verbose: print( ' Extended Condorcet reductions: {} * 2 relations fixed'. format(nnz)) lhs = sp.coo_matrix( (np.ones(nnz * 2), (np.arange(nnz * 2), np.hstack((indices_pos, indices_neg)))), shape=(nnz * 2, n * n)) rhs = np.hstack( (np.ones(len(indices_pos)), np.zeros(len(indices_neg)))) model += lhs * x == rhs cbcModel = model.getCbcModel() # Clp -> Cbc model / LP -> MIP cbcModel.logLevel = self.verbose if self.verbose: print('Solve: run MIP\n') start_time = time() status = cbcModel.solve() #-> "Call CbcMain. Solve the problem # "using the same parameters used # "by CbcSolver." # This deviates from cylp's docs which are sparse! # -> preprocessing will be used and is very important! end_time = time() if self.verbose: print(" CoinOR CBC used {:.{prec}f} secs".format(end_time - start_time, prec=3)) x_sol = cbcModel.primalVariableSolution['x'] self.obj_sol = cbcModel.objectiveValue x = np.array(x_sol).reshape((n, n)).round().astype(int) self.aggr_rank = np.argsort(x.sum(axis=0))[::-1]
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: 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:
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) #y = model.addVariable('y', 4) #z = model.addVariable('z', 5) # # #b = CyLPArray([3.1, 4.2]) #aa = np.matrix([[1, 2, 3, 3, 4], [3, 2, 1, 2, 5]]) #aa = np.matrix([[0, 0, 0, -1.5, -1.5], [-3, 0, 0, -2,0 ]])
def tournament(args): # Configuration engine = create_engine('sqlite:///' + args.bdd, echo=False) DBSession.configure(bind=engine) # On récupere les donnes de la BDD students = DBSession.query(Etudiant).filter(Etudiant.enseignant.is_(None)) nb_students = DBSession.query(Etudiant).filter( Etudiant.enseignant.is_(None)).count() nb_parcours = DBSession.query(Parcours).count() # Capacité des groupes capa_min_pec = 14 capa_max_pec = 16 capa_min_pel = 14 capa_max_pel = 16 # On construit le modèle barre_min = args.b model = CyClpSimplex() x = [] s_list = {} for s in students.all(): v = model.addVariable('etu' + str(s.id), nb_parcours, isInt=True) x.append(v) z = 0.0 i = 0 for s in students.all(): reorder = False s_list[str(i)] = s.id voeux = DBSession.query(Voeu).filter(Voeu.idEtudiant == s.id).order_by( Voeu.idParcours).all() s_voeux = [] rang_q = voeux[nb_parcours - 1].rang if rang_q != nb_parcours and rang_q != -1: if s.nom not in special or 'quebec' not in special[s.nom]: reorder = True else: reorder = not special[s.nom]['quebec'] for v in voeux: if v.rang == -1: score = 0 else: if reorder and v.rang > rang_q: rang = v.rang - 1 elif reorder and v.rang == rang_q: rang = 9 else: rang = v.rang malus = 0.0 if s.malus > 0: malus += s.malus if s.absences is not None: malus += float(s.absences) / 15 score = 2.0**(rang - malus) s_voeux.append(score) a = CyLPArray(s_voeux) b = CyLPArray([1.0 for j in range(nb_parcours)]) z += a * x[i] model += b * x[i] >= 1 model += b * x[i] <= 1 model += x[i] >= 0 model += x[i] <= 1 i += 1 model.objective = z # Taille des groupes MpInge (PEL) for j in [ 0, 3, 6 ]: # Attention, dans la BDD, le parcours vont de 1 à 8 -> décalage de 1 c = 0 for i in range(nb_students): c += x[i][j] model += c <= capa_max_pel model += c >= capa_min_pel # Taille des groupes PEC for j in [1, 2, 4, 5, 7]: c = 0 for i in range(nb_students): c += x[i][j] model += c <= capa_max_pec model += c >= capa_min_pec # Etudiants trop bas en maths i = 0 for s in students.all(): if s.moyenneMaths is not None and s.moyenneMaths < barre_min: model += x[i][0] + x[i][3] + x[i][6] == 0 i += 1 # Québec i = 0 for s in students.all(): if s.nom not in special or 'quebec' not in special[s.nom]: model += x[i][nb_parcours - 1] == 0 i += 1 # Cas particuliers (cf special.py) i = 0 for s in students.all(): if s.nom in special and 'force' in special[s.nom]: for cas in special[s.nom]['force']: if not special[s.nom]['force'][cas]: model += x[i][int(cas) - 1] == 0 i += 1 cbc_model = model.getCbcModel() cbc_model.logLevel = 0 cbc_model.branchAndBound() if cbc_model.isRelaxationOptimal() and args.v: for s in students.all(): r = cbc_model.primalVariableSolution['etu' + str(s.id)] print s.nom + '|', j = 1 reorder = False for res in r: if res == 1: if j == 1 or j == 4 or j == 7: print "!", par = DBSession.query(Parcours).filter( Parcours.id == j).one() print par.nom, voeux = DBSession.query(Voeu).filter( Voeu.idEtudiant == s.id).order_by( Voeu.idParcours).all() rang_q = voeux[nb_parcours - 1].rang if rang_q != nb_parcours and rang_q != -1: if s.nom not in special or 'quebec' not in special[ s.nom]: reorder = True else: reorder = not special[s.nom]['quebec'] son_voeu = DBSession.query(Voeu).filter( Voeu.idEtudiant == s.id).filter( Voeu.idParcours == j).one() if reorder and son_voeu.rang == rang_q: rang = 9 elif reorder and son_voeu.rang > rang_q: rang = son_voeu.rang - 1 else: rang = son_voeu.rang print '|' + str(rang) + '', print '|' + str(s.moyenneMaths), print '|' + str(s.absences), if reorder: print '|*' else: print '|' j += 1 nb_stu_grp = [0 for n in range(nb_parcours)] rangs_stu = [0 for n in range(nb_parcours)] indecis = 0 pec2pel = 0 pel2pec = 0 if cbc_model.isRelaxationOptimal() and (args.s or args.csv): for s in students.all(): r = cbc_model.primalVariableSolution['etu' + str(s.id)] j = 1 reorder = False for res in r: if res == 1: nb_stu_grp[j - 1] += 1 voeux = DBSession.query(Voeu).filter( Voeu.idEtudiant == s.id).order_by( Voeu.idParcours).all() rang_q = voeux[nb_parcours - 1].rang if rang_q != nb_parcours and rang_q != -1: if s.nom not in special or 'quebec' not in special[ s.nom]: reorder = True else: reorder = not special[s.nom]['quebec'] son_voeu = DBSession.query(Voeu).filter( Voeu.idEtudiant == s.id).filter( Voeu.idParcours == j).one() if reorder and son_voeu.rang == rang_q: rang = 9 elif reorder and son_voeu.rang > rang_q: rang = son_voeu.rang - 1 else: rang = son_voeu.rang if rang != -1: rangs_stu[rang - 1] += 1 son_voeu_un = DBSession.query(Voeu).filter( Voeu.idEtudiant == s.id).filter( Voeu.rang == 1).one() if son_voeu_un.idParcours in [ 1, 4, 7 ] and son_voeu.idParcours not in [1, 4, 7]: pel2pec += 1 elif son_voeu_un.idParcours not in [ 1, 4, 7 ] and son_voeu.idParcours in [1, 4, 7]: pec2pel += 1 else: indecis += 1 j += 1 if args.s: print "Etudiants par groupe : ", nb_stu_grp print "Etudiants par rang de voeu : ", rangs_stu print "Passages PEC->PEL", pec2pel print "Passage PEL->PEC", pel2pec print "Indécis : ", indecis if args.csv: print barre_min, ",", for item in nb_stu_grp: print item, ",", for item in rangs_stu: print item, ",", print pec2pel, ",", pel2pec if cbc_model.isRelaxationInfeasible(): print "Pas de solution possible"
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) #y = model.addVariable('y', 4) #z = model.addVariable('z', 5) # # #b = CyLPArray([3.1, 4.2]) #aa = np.matrix([[1, 2, 3, 3, 4], [3, 2, 1, 2, 5]]) #aa = np.matrix([[0, 0, 0, -1.5, -1.5], [-3, 0, 0, -2,0 ]])
def __init__(self, module_name = None, file_name = None, A = None, b = None, c = None, points = None, rays = None, sense = None, integerIndices = None, numVars = None): if file_name is not None: # We got a file name, so ignore everything else and read in the instance lp = CyClpSimplex() lp.extractCyLPModel(file_name) self.integerIndices = [i for (i, j) in enumerate(lp.integerInformation) if j == True] infinity = lp.getCoinInfinity() A = lp.coefMatrix b = CyLPArray([0 for _ in range(lp.nRows)]) for i in range(lp.nRows): if lp.constraintsLower[i] > -infinity: if lp.constraintsUpper[i] < infinity: raise Exception('Cannot handle ranged constraints') b[i] = -lp.constraintsLower[i] for j in range(lp.nCols): A[i, j] = -A[i, j] elif lp.constraintsUpper[i] < infinity: b[i] = lp.constraintsUpper[i] else: raise Exception('Constraint with no bounds detected') x = lp.addVariable('x', lp.nCols) lp += A * x <= b lp += x <= lp.variablesUpper lp += x >= lp.variablesLower lp.objective = lp.objective self.sense = '<=' numVars = lp.nCols else: min_or_max = None if module_name is not None: # We got a module name, read the data from there mip = ilib.import_module(module_name) self.A = mip.A if hasattr(mip, 'A') else None self.b = mip.b if hasattr(mip, 'b') else None points = mip.points if hasattr(mip, 'points') else None rays = mip.rays if hasattr(mip, 'rays') else None self.c = mip.c if hasattr(mip, 'c') else None self.sense = mip.sense[1] if hasattr(mip, 'sense') else None min_or_max = mip.sense[0] if hasattr(mip, 'sense') else None self.integerIndices = mip.integerIndices if hasattr(mip, 'integerIndices') else None x_u = CyLPArray(mip.x_u) if hasattr(mip, 'x_u') else None numVars = mip.numVars if hasattr(mip, 'numVars') else None self.x_sep = mip.x_sep if hasattr(mip, 'x_sep') else None if numVars is None and mip.A is not None: numVars = len(mip.A) if numVars is None: raise "Must specify number of variables when problem is not" else: self.A = A self.b = b self.c = c self.points = points self.rays = rays if sense is not None: self.sense = sense[1] min_or_max = sense[0] self.integerIndices = integerIndices x_u = None lp = CyClpSimplex() if self.A is not None: A = np.matrix(self.A) b = CyLPArray(self.b) elif numVars <= 2 and GRUMPY_INSTALLED: p = Polyhedron2D(points = points, rays = rays) A = np.matrix(p.hrep.A) b = np.matrix(p.hrep.b) else: raise "Must specify problem in inequality form with more than two variables\n" #Warning: At the moment, you must put bound constraints in explicitly for split cuts x_l = CyLPArray([0 for _ in range(numVars)]) x = lp.addVariable('x', numVars) lp += x >= x_l if x_u is not None: lp += x <= x_u lp += (A * x <= b if self.sense == '<=' else A * x >= b) c = CyLPArray(self.c) if min_or_max == 'Max': lp.objective = -c * x else: lp.objective = c * x self.lp = lp self.x = x