def solve(self) -> dict: """Method to solve for the optimal location of geometries given an input Geodataframe with a size column. :return: Dictionary that contains all the values for all S variables. """ logging.debug("method solve called") self.problem.solve( p.GLPK_CMD(msg=self.solve_msg, options=["--tmlim", f"{self.time_limit}"])) s_dict = {} for v in self.problem.variables(): var_name = v.name.split("_") if var_name[0] == "s": s, i, j = v.name.split("_") # print(v.varValue) if int(i) in s_dict: s_dict[int(i)][int(j)] = v.varValue >= 0.5 else: s_dict[int(i)] = {int(j): v.varValue >= 0.5} if len(var_name) == 2: # All variables with two parts in their name are coordinates. The first part says if it's a x or y # coordinate, the second part the geometry it corresponds to (row number in Geodataframe). c, i = v.name.split("_") self.gdf.at[int(i), f"_{c}"] = v.varValue return s_dict
def linearYRange(points, type): problem = pulp.LpProblem('range', type) x = pulp.LpVariable('x', cat='Continuous') y = pulp.LpVariable('y', cat='Continuous') # Objective function problem += y def buildLineEquation(index1, index2): a = -(points[index2][1] - points[index1][1]) b = points[index2][0] - points[index1][0] c = (a * points[index1][0]) + (b * points[index1][1]) # print '(', a, 'x+',b,'y >=',c,'),' return (a * x) + (b * y) >= c for i in range(1, len(points)): problem += buildLineEquation(i - 1, i) problem += buildLineEquation(len(points) - 1, 0) # print problem pulp.GLPK_CMD(msg=0).solve(problem) return y.value()
def solveChains(RGraph, QCA, configuration): ''' :param RGraph: :param QCA: :param paths: ''' global _QCA, _RGraph # Parse solver parameters parseConfiguration(configuration) # Parse routing structures _RGraph = RGraph _QCA = QCA fixed, shared, chains, chain_lengths, sharing = parseSystem() if sharing: prob, var_map = setupProblem(fixed, shared, chains, chain_lengths) if WRITE: prob.writeLP("SHARING.lp") prob.solve(solver=pulp.GLPK_CMD(msg=VERBOSE)) # read solution LpSolution = {} for v in prob.variables(): LpSolution[v.name] = v.varValue assignQubits(LpSolution, var_map)
def force_short_paths_from(mdp: MDP, s: int, T: List[int], l: int, b: float, msg=0, solver=pulp.GLPK_CMD()): """ Compute the maximum probability to reach a set of target states T from a state s of a MDP with a path length inferior than a threshold l and get the strategy on the unfolded mdp. :param mdp: a MDP. :param s: the state for which the probability to reach T is computed. :param T: a set of target states of the MDP. :param l: the paths length threshold. :param b: probability threshold. :param msg: (optional) set this parameter to 1 to activate the debug mode in the console. :param solver: (optional) a LP solver allowed in puLp (e.g., GLPK or CPLEX). :return: the unfolded MDP from s and the strategy that solve the reachability problem for the unfolded MDP from s. Note that the strategy uses the index of states of the unfolded MDP and not the (s, v) format. """ if not (0. <= b <= 1.): raise ValueError( "alpha must be a probability threshold, i.e., 0 <= alpha <= 1 (current value : %g)." % alpha) # First, we must define a mdp that record the length of the paths during an execution of the mdp from s u_mdp = UnfoldedMDP(mdp, s, T, l) strategy = solvers.reachability.build_strategy(u_mdp, u_mdp.target_states, msg=msg, solver=solver) if solvers.reachability.v[0] >= b: return u_mdp, strategy else: return u_mdp, None
def build_strategy(mdp: MDP, T: List[int], solver: pulp = pulp.GLPK_CMD(), msg=0) -> Callable[[int], int]: """ Build a memoryless strategy that returns, following a state s of the MDP, the action that minimize the expected length of paths to a set of target states T. :param mdp: a MDP for which the strategy will be built. :param T: a target states list. :param solver: (optional) a LP solver allowed in puLp (e.g., GLPK or CPLEX). :return: the strategy built. """ x = min_expected_cost(mdp, T, solver=solver, msg=msg) global v v = x states = range(mdp.number_of_states) act_min = [ mdp.act(s)[argmin([ mdp.w(alpha) + sum(map(lambda succ_pr: succ_pr[1] * x[succ_pr[0]], succ_list)) for (alpha, succ_list) in mdp.alpha_successors(s) ])] for s in states ] return lambda s: act_min[s]
def reach(mdp: MDP, T: List[int], msg=0, solver: pulp = pulp.GLPK_CMD()) -> List[float]: """ Compute the maximum reachability probability to T for each state of the MDP in parameter and get a vector x (as list) such that x[s] is the maximum reachability probability to T of the state s. :param mdp: a MDP for which the maximum reachability probability will be computed for each of its states. :param T: a list of target states. :param msg: (optional) set this parameter to 1 to activate the debug mode in the console. :param solver: (optional) a LP solver allowed in puLp (e.g., GLPK or CPLEX). :return: the a list x such that x[s] is the maximum reachability probability to T. """ states = list(range(mdp.number_of_states)) # x[s] is the Pr^max to reach T x = [-1] * mdp.number_of_states connected = connected_to(mdp, T) # find all states s such that s is not connected to T for s in filter(lambda s: not connected[s], states): x[s] = 0 # find all states s such that Pr^max to reach T is 1 for s in pr_max_1(mdp, T, connected=connected): x[s] = 1 # if there exist some other states such that Pr^max to reach T is in ]0, 1[, a LP is generated for these states untreated_states = list(filter(lambda s: x[s] == -1, states)) if untreated_states: # formulate the LP problem linear_program = pulp.LpProblem("reachability", pulp.LpMinimize) # initialize variables for s in untreated_states: x[s] = pulp.LpVariable(mdp.state_name(s), lowBound=0, upBound=1) # objective function linear_program += sum(x) # constraints for s in untreated_states: for (alpha, successors_list) in mdp.alpha_successors(s): linear_program += x[s] >= sum( pr * x[succ] for (succ, pr) in successors_list) if msg: print(linear_program) # solve the LP solver.msg = msg linear_program.solve(solver) for s in untreated_states: x[s] = x[s].varValue if msg: print_optimal_solution(x, states, mdp.state_name) global v v = x return x
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 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 min_expected_cost(mdp: MDP, T: List[int], msg=0, solver: pulp = pulp.GLPK_CMD()) -> List[float]: """ Compute the minimum expected length of paths to the set of targets T from each state in the MDP. :param mdp: a MDP. :param T: a list of target states of the MDP. :param msg: (optional) set this parameter to 1 to activate the debug mode in the console. :param solver: (optional) a LP solver allowed in puLp (e.g., GLPK or CPLEX). :return: a list x such that x[s] is the mimum expected length of paths to the set of targets T from the state s of the MDP. """ states = range(mdp.number_of_states) x = [float('inf')] * mdp.number_of_states expect_inf = [True] * mdp.number_of_states # determine states for which x[s] != inf for s in pr_max_1(mdp, T): x[s] = -1 expect_inf[s] = False for t in T: x[t] = 0 # formulate the LP problem linear_program = pulp.LpProblem( "minimum expected length of path to target", pulp.LpMaximize) # initialize variables for s in filter(lambda s: x[s] == -1, states): x[s] = pulp.LpVariable(mdp.state_name(s), lowBound=0) # objective function linear_program += sum( map(lambda s: x[s], filter(lambda s: not expect_inf[s], states))) # constraints for s in filter(lambda s: x[s] == -1, states): for (alpha, successor_list) in mdp.alpha_successors(s): if not list( filter(lambda succ_pr: expect_inf[succ_pr[0]], successor_list)): linear_program += x[s] <= mdp.w(alpha) + sum( map(lambda succ_pr: succ_pr[1] * x[succ_pr[0]], successor_list)) if msg: print(linear_program) # solve the LP solver.msg = msg if linear_program.variables(): linear_program.solve(solver) for s in states: if x[s] != 0 and x[s] != float('inf'): x[s] = x[s].varValue if msg: print_optimal_solution(x, states, mdp.state_name) return x
def possible_cascade(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.LpMinimize) belonging_array, sizes, id_array, index1, index2 = g.belonging_array( 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] * xs[i, j] * belonging_array[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([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 compnents that must merge will be in the same cluster for i in range(l): Lp_prob += xs[index1, i] == xs[index2, i] # solving the problem #path_to_solver = r'C:\gurobi902\win64\bin\grb_ts.exe' # solver = p.PULP_CBC_CMD( msg=0) solver = p.GLPK_CMD(msg=0) # solver = p.GUROBI_CMD(msg=0) Lp_prob.solve(solver) # Comunicating 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 __init__(self, S, fluxes, dG0_r_prime, cids, dG0_r_std=None, concentration_bounds=None): """Create a pathway object. Args: S: Stoichiometric matrix of the pathway. Reactions are on the rows, compounds on the columns. fluxes: the list of relative fluxes through each of the reactions. By default, all fluxes are 1. dG0_r_prime: the change in Gibbs energy for the reactions in standard conditions, corrected for pH, ionic strength, etc. Should be a column vector in np.matrix format. dG0_r_std: (optional) the square root of the covariance matrix corresponding to the uncertainty in the dG0_r values. concentration_bounds: a bounds.Bounds object expressing bounds on the metabolite concentrations. """ self.pulp_solver = pulp.GLPK_CMD(msg=0, options=['--xcheck']) self.S = S self.Nc, self.Nr = S.shape self.dG0_r_prime = dG0_r_prime if dG0_r_std is None: self.dG0_r_std = np.matrix(np.zeros((self.Nr, self.Nr))) else: self.dG0_r_std = dG0_r_std # Make sure dG0_r' is the right size assert self.dG0_r_prime.shape[0] == self.Nr assert self.dG0_r_std.shape[0] == self.Nr assert self.dG0_r_std.shape[1] == self.Nr self.fluxes = fluxes if self.fluxes is None: self.fluxes = np.ones((1, self.Nr)) self.fluxes = np.matrix(self.fluxes) assert self.fluxes.shape[ 1] == self.Nr, 'Fluxes required for all reactions' _signs = list(map(np.sign, self.fluxes.flat)) self.I_dir = np.matrix(np.diag(_signs)) self.Nr_active = int(sum(self.fluxes.T != 0)) self.cids = cids self.concentration_bounds = concentration_bounds if self.concentration_bounds is None: lb, ub = self.DEFAULT_C_RANGE self.concentration_bounds = Bounds(default_lb=lb, default_ub=ub) # Currently unused bounds on reaction dGs. self.r_bounds = None
def solve(self, path=None, verbosity=0): """ Solves the LP problem and returns the list of people chosen for sampling. :param path: str - path to the solver executable file :param verbosity: 0 - no messages, 1 - only python messages, 2 - python and solver messages :return: list of person chosen for sampling, or None if failed """ try: self.problem.solve(pl.GLPK_CMD(msg=verbosity > 1, path=path)) solver_crashed = False except: solver_crashed = True if not solver_crashed and self.problem.status == 1: sampled_person_lst = [] person_idx_to_x_value_dict = { person_id: pl.value(x) for person_id, x in sorted(self.x.items()) } for person_idx, x_value in sorted( person_idx_to_x_value_dict.items()): if self.integer_programming: sampled = x_value if verbosity > 0: print("person {} : {}".format(person_idx, pl.value(x_value))) else: # Requires randomized rounding sampled = np.random.binomial(1, pl.value(x_value)) if verbosity > 0: print( "person {:25} : {} randomly rounded to {} ".format( person_idx, x_value, sampled)) if sampled: sampled_person_lst.append(person_idx) # if the number of sampled people is different than B - add/remove people as required to reach exactly B: sampled_person_lst = self.refine_sampled_person_lst( sampled_person_lst, person_idx_to_x_value_dict, verbosity=verbosity) # Report the sampled people num_selected_people = len(sampled_person_lst) if verbosity > 0: print("Found a solution (z={}): People chosen for sampling". format(pl.value(self.z))) print(sampled_person_lst) print("-" * 72) print("The solution selected {} {} (B was set to {})".format( num_selected_people, "person" if num_selected_people == 1 else "people", self.B)) return sampled_person_lst else: if verbosity > 0: print("Failed solving the linear program of people selection") return None
def build_strategy(mdp: MDP, T: List[int], solver: pulp = pulp.GLPK_CMD(), msg=0) -> Callable[[int], int]: """ Build a memoryless strategy that returns the action that maximises the reachability probability to T of each state s in parameter of this strategy. :param mdp: a MDP for which the strategy will be built. :param T: a target states list. :param solver: (optional) a LP solver allowed in puLp (e.g., GLPK or CPLEX). :return: the strategy built. """ x = reach(mdp, T, solver=solver, msg=msg) states = range(mdp.number_of_states) act_max = [[] for _ in states] # update act_max for s in states: pr_max = 0 for (alpha, successor_list) in mdp.alpha_successors(s): pr = sum( map(lambda succ_pr: succ_pr[1] * x[succ_pr[0]], successor_list)) if pr == pr_max: act_max[s].append(alpha) elif pr > pr_max: pr_max = pr act_max[s] = [alpha] # compute M^max mdp_max = MDP([], [], mdp._w, mdp.number_of_states, validation=False) for s in states: i = 0 for (alpha, successor_list) in mdp.alpha_successors(s): if alpha == act_max[s][i]: i += 1 mdp_max.enable_action(s, alpha, successor_list) if i == len(act_max[s]): break # compute the final strategy minimal_steps = minimal_steps_number_to(mdp_max, T) strategy: List[int] = [] for s in states: if x[s] == 0 or minimal_steps[s] == 0: strategy.append(act_max[s][0]) else: for (alpha, successor_list) in mdp_max.alpha_successors(s): for (succ, pr) in successor_list: if minimal_steps[succ] == minimal_steps[s] - 1: strategy.append(alpha) break if len(strategy) == s + 1: break return lambda s: strategy[s]
def solve(self, tmlim): self.status = self.model.solve( pulp.GLPK_CMD(options=['--tmlim', str(tmlim)])) clusters = None if self.status == 1: clusters = [-1 for i in range(self.n)] for i in range(self.n): for j in range(self.k): if self.y[(i, j)].value() > 0: clusters[i] = j return clusters
def solve(self, solver="cbc", timeout=None): """Solves this problem and returns the problem result. :param solver: The solver that should be used. Currently supported are "cbc", "gurobi", "glpk" and "cplex", defaults to "cbc" :type solver: str, optional :return: Result. :rtype: solver.SolverResult """ assert solver in [ "gurobi", "cbc", "glpk", "cplex" ], "solver must be in ['gurobi','cbc','glpk','cplex']" if timeout != None: assert isinstance( timeout, int), "timeout must be specified in seconds as integer value" if solver == "gurobi": gurobi_options = [ ("MIPGap",0), ("MIPGapAbs",0), ("FeasibilityTol",1e-9),\ ("IntFeasTol",1e-9),("NumericFocus",3)] if timeout != None: gurobi_options.append(("TimeLimit", str(timeout))) self.__pulpmodel.setSolver(pulp.GUROBI_CMD(options=gurobi_options)) elif solver == "cbc": cbc_options = ["--integerT", "0"] self.__pulpmodel.setSolver( pulp.PULP_CBC_CMD(gapRel=1e-9, timeLimit=timeout, options=cbc_options)) elif solver == "glpk": glpk_options = ["--tmlim", str(timeout)] if timeout != None else [] self.__pulpmodel.setSolver(pulp.GLPK_CMD(options=glpk_options)) elif solver == "cplex": self.__pulpmodel.setSolver(pulp.CPLEX_PY(timeLimit=timeout)) self.__pulpmodel.solve() status = { 1: "optimal", 0: "notsolved", -1: "infeasible", -2: "unbounded", -3: "undefined" }[self.__pulpmodel.status] result_vector = np.array([var.value() for var in self.__variables]) dual_result_vector = np.array( [constr.pi for constr in self.__constraints]) value = self.__pulpmodel.objective.value() return SolverResult(status, result_vector, dual_result_vector, value)
def optimize(self): """ Default solver is 'cbc' unless solver is set to something else. You may need to provide a path for any of the solvers using 'path' argument. """ if model_params['write_lp']: logger.info('Writing the lp file!') self.model.writeLP(self.model.name + '.lp') logger.info('Optimization starts!') _solver = pulp.PULP_CBC_CMD(keepFiles=model_params['write_log'], fracGap=model_params['mip_gap'], maxSeconds=model_params['time_limit'], msg=model_params['display_log']) if model_params['solver'] == 'gurobi': _solver = pulp.GUROBI(msg=model_params['write_log'], timeLimit=model_params['time_limit'], epgap=model_params['mip_gap']) elif model_params['solver'] == 'cplex': options = [] if model_params['mip_gap']: set_mip_gap = "set mip tolerances mipgap {}".format( model_params['mip_gap']) options.append(set_mip_gap) _solver = pulp.CPLEX_CMD(keepFiles=model_params['write_log'], options=options, timelimit=model_params['time_limit'], msg=model_params['display_log']) elif model_params['solver'] == 'glpk': # Read more about glpk options: https://en.wikibooks.org/wiki/GLPK/Using_GLPSOL options = [] if model_params['mip_gap']: set_mip_gap = "--mipgap {}".format(model_params['mip_gap']) options.append(set_mip_gap) if model_params['time_limit']: set_time_limit = "--tmlim {}".format( model_params['time_limit']) options.append(set_time_limit) _solver = pulp.GLPK_CMD(keepFiles=model_params['write_log'], options=options, msg=model_params['display_log']) self.model.solve(solver=_solver) if self.model.status == pulp.LpStatusOptimal: logger.info('The solution is optimal and the objective value ' 'is ${:,.2f}'.format(pulp.value(self.model.objective)))
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 = 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 = 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 == 'CBC': 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)]) self.mip.solve(pl.PULP_CBC_CMD(msg=msg, options=options)) 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 oneCase(inputFile): [tx, ty] = map(int, inputFile.readline().split(' ')) status = 0 N = int(math.sqrt(abs(tx)) + math.sqrt(abs(ty))) - 1 while status != 1: N += 1 solver = pulp.LpProblem("problem", pulp.LpMinimize) sn = [ pulp.LpVariable("n" + str(i), 0, 1, cat=pulp.LpInteger) for i in range(N) ] ss = [ pulp.LpVariable("s" + str(i), 0, 1, cat=pulp.LpInteger) for i in range(N) ] se = [ pulp.LpVariable("e" + str(i), 0, 1, cat=pulp.LpInteger) for i in range(N) ] sw = [ pulp.LpVariable("w" + str(i), 0, 1, cat=pulp.LpInteger) for i in range(N) ] #h = [pulp.LpVariable("h_"+str(i),0, 1, cat=pulp.LpInteger) for i in range(N)] for i in xrange(N): solver += sn[i] + ss[i] + se[i] + sw[i] == 1 #if i!=0: solver += h[i] <= h[i-1] #solver += sum(h) solver += sum([(i + 1) * sn[i] - (i + 1) * ss[i] for i in xrange(N)]) == ty solver += sum([(i + 1) * se[i] - (i + 1) * sw[i] for i in xrange(N)]) == tx status = solver.solve(pulp.GLPK_CMD(msg=0)) r = "" for i in xrange(N): if pulp.value(sn[i]) >= 1: r += "N" if pulp.value(ss[i]) >= 1: r += "S" if pulp.value(se[i]) >= 1: r += "E" if pulp.value(sw[i]) >= 1: r += "W" return r
def _paths_to_chains(legal, paths, mapped, unassigned, opts): """ Using a Linear Programming formulation, map the unassigned target nodes, so that the maximum length chain in the embedding is minimized. Linear Programming formulation to solve unassigned nodes. Constraints for all edges: var<source><source><sink> + var<sink><source><sink> = |path| Constraints for all nodes: Z - All( var<node><source><sink> ) >= |<mapped['node']>| Goal: min(Z) """ if not legal: raise RuntimeError('Embedding is illegal.') if opts.verbose: print('Assigned') for node, fixed in mapped.items(): print(str(node) + str(fixed)) print('Unassigned') for node, shared in unassigned.items(): print(str(node) + str(shared)) lp, var_map = _setup_lp(paths, mapped, unassigned) if opts.verbose == 2: lp.writeLP("SHARING.lp") lp.solve(solver=pulp.GLPK_CMD(msg=opts.verbose)) # read solution lp_sol = {} for v in lp.variables(): lp_sol[v.name] = v.varValue _assign_nodes(paths, lp_sol, var_map, mapped) return mapped
def cargo_loading(blocks, params, solver='default'): a = pulp.LpVariable.dicts(name='cargo', indexs=blocks.to_dict().keys(), lowBound=0, upBound=1, cat=pulp.LpInteger) lp_problem = pulp.LpProblem('Cargo loading', pulp.LpMaximize) # Objective function added first lp_problem += sum([ block.mass * a[block.short_name] for block in blocks.blocks ]), "Total mass of cargo" # Constraints added next lp_problem += sum( [block.mass * a[block.short_name] for block in blocks.blocks] ) <= params['max_load'], "Total mass of cargo cannot exceed a maximum load" lp_problem += sum([ block.size * a[block.short_name] for block in blocks.blocks ]) <= params[ 'fuselage_length'], "Total size of cargo cannot exceed fuselage length" lp_problem.writeLP("CargoLoad.lp") if solver.lower() == 'glpk': lp_problem.solve(pulp.GLPK_CMD(msg=1)) elif solver.lower() == 'coin': lp_problem.solve(pulp.COIN_CMD(timeLimit=60)) else: lp_problem.solve(pulp.PULP_CBC_CMD(maxSeconds=60, msg=1, fracGap=0)) lp_prob_response = [{ 'status': pulp.LpStatus[lp_problem.status], 'cargo_mass': pulp.value(lp_problem.objective), 'fuselage_length': params['fuselage_length'], 'max_load': params['max_load'] }] variables_result = { f'{variable.name}': variable.varValue for variable in lp_problem.variables() } lp_prob_response.append(variables_result) return lp_prob_response
def optimize(self): """ Default solver is 'cbc' unless solver is set to something else. You may need to provide a path for any of the solvers using 'path' argument. """ _solver = None s_name = model_params['solver'] w_log = model_params['write_log'] disp_log = model_params['display_log'] mip_gap = model_params['mip_gap'] tl = model_params['time_limit'] if model_params['write_lp']: logger.info('Writing the lp file!') self.model.writeLP(self.model.name + '.lp') if not s_name or s_name == 'cbc': _solver = pulp.PULP_CBC_CMD(keepFiles=w_log, msg=disp_log, gapRel=mip_gap, timeLimit=tl) elif s_name == 'gurobi': # One can use GUROBI_CMD like CPLEX_CMD and pass mip_gap and time_limit as options _solver = pulp.GUROBI(msg=w_log, gapRel=mip_gap, timeLimit=tl) elif s_name == 'cplex': _solver = pulp.CPLEX_CMD(keepFiles=w_log, msg=disp_log, gapRel=mip_gap, timelimit=tl) elif s_name == 'glpk': # Read more about glpk options: https://en.wikibooks.org/wiki/GLPK/Using_GLPSOL options = [] if mip_gap: set_mip_gap = f'--mipgap {mip_gap}' options.append(set_mip_gap) _solver = pulp.GLPK_CMD(keepFiles=w_log, msg=disp_log, options=options, timeLimit=tl) elif s_name == 'xpress': _solver = pulp.XPRESS(keepFiles=w_log, msg=disp_log, gapRel=mip_gap, timeLimit=tl) logger.info('Optimization starts!') self.model.solve(solver=_solver) if self.model.status == pulp.LpStatusOptimal: logger.info(f'The solution is optimal and the objective value ' f'is ${self.model.objective.value():,.2f}')
def solve(self): ''' Model çözüm fonksiyonu, GLPK open-source solver'ı kullanır. :return: ''' self.status = self.model.solve(pulp.GLPK_CMD(options=['--tmlim', '480'],keepFiles=False)) solution_dict = {} if self.status == 1: for i in range(self.n_with_dummies): for j in range(self.n_with_dummies): for p in self.periods: if self.x[(i, j, p)].value(): solution_dict['x' + str((i, j, p))] = 1 for i in range(self.n_with_dummies): for p in self.periods: solution_dict['S' + str((i, p))] = self.S[(i,p)].value() for i in range(1,self.n + 1): for p in self.periods: if self.g[(i, p)].value(): solution_dict['g' + str((i,p))] = self.g[(i,p)].value() for p in self.periods: if self.extra[(p)].value(): solution_dict['extra' + str((p))] = self.extra[(p)].value() for p in self.periods: solution_dict['z' + str((p))] = self.z[(p)].value() for p in self.periods: if self.deficit[(p)].value(): solution_dict['def' + str((p))] = self.deficit[(p)].value() return solution_dict
import sys from Nfl import Nfl from Nhl import Nhl from Nba import Nba while True: print() if sys.argv[1].lower() == 'nfl': generator = Nfl( sport="NFL", num_lineups=150, overlap=int(sys.argv[4]), player_limit=int(sys.argv[5]), teams_limit=int(sys.argv[6]), stack=sys.argv[7], solver=pulp.GLPK_CMD(msg=0), correlation_file='nfl/inputs/{}/correlation.csv'.format( sys.argv[2]), players_file='nfl/inputs/{}/{}/players.csv'.format( sys.argv[2], sys.argv[3]), defenses_goalies_file='nfl/inputs/defense.csv', output_file= 'nfl/outputs/{}/output_{}_overlap_{}_playerlimit_{}_numteams_{}_stack_{}.csv' .format(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7])) if sys.argv[1].lower() == 'nhl': generator = Nhl( sport="NHL", num_lineups=150, overlap=int(sys.argv[4]), player_limit=int(sys.argv[5]),
fwd_id = rxn_id.replace('_reverse', '') x_dict[fwd_id] -= x_dict[rxn_id] x_dict.pop(rxn_id) return x_dict ############################################################################### bigg2kegg_df = get_metabolite_df() bigg2kegg_dict = bigg2kegg_df['KEGG ID'].to_dict() S = settings.get_stoichiometry_from_model(cobra_model) flux_dict = get_pfba_fluxes(cobra_model) #%% # construct the LP for NEST (network-embedded semi-thermodynamic analysis) pulp_solver = pulp.GLPK_CMD(msg=0, options=['--xcheck']) ln_conc = pulp.LpVariable.dicts('lnC', indexs=S.index, lowBound=-settings.M, upBound=settings.M, cat=pulp.LpContinuous) # keep only reactions that carry flux and are internal active_rxn = [x for x in flux_dict.keys() if x[0:3] != 'EX_'] active_rxn.remove(BM_RXN) active_rxn = [x for x in active_rxn if np.abs(flux_dict[x]) > settings.eps] S_int = S[active_rxn] # keep only metabolites that are not involved and active internal reaction S_int = S_int.loc[np.abs(S_int).sum(1) > 0, :]
def cargo_ordering(blocks, params, solver='default'): get_name = lambda cargo_string: cargo_string.rpartition('_')[0] get_position = lambda cargo_string: cargo_string.rpartition('_')[2] fuselage_length = int(params['fuselage_length']) b = pulp.LpVariable.dicts(name='cargo', indexs=(blocks.to_dict().keys(), range(fuselage_length)), lowBound=0, upBound=1, cat=pulp.LpInteger) lp_problem = pulp.LpProblem('Cargo ordering', pulp.LpMinimize) # Objective function added first lp_problem += pulp.lpSum([ b[block.short_name][j] * block.mass * (j - ((fuselage_length - 1) / 2)) * (1 - ((1 / 3) * (block.size - (1 / 2)) * (block.size - 1))) for block in blocks.blocks for j in range(fuselage_length) ]), "Total torque around centre of fuselage" # Constraints added next lp_problem += pulp.lpSum([ b[block.short_name][j] * block.mass * (j - ((fuselage_length - 1) / 2)) * (1 - ((1 / 3) * (block.size - (1 / 2)) * (block.size - 1))) for block in blocks.blocks for j in range(fuselage_length) ]) >= 0, "Torque must be greater than or equal to 0" for j in range(fuselage_length): lp_problem += pulp.lpSum( [ b[block.short_name][j] * (block.size - ((2 / 3) * (block.size - (1 / 2)) * (block.size - 1))) for block in blocks.blocks ] ) <= 1, f"Position {j} can only have one block, two half blocks or no blocks" for block in blocks.blocks: lp_problem += pulp.lpSum([ b[block.short_name][j] for j in range(fuselage_length) ]) == block.size + ( (2 / 3) * ((1 - block.size) * (2 - block.size)) ), f"Each block {block.short_name} is in exactly one place" for block in blocks.blocks: if block.size == 2: lp_problem += pulp.lpSum( [ b[block.short_name][j] * ((-1)**j) * j * (2 / 3) * (block.size - (1 / 2)) * (block.size - 1) for j in range(fuselage_length) ] ) <= 1, f"Difference in block {block.short_name} locations is less than or equal to 1" lp_problem += pulp.lpSum( [ b[block.short_name][j] * ((-1)**j) * j * (2 / 3) * (block.size - (1 / 2)) * (block.size - 1) for j in range(fuselage_length) ] ) >= -1, f"Difference in block {block.short_name} locations is greater than or equal to -1" lp_problem.writeLP("CargoOrder.lp") if solver.lower() == 'glpk': lp_problem.solve(pulp.GLPK_CMD(msg=1)) elif solver.lower() == 'coin': lp_problem.solve(pulp.COIN_CMD(timeLimit=60)) else: lp_problem.solve(pulp.PULP_CBC_CMD(maxSeconds=60, msg=1, fracGap=0)) variables_result = { f'{variable.name}': variable.varValue for variable in lp_problem.variables() } # using 'reversed' should ensure that we get the minimum position for each block cargo_positions = { f'{get_name(variable.name)}': int(get_position(variable.name)) for variable in reversed(lp_problem.variables()) if variable.varValue } lp_prob_response = [{ 'status': pulp.LpStatus[lp_problem.status], 'turning_effect': pulp.value(lp_problem.objective), 'fuselage_length': params['fuselage_length'], 'max_load': params['max_load'] }] lp_prob_response.append(cargo_positions) lp_prob_response.append(variables_result) return lp_prob_response
def solveLP(prob_dict, verbose): '''Solve the optimation problem using either Mixed Integer Programming or LP-Relaxation''' K = len(prob_dict['keys']) N = prob_dict['node_lens'] M = prob_dict['chain_lens'] end_lists = prob_dict['end_lists'] # initialize LP solver prob = pulp.LpProblem('LP-prob', sense=pulp.LpMinimize) ### set up problem ## parameter dicts for LpVariable generation if USE_LPR: par_dict = {'lowBound': 0, 'upBound': None, 'cat': pulp.LpContinuous} else: par_dict = {'lowBound': 0, 'upBound': None, 'cat': pulp.LpInteger} mu_dict = {'lowBound': 0, 'upBound': None, 'cat': pulp.LpContinuous} # variable to be optimized n = [pulp.LpVariable('n%d' % i, **par_dict) for i in xrange(K)] # starts m = [pulp.LpVariable('m%d' % i, **par_dict) for i in xrange(K)] # end mu = pulp.LpVariable('mu', **mu_dict) # max model size ## objective function prob += mu ## constraints # end group sizes for node in end_lists: ns = map(lambda x: n[x], end_lists[node]['n']) ms = map(lambda x: m[x], end_lists[node]['m']) prob += pulp.lpSum(ns) + pulp.lpSum(ms) + 1 <= mu # average chain sizes for i in prob_dict['ind_nodes']: prob += M[i] - n[i] - m[i] <= mu*N[i] prob += n[i] + m[i] <= M[i] - N[i] # chain without internal nodes must have n+m==M for i in prob_dict['ind_none']: prob += n[i] + m[i] == M[i] # write lp file and solve try: prob.writeLP(LP_FILE) fn = LP_FILE except: print 'Invalid LP filename' prob.writeLP('./lp-sol.lp') fn = './lp-sol.lp' if verbose: print 'Saved to file: %s' % fn print '\n\n' if USE_DEFAULT: status = prob.solve() else: status = prob.solve(solver=pulp.GLPK_CMD()) print '\n\n' # check solution status if verbose: print(pulp.LpStatus[status]) # store solution values sol = {} sol['n'] = map(lambda v: pulp.value(v), n) sol['m'] = map(lambda v: pulp.value(v), m) sol['mu'] = pulp.value(mu) # for consistency check # delete solution file if DEL_LP_FILE: if verbose: print 'Deleting file: %s' % fn os.remove(fn) if verbose: print sol['m'] print sol['n'] models = solToModels(sol, prob_dict) if verbose: for cell in models: print 'c: %s \t :: %s' % (str(cell), str(models[cell]['qbits'])) return models, sol['mu']