def solve(self, objective, constraints, cached_data, warm_start, verbose, solver_opts): """Returns the result of the call to the solver. Parameters ---------- objective : LinOp The canonicalized objective. constraints : list The list of canonicalized cosntraints. cached_data : dict A map of solver name to cached problem data. warm_start : bool Not used. verbose : bool Should the solver print output? solver_opts : dict Additional arguments for the solver. Returns ------- tuple (status, optimal value, primal, equality dual, inequality dual) """ # Import basic modelling tools of cylp from cylp.cy import CyClpSimplex from cylp.py.modeling.CyLPModel import CyLPModel, CyLPArray # Get problem data data = self.get_problem_data(objective, constraints, cached_data) c = data[s.C] b = data[s.B] A = data[s.A] dims = data[s.DIMS] data[s.BOOL_IDX] = solver_opts[s.BOOL_IDX] data[s.INT_IDX] = solver_opts[s.INT_IDX] n = c.shape[0] # Problem model = CyLPModel() # Variables x = model.addVariable('x', n) # Constraints # eq model += A[0:dims[s.EQ_DIM], :] * x == CyLPArray(b[0:dims[s.EQ_DIM]]) # leq leq_start = dims[s.EQ_DIM] leq_end = dims[s.EQ_DIM] + dims[s.LEQ_DIM] model += A[leq_start:leq_end, :] * x <= CyLPArray(b[leq_start:leq_end]) # Objective model.objective = c # Convert model model = CyClpSimplex(model) # No boolean vars available in Cbc -> model as int + restrict to [0,1] if self.is_mip(data): # Mark integer- and binary-vars as "integer" model.setInteger(x[data[s.BOOL_IDX]]) model.setInteger(x[data[s.INT_IDX]]) # Restrict binary vars only idxs = data[s.BOOL_IDX] n_idxs = len(idxs) model.setColumnLowerSubset(np.arange(n_idxs, dtype=np.int32), np.array(idxs, np.int32), np.zeros(n_idxs)) model.setColumnUpperSubset(np.arange(n_idxs, dtype=np.int32), np.array(idxs, np.int32), np.ones(n_idxs)) # Verbosity Clp if not verbose: model.logLevel = 0 # Build model & solve status = None if self.is_mip(data): # Convert model cbcModel = model.getCbcModel() # Verbosity Cbc if not verbose: cbcModel.logLevel = 0 # cylp: /cylp/cy/CyCbcModel.pyx#L134 # Call CbcMain. Solve the problem using the same parameters used by # CbcSolver. Equivalent to solving the model from the command line # using cbc's binary. cbcModel.solve() status = cbcModel.status else: # cylp: /cylp/cy/CyClpSimplex.pyx # Run CLP's initialSolve. It does a presolve and uses primal or dual # Simplex to solve a problem. status = model.initialSolve() results_dict = {} results_dict["status"] = status if self.is_mip(data): results_dict["x"] = cbcModel.primalVariableSolution['x'] results_dict["obj_value"] = cbcModel.objectiveValue else: results_dict["x"] = model.primalVariableSolution['x'] results_dict["obj_value"] = model.objectiveValue return self.format_results(results_dict, data, cached_data)
def solve_via_data(self, data, warm_start, verbose, solver_opts, solver_cache=None): # Import basic modelling tools of cylp from cylp.cy import CyClpSimplex from cylp.py.modeling.CyLPModel import CyLPModel, CyLPArray c = data[s.C] b = data[s.B] A = data[s.A] dims = dims_to_solver_dict(data[s.DIMS]) n = c.shape[0] # Problem model = CyLPModel() # Variables x = model.addVariable('x', n) # Constraints # eq model += A[0:dims[s.EQ_DIM], :] * x == CyLPArray(b[0:dims[s.EQ_DIM]]) # leq leq_start = dims[s.EQ_DIM] leq_end = dims[s.EQ_DIM] + dims[s.LEQ_DIM] model += A[leq_start:leq_end, :] * x <= CyLPArray(b[leq_start:leq_end]) # Objective model.objective = c # Convert model model = CyClpSimplex(model) # No boolean vars available in Cbc -> model as int + restrict to [0,1] if data[s.BOOL_IDX] or data[s.INT_IDX]: # Mark integer- and binary-vars as "integer" model.setInteger(x[data[s.BOOL_IDX]]) model.setInteger(x[data[s.INT_IDX]]) # Restrict binary vars only idxs = data[s.BOOL_IDX] n_idxs = len(idxs) model.setColumnLowerSubset(np.arange(n_idxs, dtype=np.int32), np.array(idxs, np.int32), np.zeros(n_idxs)) model.setColumnUpperSubset(np.arange(n_idxs, dtype=np.int32), np.array(idxs, np.int32), np.ones(n_idxs)) # Verbosity Clp if not verbose: model.logLevel = 0 # Build model & solve status = None if data[s.BOOL_IDX] or data[s.INT_IDX]: # Convert model cbcModel = model.getCbcModel() for key, value in solver_opts.items(): setattr(cbcModel, key, value) # Verbosity Cbc if not verbose: cbcModel.logLevel = 0 # cylp: /cylp/cy/CyCbcModel.pyx#L134 # Call CbcMain. Solve the problem using the same parameters used by # CbcSolver. Equivalent to solving the model from the command line # using cbc's binary. cbcModel.solve() status = cbcModel.status else: # cylp: /cylp/cy/CyClpSimplex.pyx # Run CLP's initialSolve. It does a presolve and uses primal or dual # Simplex to solve a problem. status = model.initialSolve() solution = {} if data[s.BOOL_IDX] or data[s.INT_IDX]: solution["status"] = self.STATUS_MAP_MIP[status] solution["primal"] = cbcModel.primalVariableSolution['x'] solution["value"] = cbcModel.objectiveValue else: solution["status"] = self.STATUS_MAP_LP[status] solution["primal"] = model.primalVariableSolution['x'] solution["value"] = model.objectiveValue return solution