def solve(self, solver_name: str = "cbc", initial_tour: List[int] = None, threads: int = 2) -> List[int]: ws = False if initial_tour: self.warmStart(initial_tour) ws = True if solver_name == "cbc": solver = pulp.PULP_CBC_CMD(msg=0, warmStart=ws, threads=threads) elif solver_name == "cplex": solver = pulp.CPLEX_CMD(msg=0, threads=threads) else: print(f"Cannot use {solver_name} to solve.") print("We use cbc solver instead.") try: status = self.problem.solve(solver) except: solver = pulp.PULP_CBC_CMD(msg=0, warmStart=ws, threads=threads) status = self.problem.solve(solver) tour = list(self.cities) tour.sort(key=lambda x: self.u[x].value()) for i, j in zip(tour, tour[1:] + tour[:1]): assert isclose(self.x[i][j].value(), 1) assert len(tour) == self.ncity return tour
def linearProgramming(self): numActions, numStates, y, T, R = self.numActions, self.numStates, self.discount, self.transition, self.reward pi = np.zeros(numStates, dtype=int) V = np.zeros(numStates, dtype=float) Lp_prob = pulp.LpProblem('policyEvaluation', pulp.LpMinimize) #adding var ValueVar = [] for i in range(numStates): variable = str('V' + str(i)) variable = pulp.LpVariable(variable) ValueVar.append(variable) ValueVar = np.array(ValueVar) #Objective Lp_prob += ValueVar.sum() # Constraints: '''for s,listItem in enumerate(transitionList): print([ p*(r+y*ValueVar[s2]) for a, s2, r, p in listItem ]) Lp_prob +=ValueVar[s]>=pulp.lpSum([ p*(r+y*ValueVar[s2]) for a, s2, r, p in transitionList[s] ])''' for s in range(numStates): for a in range(numActions): Lp_prob += ValueVar[s] >= T[s][a].dot((R[s][a] + y * ValueVar)) status = pulp.PULP_CBC_CMD(msg=0).solve(Lp_prob) #status = pulp.PULP_CBC_CMD(msg=0,path='/Library/Python/3.8/site-packages/pulp/solverdir/cbc/linux/64/cbc').solve(Lp_prob) assert status == pulp.LpStatusOptimal for i, v in enumerate(ValueVar): V[i] = pulp.value(v) V = np.round(V, decimals=6) for s in range(numStates): pi[s] = np.argmax(np.einsum('ij,ij->i', T[s], R[s] + y * V)) return (V, pi)
def main(): data = { 'エスプレッソアイス': { '牛乳': 100, '作業時間': 7, '儲け': 250 }, 'ラズベリーアイス': { '牛乳': 150, '作業時間': 5, '儲け': 300 }, } v = {} for k in data.keys(): v[k] = pulp.LpVariable(f'v_{k}', lowBound=0, cat=pulp.LpInteger) problem = pulp.LpProblem("アイス生産問題", pulp.LpMaximize) problem += pulp.lpSum([v[x] * data[x]['儲け'] for x in data.keys()]) problem += pulp.lpSum([v[x] * data[x]['牛乳'] for x in data.keys()]) <= 8000 problem += pulp.lpSum([v[x] * data[x]['作業時間'] for x in data.keys()]) <= 360 solver = pulp.PULP_CBC_CMD(msg=False) result = problem.solve(solver) print(pulp.value(result)) if result == pulp.LpStatusOptimal: print(pulp.value(problem.objective)) for k in data.keys(): print(pulp.value(v[k]))
def __calcImportance(self, solutionsList): '''Calculates the importance of a weight using Equation 2 to find the lower point and Proposition 4 of the referenced work to calculate the importance. ''' oidx = [i for i in range(self.M)] prob = lp.LpProblem("Lower point", lp.LpMinimize) uR = list(lp.LpVariable.dicts('uR', oidx, cat='Continuous').values()) for value, sols in enumerate(solutionsList): expr = lp.lpDot(self.__normw(sols.w), uR) cons = self.__normf(sols.objs) @ self.__normw(sols.w) prob += expr >= cons prob += lp.lpDot(self.__normw(self.w), uR) grbs = lp.GUROBI(msg=False, OutputFlag=False, Threads=1) if grbs.available(): prob.solve(grbs) else: cbcs = lp.PULP_CBC_CMD(threads=1) prob.solve(cbcs, use_mps=False) feasible = False if prob.status in [-1, -2] else True self.__uR = np.array([lp.value(uR[i]) for i in oidx]) if feasible: self.__importance = ((self.__normw(self.w) @ self.__point - self.__normw(self.w) @ self.__uR) / (self.__normw(sols.w) @ np.ones(self.M))) else: raise ('Non-feasible solution')
def convexCombination(points, point): '''Calculates if a point is a convex combination of another points in the hull, this is done to avoid unecessary point in the hull calculation. ''' points_idx = [i for i in range(len(points))] dim_idx = [j for j in range(len(point))] prob = lp.LpProblem("max mean", lp.LpMinimize) alpha = list( lp.LpVariable.dicts('alpha', points_idx, cat='Continuous').values()) for j in dim_idx: prob += (lp.lpSum([alpha[i] * points[i][j] for i in points_idx]) == point[j]) prob += lp.lpSum([alpha[i] for i in points_idx]) == 1 for i in points_idx: if all(points[i] == point): prob += alpha[i] == 0 else: prob += alpha[i] >= 0 grbs = lp.GUROBI(msg=False, OutputFlag=False, Threads=1) if grbs.available(): prob.solve(grbs) else: cbcs = lp.PULP_CBC_CMD(threads=1) prob.solve(cbcs, use_mps=False) feasible = False if prob.status in [-1, -2] else True return feasible
def _solve(self): if self.solver == "cbc": self.prob.solve( pulp.PULP_CBC_CMD( msg=0, maxSeconds=self.time_limit, options=["startalg", "barrier", "crossover", "0"], )) elif self.solver == "cplex": self.prob.solve( pulp.CPLEX_CMD( msg=0, timelimit=self.time_limit, options=["set lpmethod 4", "set barrier crossover -1"], )) elif self.solver == "gurobi": gurobi_options = [ ("Method", 2), # 2 = barrier ("Crossover", 0), ] # Only specify time limit if given (o.w. errors) if self.time_limit is not None: gurobi_options.append(( "TimeLimit", self.time_limit, )) self.prob.solve(pulp.GUROBI(msg=0, options=gurobi_options))
def lp(mdp): model = pulp.LpProblem("MDP_Solver", pulp.LpMinimize) # define variables state_dict = pulp.LpVariable.dicts("states", (i for i in range(mdp.num_states)), cat='Continuous') # objective model += pulp.lpSum([state_dict[i] for i in range(mdp.num_states)]) # set up constraints for state in range(mdp.num_states): for action in range(mdp.num_actions): model += pulp.lpSum([ mdp.t[state, action, i] * (mdp.gamma * state_dict[i] + mdp.r[state, action, i]) for i in range(mdp.num_states) ]) <= state_dict[state] # solve solver = pulp.PULP_CBC_CMD(msg=False) model.solve(solver) # get the optimal value function for state in state_dict: mdp.value_function[state] = state_dict[state].varValue mdp.update_action_value() mdp.policy = np.argmax(mdp.action_value, axis=1) mdp.update_value_function()
def linear_prog(numStates, numActions, rewards, transition, discount, mdpType, end): lin_prog = LpProblem("MDP", LpMinimize) decision_var = LpVariable.dict("value_function", range(numStates)) LpSolverDefault.msg = 0 # The Objective Function lin_prog += lpSum([decision_var[i] for i in range(numStates)]) # adding constraints V = np.zeros((numStates, 1), dtype=LpVariable) for i in range(numStates): V[i][0] = decision_var[i] for state in range(numStates): for action in range(numActions): lowerBound = bellman_equations(transition[state][action], rewards[state][action], V, discount) lin_prog += decision_var[state] >= lowerBound if (mdpType == "episodic"): for i in end: lin_prog += (decision_var[i] == 0) lin_prog.solve(pulp.PULP_CBC_CMD(msg=0)) V = np.zeros((numStates, 1)) for i in range(numStates): V[i][0] = decision_var[i].varValue P = np.zeros((numStates, 1), dtype=int) tmp = np.zeros((numActions, )) for state in range(numStates): for action in range(numActions): tmp[action] = bellman_equations(transition[state][action], rewards[state][action], V, discount) P[state][0] = np.argmax(tmp) return P, V
def solve_truck_problem(file_path): """TODO: Description.""" # ------------------------------------------------------------------------ # # Set data # ------------------------------------------------------------------------ # graph, source, p = extract_data(file_path) # ------------------------------------------------------------------------ # # Solve the problem using the model # ------------------------------------------------------------------------ # prob = set_benef_max(graph, source, p) # Coin Branch and Cut solver is used to solve the instanced model log_path = './output' if not os.path.exists(log_path): os.mkdir(log_path) prob.solve(pl.PULP_CBC_CMD(logPath=log_path + '/log_path_file.log')) # ------------------------------------------------------------------------ # # Print the solver output # ------------------------------------------------------------------------ # print(f'Status:\n{pl.LpStatus[prob.status]}') print() print('-' * 40) print() # Each of the variables is printed with it's resolved optimum value for v in prob.variables(): print(v.name, '=', v.varValue) print("benefice max : ", pl.value(prob.objective))
def optimize(model): w = 7 model += plp.lpSum( get_sink_inflow()) - w * plp.lpSum(z(model)) #- v * plp.lpSum(y()) # Solves With a cut of of fracGap model.solve(plp.PULP_CBC_CMD(fracGap=0.3, msg=False))
def solve(self, options: dict) -> dict: model = pl.LpProblem("rostering", pl.LpMaximize) # Variables: self.create_variables() # Constraints: model = self.create_constraints(model) # print(model) # Solver and solve mat_solver = pl.PULP_CBC_CMD( gapRel=0.001, timeLimit=options.get("timeLimit", 240), msg=options.get("msg", False), ) status = model.solve(mat_solver) # Check status if model.sol_status not in [pl.LpSolutionIntegerFeasible, pl.LpSolutionOptimal]: return dict(status=status, status_sol=SOLUTION_STATUS_INFEASIBLE) work_assignments = ( self.works.vfilter(lambda v: pl.value(v)) .keys_tl() .vapply(lambda v: dict(id_employee=v[1], time_slot=v[0])) ) self.solution = Solution.from_dict(SuperDict(works=work_assignments)) return dict(status=status, status_sol=SOLUTION_STATUS_FEASIBLE)
def solve(self, time_limit): if not self.run_subsolve: return self.routes, False self.formulate() # self.prob.writeLP("subprob.lp") if self.solver == "cbc": self.prob.solve(pulp.PULP_CBC_CMD(maxSeconds=time_limit)) elif self.solver == "cplex": self.prob.solve(pulp.solvers.CPLEX_CMD(msg=0, timelimit=time_limit)) elif self.solver == "gurobi": gurobi_options = [("TimeLimit", time_limit)] self.prob.solve(pulp.solvers.GUROBI_CMD(options=gurobi_options)) logger.debug("") logger.debug("Solving subproblem using LP") logger.debug("Status: %s" % pulp.LpStatus[self.prob.status]) logger.debug("Objective %s" % pulp.value(self.prob.objective)) if pulp.value(self.prob.objective) is not None and pulp.value( self.prob.objective) < -(10**-3): more_routes = True self.add_new_route() return self.routes, more_routes else: more_routes = False return self.routes, more_routes
def soln(S, A, R, T, gamma): V = np.zeros(S) V_list = [] for s in range(S): V_list.append(LpVariable(f"V{s}")) V_list = np.array(V_list) C_list = np.sum(np.multiply(T, R + gamma * V_list), axis=2) prob = LpProblem("MDP_Planning", LpMaximize) prob += -pulp.lpSum(V_list) for s in range(S): for a in range(A): prob += pulp.lpSum(C_list[s][a]) <= V_list[s] status = prob.solve(pulp.PULP_CBC_CMD(msg=0)) if (pulp.LpStatus[status] == 'Optimal'): logging.debug("Linear Programming [OK]") else: logging.error("Linear Programming [FAILED]") for s in range(S): V[s] = pulp.value(V_list[s]) # Finding policy* Policy = np.argmax(np.sum(np.multiply(T, R + gamma * V), axis=2), axis=1) return V, Policy
def lpp_method(self): start_t = time.time() # Create a LP Minimization problem Lp_prob = p.LpProblem('LPP', p.LpMaximize) #create problem variables V = [] for s in range(self.numStates): V.append(p.LpVariable(f"V{s}")) #objective function Lp_prob += -1 * sum(V) #constraints for s in range(self.numStates): for a in range(self.numActions): rhs = [] s_prime_arr = np.where(np.abs(self.T[s, a, :] - 1.0) < 1e-6)[0] for s_prime in range(self.numStates): rhs.append( self.T[s, a, s_prime] * (self.R[s, a, s_prime] + self.discount * V[s_prime])) Lp_prob += V[s] >= sum(rhs) end_t = time.time() # print('execution time for creating lpp = ', end_t-start_t) start_t = time.time() #status # status = Lp_prob.solve() p.PULP_CBC_CMD(msg=False).solve(Lp_prob) # print(p.LpStatus[status]) optimal_V = np.zeros(self.numStates) for s in range(self.numStates): optimal_V[s] = p.value(V[s]) end_t = time.time() # print('time to solve lpp = ', end_t-start_t) return optimal_V, self._pi_from_V(optimal_V)
def solve(self, max_time, opt_gap, verbose=1): """ Solve the Integers Linear Program instance built in self.build_model(). Args : max_time : int, maximum running time required in seconds. opt_gap : float, in (0, 1), if max_time is None, then the objective value of the solution is guaranteed to be at most opt_gap % larger than the true optimum. verbose : 1 to print log of resolution. 0 for nothing. Returns : Status of the model : Infeasible or Optimal. Infeasible indicates that all constraints could not be met. Optimal indicates that the model has been solved optimally. """ start = time.time() self.model.solve( plp.PULP_CBC_CMD(maxSeconds=max_time, fracGap=opt_gap, msg=verbose, mip_start=False, options=["randomCbcSeed 31"])) #Get Status print("Status:", plp.LpStatus[self.model.status]) print("Total Costs = ", plp.value(self.model.objective)) print("Solving time : ", round(time.time() - start, 3), " seconds.") return plp.LpStatus[self.model.status]
def lpSolution(mdp: MDP, errorMargin): lpProb = pulp.LpProblem("MDP_solution", pulp.LpMinimize) stateValues = pulp.LpVariable.dicts(name='V', indexs=list(range(mdp.S)), cat=pulp.LpContinuous) # Objective function lpProb += pulp.lpSum(stateValues) # Constraints for s in range(mdp.S): for a in range(mdp.A): lpProb += pulp.lpSum( [mdp.T[s][a][i] * (mdp.R[s][a][i] + (mdp.gamma * stateValues[i])) for i in range(mdp.S)]) <= \ stateValues[s] status = lpProb.solve( solver=pulp.PULP_CBC_CMD(msg=False, gapRel=errorMargin)) assert pulp.LpStatus[status] == 'Optimal' V, pi = np.zeros((mdp.S, 1)), np.zeros((mdp.S, 1)) for s in range(mdp.S): V[s] = pulp.value(stateValues[s]) pi = np.zeros_like(V) for s in range(mdp.S): pi[s] = np.argmax( np.sum(mdp.T[s] * (mdp.R[s] + (mdp.gamma * np.transpose(V))), axis=1)) print(f"{V[s][0]} {pi[s][0]}") return V, pi
def ILP(env: Environment, **kwargs): # Initialize decision variables. esm = [(e, s, m) for e in env.edges for s in env.services for m in env.models_for_service(s)] um = [(u, m) for u in env.requests for m in env.models_for_request(u)] x = pulp.LpVariable.dicts("placement", esm, cat=pulp.LpBinary) y = pulp.LpVariable.dicts("scheduling", um, cat=pulp.LpBinary) # Initialize the model and the objective function. model = pulp.LpProblem("PIES", pulp.LpMaximize) model += pulp.lpSum(y[u, m] * QoS_coeff(u, env.req_service(u), m, env) for u in env.requests for m in env.models_for_request(u)) # Constraint 1: Service model constraing; user `u` can be served by, at most, 1 model. for u in env.requests: s = env.req_service(u) model += pulp.lpSum(y[u, m] for m in env.models_for_request(u)) <= 1 # Constraint 2: Storage resource capacity constraint. for e in env.edges: model += pulp.lpSum( x[e, s, m] * env.storage_cost(s, m) for s in env.services for m in env.models_for_service(s)) <= env.storage_capacity(e) # Constraint 3: Ensures no user is served by an edge without a model for its service. for u in env.requests: e = env.covering_edge(u) s = env.req_service(u) for m in env.models_for_request(u): model += y[u, m] <= x[e, s, m] solver = pulp.PULP_CBC_CMD(**kwargs) model.solve(solver) return x, y
def solve(self): status = self.prob.solve(pl.PULP_CBC_CMD(msg=0)) foods_df = self.food_table.df foods_df['amount'] = foods_df.apply( lambda food: pl.value(food['amount_var']), axis=1) included = foods_df[foods_df['amount'] > 0] self.recipe = included[['amount']].copy()
def solve_problem(obj, tolerance=0.01, threads=1, timeLimit=120): material_model = pulp.LpProblem("MaterialProductionModel", pulp.LpMinimize) # Create Equality Constraints that produce the Price and Volume as independent variables. price_coefficients = [(mineral, obj.price_per_ore[mineral]) for mineral in obj.variable_ore_dict.values()] price_coefficients.append((obj.price, -1)) price_constraint = pulp.LpConstraint( pulp.LpAffineExpression(price_coefficients), sense=pulp.LpConstraintEQ, name='PriceConstraint', rhs=0) volume_coefficients = [(mineral, obj.volume_per_ore[mineral]) for mineral in obj.variable_ore_dict.values()] volume_coefficients.append((obj.volume, -1)) volume_constraint = pulp.LpConstraint( pulp.LpAffineExpression(volume_coefficients), sense=pulp.LpConstraintEQ, name='VolumeConstraint', rhs=0) material_model += price_constraint material_model += volume_constraint # Create Cost Function in terms of variables # I'll be lazy for now and just minimize price in ISK. material_model += (obj.weight_of_price * obj.price + obj.weight_of_volume * obj.volume) # Now go through the required materials and impose constraints that ensure we produce the right amount of stuff for material, amount in obj.required_materials.items(): production_expr = pulp.LpAffineExpression( obj.yield_per_mineral[material].items()) production_constraint = pulp.LpConstraint( production_expr, sense=pulp.LpConstraintGE, name='Produce{}'.format(material), rhs=amount) # Add Constraint to Model material_model += production_constraint solver = pulp.PULP_CBC_CMD(timeLimit=timeLimit, gapRel=tolerance, threads=threads) print(material_model) material_model.solve(solver) # The status of the solution is printed to the screen print("Status:", pulp.LpStatus[material_model.status]) result = dict() for v in material_model.variables(): result[v.name] = v.varValue return result
def _resoud_pulp(nom: str, var: List[variable], coeff: coeff, mb1: coeff, mb2: coeff, maxi: bool, sup: bool) -> Union[prob, float]: """Résoud les programmes primal et dual avec 'pulp', pour des lots non fractionnables""" if maxi == True: prob = pp.LpProblem(nom, pp.LpMaximize) elif maxi == False: prob = pp.LpProblem(nom, pp.LpMinimize) b = 0 for i, j in zip(mb1, var): a = i * j b = b + a prob.setObjective(b) for k, d in zip(coeff, mb2): b = 0 for i, j in zip(k, var): a = i * j b = b + a if sup == False: prob.addConstraint(b <= d) elif sup == True: prob.addConstraint(b >= d) prob.solve(pp.PULP_CBC_CMD(msg=0)) results = list() for var in prob.variables(): results.append(var.value()) obj = prob.objective.value() return prob, results, obj
def construct_distribution(self, map, epsilon, spanner, prior): delta = spanner.delta variables = [[ pulp.LpVariable(str(id_in) + "_" + str(id), 0, 1, 'Continuous') for id in map.ids ] for id_in in map.ids] problem = pulp.LpProblem('optGeoI', pulp.LpMinimize) problem += pulp.lpSum(variables * prior * list(map.euclidean_distances.values())) for i in map.ids: problem += pulp.lpSum(variables[i]) == 1.0 for variables_ in variables: for variable in variables_: problem += variable >= 0 for edge in spanner.graph.edges: #for edge in itertools.combinations(map.ids, 2): for id in map.ids: problem += variables[edge[0]][id] <= np.exp( epsilon * map.euclidean_distances[edge[0]][edge[1]] / delta) * variables[edge[1]][id] problem += variables[edge[1]][id] <= np.exp( epsilon * map.euclidean_distances[edge[0]][edge[1]] / delta) * variables[edge[0]][id] status = problem.solve(pulp.PULP_CBC_CMD(msg=0)) f = np.frompyfunc(lambda x: x.value(), 1, 1) return f(variables).astype(np.float64)
def LPsolver(MDP): LPproblem = pulp.LpProblem("V*", pulp.LpMinimize) states = range(0, MDP["S"]) V = np.zeros(MDP["S"], dtype=np.float128) Q = np.zeros((MDP["S"], MDP["A"]), dtype=np.float128) state_variables = pulp.LpVariable.dicts('vpi', states, cat='Continuous') LPproblem += pulp.lpSum([state_variables[s] for s in states]) for s in range(0, MDP["S"]): for a in range(0, MDP["A"]): LPproblem += state_variables[s] >= pulp.lpSum( (MDP["T"][s, a, s_dash] * (MDP["R"][s, a, s_dash] + MDP["gamma"] * state_variables[s_dash])) for s_dash in range(0, MDP["S"])) status = pulp.PULP_CBC_CMD(msg=0, gapRel=1e-10).solve(LPproblem) for x in range(0, MDP["S"]): V[x] = pulp.value(state_variables[x]) action_list = MDP["gamma"] * (np.multiply( V, MDP["T"])).sum(axis=2) + np.multiply(MDP["R"], MDP["T"]).sum(axis=2) Pi_optimal = np.argmax(action_list, axis=1) for s in range(0, MDP["S"]): print(str(format(V[s], '.6f')) + ' ' + str(Pi_optimal[s])) return Pi_optimal
def _compute_inference_function(self, mechanism, map, prior): remapping = [[ pulp.LpVariable((str(perturbed_node) + "_" + str(inf_node)), 0, 1, 'Continuous') for inf_node in map.ids ] for perturbed_node in map.ids] problem = pulp.LpProblem('AE', pulp.LpMinimize) prior_distribution = prior * mechanism.distribution if self.euclid: problem += pulp.lpSum(remapping * np.dot( prior_distribution.T, list(map.euclidean_distances.values()))) else: problem += pulp.lpSum( remapping * np.dot(prior_distribution.T, list(map.shortest_path_distances.values()))) for i in range(len(map.ids)): problem += pulp.lpSum(remapping[i]) == 1.0 status = problem.solve(pulp.PULP_CBC_CMD(msg=1)) if (status): f = np.frompyfunc(lambda x: x.value(), 1, 1) else: print("error") return f(remapping)
def do( # pylint: disable=invalid-name problem: Problem, debug: bool = False) -> Solution: # Define optimization variables # - number_of_de - number of devops in specific datacenter # - dm_to_datacenter - assign DevOps manager to specific datacenter number_of_de = {} dm_to_datacenter = {} for datacenter in problem.datacenters: number_of_de[datacenter.name] = pulp.LpVariable( f"number_of_de_{datacenter.name}", cat=pulp.LpInteger, lowBound=0) dm_to_datacenter[datacenter.name] = pulp.LpVariable( f"dm_to_{datacenter.name}", cat=pulp.LpBinary) # We want to solve optimization problem # to find mininum devops across all datacenters model = pulp.LpProblem('DevOps Assignment', pulp.LpMinimize) model += sum(var for var in number_of_de.values()) # Set constraints for the problem # Each server must have maintenance available at all times. # So we have to have equal or greater number of DevOps for all datacenters for datacenter in problem.datacenters: model += (problem.dm_capacity * dm_to_datacenter[datacenter.name] + (problem.de_capacity * number_of_de[datacenter.name]) >= datacenter.servers) # DevOps Manager has to be only one model += (sum([ dm_to_datacenter[datacenter.name] for datacenter in problem.datacenters ]) == 1) solver = pulp.PULP_CBC_CMD(msg=1 if debug else 0) status = model.solve(solver) if debug: model.writeLP('model.lp') print(pulp.LpStatus[status]) for var in number_of_de.values(): print(var.name, var.value()) for var in dm_to_datacenter.values(): print(var.name, var.value()) # If we could not find optimal solution # return empty Solution if not status == pulp.LpStatusOptimal: return Solution() return Solution( de=sum( int(var.value()) for var in number_of_de.values() if var.value() > 0), dm_datacenter=[ name for name, var in dm_to_datacenter.items() if var.value() == 1 ][0], status=status, )
def _optimize(now, forecast, parameters={}): """Solve an optimization problem defined by `get_pulp_function` :param forecast: forecasts over the optimization window :type forecast: list[dict] :param parameters: component parameters :type parameters: dict[dict] :rtype: dict :returns: optimized value of each variable in the problem """ prob = pulp_build_function(forecast, parameters) if write_lp: base_file = os.path.join(lp_out_dir, str(now).replace(":", "_")) prob.writeLP(base_file + ".lp") with open(base_file + ".forecast", "w") as f: f.write(pformat(forecast) + "\n") with open(base_file + ".parameters", "w") as f: f.write(pformat(parameters) + "\n") solve_start = time.time() try: if use_glpk: glpk_options = [] if time_limit is not None: glpk_options = ["--tmlim", str(time_limit)] prob.solve(pulp.GLPK_CMD(options=glpk_options, msg=False)) else: prob.solve(pulp.PULP_CBC_CMD(timeLimit=time_limit, msg=False)) except Exception as e: LOG.warning("PuLP failed: " + str(e)) convergence_time = -1 objective_value = -1 else: # PuLP's solutionTime appears to return machine time, not wall # time, but the time limit is defined on wall time. # Could use `convergence_time = prob.solutionTime` instead. convergence_time = time.time() - solve_start objective_value = pulp.value(prob.objective) status = pulp.LpStatus[prob.status] # build dict of problem variables result = {} for var in prob.variables(): result[var.name] = var.varValue # add solution meta-data result["Optimization Status"] = status result["Objective Value"] = objective_value result["Convergence Time"] = convergence_time if write_lp: with open(base_file + ".result", "w") as f: f.write("Status: {}\n".format(status)) f.write("Objective Value: {}\n".format(objective_value)) f.write("Convergence Time: {}\n\n".format(convergence_time)) f.write(pformat(result) + "\n") return result
def closest_to_origin_cascade_v2(cls, g): k = g.k l = g.l id1, id2 = g.comps_to_merge[0], g.comps_to_merge[1] Lp_prob = p.LpProblem('cascade', p.LpMaximize) belonging_array, sizes, comp_sizes, id_array, index1, index2 = g.belonging_array_v2( id1, id2) m = len(sizes) # creating the variables xs = [ p.LpVariable("x{0}_{1}".format(i, j), cat="Binary") for i in range(m) for j in range(l) ] xs = np.array(xs) xs = xs.reshape((m, l)) # minimize objective objective = p.lpSum( [sizes[i, j] * xs[i, j] for i in range(m) for j in range(l)]) Lp_prob += objective # conditions # conditions for respecting the sizes of components for i in range(l): Lp_prob += p.lpSum([comp_sizes[j] * xs[j, i]] for j in range(m)) == k # conditions to make sure that any component is in one cluster at the time for i in range(m): Lp_prob += p.lpSum([xs[i, j]] for j in range(l)) == 1 # condition to make sure that the two components that must merge will be in the same cluster for i in range(l): Lp_prob += xs[index1, i] == xs[index2, i] # condition on the cost of the cascade Lp_prob += p.lpSum([comp_sizes[i] * xs[i, j] * belonging_array[i, j]] for i in range(m) for j in range(l)) <= l * k * np.log(k) # solving the problem p.PULP_CBC_CMD(msg=0).solve(Lp_prob) # Communicating the results to create a new graph if Lp_prob.sol_status != 1: return Lp_prob.sol_status, None else: exchange_list = [] for i in range(len(belonging_array)): for j in range(len(belonging_array[i])): if belonging_array[i][j] == 0: tmp = [j, id_array[i][j]] break for k in range(len(xs[i])): if xs[i][k].varValue == 1 and k != j: tmp.insert(1, k) exchange_list.append(tmp) cc = cascade_changes.Cascade_Changes(id1, id2, exchange_list) return Lp_prob.sol_status, cc
def solver(name: str): size = len(name) # 問題の定義 prob = pulp.LpProblem('tsp', sense=pulp.LpMaximize) # 変数の生成 xs = [] for i in range(size): x = [pulp.LpVariable('x{}_{}'.format(i, j), cat='Binary') for j in range(size)] xs.append(x) # 部分順回路排除用 u = pulp.LpVariable.dicts('u', (i for i in range(size)), lowBound=1, upBound=size, cat='Integer') # スコア生成用の定数配列の生成 cs = [] for i in range(size): cs.append([]) for j in range(size): if name[i] in vowels or name[j] in vowels: cs[i].append(1) else: cs[i].append(0) # 目的関数 prob += pulp.lpSum([pulp.lpDot(c, x) for c, x in zip(cs, xs)]) # 制約条件 # 各文字への行きと帰りはそれぞれ一度しか選ばれない for i in range(size): prob += pulp.lpSum([xs[j][i] for j in range(size)]) <= 1 prob += pulp.lpSum([xs[i][j] for j in range(size)]) <= 1 # n文字(n-1回の連結) prob += pulp.lpSum([pulp.lpSum([x2 for x2 in x1]) for x1 in xs]) == size - 1 # おなじ文字には行かない for i in range(size): prob += xs[i][i] == 0 # 部分順回路排除用 # @see: http://www.ie110704.net/2020/08/15/pulp%E3%81%A7%E6%95%B0%E7%90%86%E6%9C%80%E9%81%A9%E5%8C%96%E5%95%8F%E9%A1%8C%EF%BC%88tsp%E3%80%81vrp%EF%BC%89/ for i in range(size): for j in range(size): if i != j: # ハミルトン閉路ではi,j == 0のとき制約を追加しない prob += u[i] - u[j] <= (1 - xs[i][j]) * size - 1 # 行きか帰りに一度は選ばれる for i in range(size): prob += pulp.lpSum([xs[i][j] for j in range(size)]) + pulp.lpSum([xs[j][i] for j in range(size)]) >= 1 pulp.PULP_CBC_CMD(msg=0, timeLimit=1, options = ['maxsol 1']).solve(prob) xs = [[round(x2.value()) for x2 in x1] for x1 in xs] if prob.status != 1: print(prob.status, pulp.LpStatus[prob.status]) # print("score:", prob.objective.value()) # pprint(xs) # pprint([u1 for u1 in u]) result = target_name(xs, name) return (result, prob.objective.value())
def solve(self,msg=0,**kwarg): # kind = 'CBC' if 'kind' in kwarg: kind = kwarg['kind'] time_limit = None if 'time_limit' in kwarg: time_limit = float(kwarg['time_limit']) random_seed = None if 'random_seed' in kwarg: random_seed = kwarg['random_seed'] ratio_gap = None if 'ratio_gap' in kwarg: ratio_gap = float(kwarg['ratio_gap']) start_time = time.time() # select solver for pl if kind == 'CPLEX': if time_limit is not None: # pulp does currently not support a timelimit in 1.5.9 self.mip.solve(pl.CPLEX_CMD(msg=msg, timelimit=time_limit)) else: self.mip.solve(pl.CPLEX_CMD(msg=msg)) elif kind == 'GLPK': self.mip.solve(pl.GLPK_CMD(msg=msg)) elif kind == 'SCIP': self.mip.solve(SCIP_CMD(msg=msg,time_limit=time_limit,ratio_gap=ratio_gap)) elif kind == 'CBC' or kind == 'COIN': options = [] if time_limit is not None: options.extend(['sec', str(time_limit)]) if random_seed is not None: options.extend(['randomSeed', str(random_seed)]) options.extend(['randomCbcSeed', str(random_seed)]) if ratio_gap is not None: options.extend(['ratio', str(ratio_gap)]) if kind == 'CBC': self.mip.solve(pl.PULP_CBC_CMD(msg=msg, options=options)) elif kind == 'COIN': self.mip.solve(pl.COIN(msg=msg, options=options)) elif kind == 'GUROBI': # GUROBI_CMD does not support a timelimit or epgap # GUROBI cannot dispatch parameters from options correctly options=[] if time_limit is not None: if ratio_gap is not None: self.mip.solve(pl.GUROBI(msg=msg,timeLimit=time_limit,epgap=ratio_gap)) elif time_limit is not None: self.mip.solve(pl.GUROBI(msg=msg, timeLimit=time_limit)) elif ratio_gap is not None: self.mip.solve(pl.GUROBI(msg=msg, epgap=ratio_gap)) else: self.mip.solve(pl.GUROBI_CMD(msg=msg)) else: raise Exception('ERROR: solver ' + kind + ' not known') if msg: print('INFO: execution time for solving mip (sec) = ' + str(time.time() - start_time)) if self.mip.status == 1 and msg: print('INFO: objective = ' + str(pl.value(self.mip.objective)))
def _solve(self, relax: bool, time_limit: Optional[int]): # Set variable types if not relax: # Set partitioning constraints and artificial variables to integer # (for the periodic case) for node in self.G.nodes(): if (node not in ["Source", "Sink"] and "depot_from" not in self.G.nodes[node] and "depot_to" not in self.G.nodes[node]): for const in self.prob.constraints: # Modify the self.prob object (the # self.set_covering_constrs object cannot be modified # (?)) if "visit_node" in const: self.prob.constraints[ const].sense = pulp.LpConstraintEQ if (self.periodic and self.G.nodes[node]["frequency"] > 1 and node != "Source"): self.dummy[node].cat = pulp.LpInteger # Set route variables to integer for var in self.y.values(): # Disallow routes that visit multiple nodes if "non" in var.name: var.upBound = 0 var.lowBound = 0 var.cat = pulp.LpInteger # Force vehicle bound artificial variable to 0 for var in self.dummy_bound.values(): if "artificial_bound_" in var.name: var.upBound = 0 var.lowBound = 0 # Solve with appropriate solver if self.solver == "cbc": self.prob.solve( pulp.PULP_CBC_CMD( msg=False, timeLimit=time_limit, options=["startalg", "barrier", "crossover", "0"], )) elif self.solver == "cplex": self.prob.solve( pulp.CPLEX_CMD( msg=False, timeLimit=time_limit, # options=["set lpmethod 4", "set barrier crossover -1"], # set barrier crossover -1 is deprecated options=["set lpmethod 4", "set solutiontype 2"], )) elif self.solver == "gurobi": gurobi_options = [ ("Method", 2), # 2 = barrier ("Crossover", 0), ] # Only specify time limit if given (o.w. errors) if time_limit is not None: gurobi_options.append(( "TimeLimit", time_limit, )) self.prob.solve(pulp.GUROBI(msg=False, options=gurobi_options))
def optimize(): global model w = 7 model += plp.lpSum( get_sink_inflow()) - w * plp.lpSum(z()) #- v * plp.lpSum(y()) # Solves With a cut of of fracGap model.solve(plp.PULP_CBC_CMD(fracGap=0.1))