def K_dominance_check(self, _V_best_d, Q_d): """ :param _V_best_d: a list of d-dimension :param Q_d: a list of d-dimension :return: True if _V_best_d is prefered to Q_d regarding self.Lambda_inequalities and using Kdominance other wise it returns False """ _d = len(_V_best_d) prob = LpProblem("Ldominance", LpMinimize) lambda_variables = LpVariable.dicts("l", range(_d), 0) for inequ in self.Lambda_ineqalities: prob += lpSum([inequ[j + 1] * lambda_variables[j] for j in range(0, _d)]) + inequ[0] >= 0 prob += lpSum([lambda_variables[i] * (_V_best_d[i]-Q_d[i]) for i in range(_d)]) #prob.writeLP("show-Ldominance.lp") status = prob.solve() LpStatus[status] result = value(prob.objective) if result < 0: return False return True
def get_optimal_allocations(domain, criterion, batch_size, method): candidates = get_candidates(domain, criterion, method, limit=1000) n = len(candidates) ilp_vars = [pulp.LpVariable('x%s' % x, 0, batch_size, pulp.LpInteger) \ for x in range(n)] prices = [candidates[i]['price'] for i in range(n)] confs = [candidates[i]['conf'] for i in range(n)] dists = [candidates[i]['dist'] for i in range(n)] histo = get_availability_histo(domain) ilp = None if method == 'min_price': ilp = pulp.LpProblem('minprice', pulp.LpMinimize) ilp += pulp.lpDot(prices, ilp_vars) ilp += pulp.lpDot(confs, ilp_vars) >= decimal.Decimal(batch_size * criterion) elif method == 'max_conf': ilp = pulp.LpProblem('maxconf', pulp.LpMaximize) ilp += pulp.lpDot(confs, ilp_vars) ilp += pulp.lpDot(prices, ilp_vars) <= decimal.Decimal(criterion) ilp += pulp.lpSum(ilp_vars) == batch_size for level in histo: ilp += pulp.lpDot([dists[i][level - 1] for i in range(n)], \ ilp_vars) <= histo[level] status = ilp.solve(pulp.GLPK(msg=0)) allocs = [] if pulp.LpStatus[status] == 'Optimal': for i in range(n): x = ilp_vars[i] if pulp.value(x) > 0: allocs.append((pulp.value(x), candidates[i])) return allocs
def FindMDF(self): """ Find the MDF (Optimized Bottleneck Driving-Force) Returns: A pair of the resulting MDF (in units of RT) and a dictionary of all the parameters and the resulting MDF value """ lp_primal, lnC = self._MakeMDFProblem() lp_primal.solve(pulp.CPLEX(msg=0)) lp_primal.writeLP('/tmp/mdf.lp') if lp_primal.status != pulp.LpStatusOptimal: raise pulp.solvers.PulpSolverError("cannot solve MDF primal") mdf = pulp.value(lnC[-1]) lnC = np.matrix(map(pulp.value, lnC[0:self.Nc])).T lp_dual, w, z, u = self._MakeMDFProblemDual() lp_dual.solve(pulp.CPLEX(msg=0)) if lp_dual.status != pulp.LpStatusOptimal: raise pulp.solvers.PulpSolverError("cannot solve MDF dual") reaction_prices = np.matrix([pulp.value(w["%d" % i]) for i in xrange(self.Nr)]).T compound_prices = np.matrix([pulp.value(z["%d" % j]) for j in xrange(self.Nc)]).T - \ np.matrix([pulp.value(u["%d" % j]) for j in xrange(self.Nc)]).T params = {'MDF': mdf, 'ln concentrations' : lnC, 'reaction prices' : reaction_prices, 'compound prices' : compound_prices} return mdf, params
def knapsack(self, f, d, b, quantities): """ max z: f1X1 + ... + frXr d1X1 + ... + frXr <= b X1 .. Xr >=0, integer @param f, list of parameters to be maximized @param d, list of objective parameters @param b, int boundary of the objective @return (x, z) x list of values z, the maximized value """ problem = pulp.LpProblem("Knapsakc", pulp.LpMaximize) nrCols = len(f) x = [] for r in range(nrCols): # Create variables Xi, int, >=0 x.append(pulp.LpVariable("x%d"%r , 0, quantities[r], pulp.LpInteger)) problem += sum( d[r] * x[r] for r in range(nrCols)) <= b problem += sum( f[r] * x[r] for r in range(nrCols)) #status = problem.solve(pulp.GLPK(msg = 0)) #problem.writeLP("/tmp/knapsack.lp") status = problem.solve() if self.LOG: print problem return ([pulp.value(a) for a in x], pulp.value(problem.objective))
def solveProblemWithRestr(weigthLimit): prob = pulp.LpProblem("myProblem", pulp.LpMaximize) # Only one of each piece prob += sum([a.var for a in arms]) <= 1.0 prob += sum([a.var for a in chests]) <= 1.0 prob += sum([a.var for a in heads]) <= 1.0 prob += sum([a.var for a in legs]) <= 1.0 # Maximum Weigth restr = sum(getRestr(armors)) prob += restr <= weigthLimit obj = sum(getObj(armors)) prob += obj status = prob.solve() print("| Name | Armor Rating | Weigth |") print("|:-----|------:|------:|") for a in armors: if pulp.value(a.var) > 0: print("|", a.name, "|", a.ar, "|", a.w, "|") print("| Total | ", pulp.value(obj), "|", pulp.value(restr), "|")
def vector_solver(): d = pp.LpVariable.dicts("x", range(2), 0, 1) prob = pp.LpProblem("myV", pp.LpMinimize) prob += d[0] + d[1] == 1 print pp.LpStatus[prob.solve()] print pp.value(d[0]) print pp.value(d[1])
def LPboost_solver(): d = pp.LpVariable.dicts("d", range(3), 0, 1) prob = pp.LpProblem("LPboost", pp.LpMinimize) prob += pp.lpSum(d) == 1 print pp.LpStatus[prob.solve()] for i in range(3): print pp.value(d[i])
def print_model(model): print "STATUS: ", LpStatus[model.status] print "TOTAL COST: ", value(model.total_cost) print "FUEL COSTS: ", value(model.fuel_costs) print "STOP COSTS: ", value(model.stop_costs) print "CONTRACT COSTS: ", value(model.contract_costs) for yard in model.d.YARDS: print "Yard ", yard, value(model.v_contract[yard])
def basic_pulp_solver(): x = pp.LpVariable("x", 0, 3) y = pp.LpVariable("y", 0, 1) prob = pp.LpProblem("myP", pp.LpMinimize) prob += x + y <= 2 prob += -4*x + y status = prob.solve() print pp.LpStatus[status] print pp.value(x), pp.value(y)
def get_true_false_classes(): true_set = set() false_set = set() for rep, size in classes.items(): if value(get_var(rep)) == 0: false_set.add(rep) elif value(get_var(rep)) == size: true_set.add(rep) return true_set, false_set
def main(): x = LpVariable("x", 0, 3) y = LpVariable("y", 0, 1) prob = LpProblem("myProblem", LpMinimize) prob += x + y <= 2 prob += -4*x + y status = prob.solve(COIN(msg = 0)) print LpStatus[status] print value(x) print value(y)
def print_results (self): print '<score>%s</score>' % (pulp.value(self.score),) print '<total>%s</total>' % fmt_stats(map (lambda x: pulp.value(x), self.total_stats)) print '<base>%s</base>' % fmt_stats(self.base_stats) print '<items>' for item_list in self.items.values(): for item in item_list: if pulp.value(self.used[item]) == 1: item.print_results() print '</items>'
def test_expanded_ToyMMB(self): self.pkn.compress() self.pkn.expand_and_gates() model = cno.milp.model.MILPTrain(self.pkn, self.midas) model.train() eps = 1e-12 model_error = pulp.value(model.error_objective_expression()) model_size = pulp.value(model.size_objective_expression()) assert abs(model_error-10.02) < eps assert abs(model_size-9) < eps
def report_copy_map(self): """ Reports the raw counts seen at each variable. This is normalized by the number of variables in the block. """ copy_map = defaultdict(list) for para in self.block_map: for i in xrange(len(self.block_map[para])): start, stop, var, block = self.block_map[para][i] if var is not None: copy_map[para].append([start, stop, pulp.value(var)]) prev_var = pulp.value(var) else: copy_map[para].append([start, stop, prev_var]) return copy_map
def pulp_solve(self): problem = pulp.LpProblem(pulp.LpMinimize) vs = self.get_vars() our_vars = dict() v = [] for i in range(len(vs)): v.append(pulp.LpVariable('%d' %vs[i][0], vs[i][1], vs[i][2])) our_vars[vs[i][0]] = v[i] ob = self.get_objective() problem.objective = pulp.LpAffineExpression([(our_vars[ob[i][0]], ob[i][1]) for i in range(len(ob))]) css = self.get_linear_cons() for i in range(len(css)): ids, coefs, cnst = css[i] c = pulp.LpConstraint( pulp.LpAffineExpression([(our_vars[ids[j]], coefs[j]) for j in range(len(coefs))], constant=cnst) , sense=-1) problem.constraints[i] = c problem.solve() self.solutions.clear() for variable in problem.variables(): self.solutions[int(variable.name)] = variable.varValue self.obj_val = pulp.value(problem.objective)
def GetOptimalWinners(self): ''' By default, find the set of candidates that maximize total bids. :return: ''' prob = pp.LpProblem('KNAPSACK', pp.LpMaximize) x = pp.LpVariable.dict('x', range(len(self.candidates)), 0, 1.5, pp.LpInteger) prob += (sum(x) <= self.n_winners) prob += (sum([x[k] * candidate['duration'] for k, candidate in enumerate(self.candidates)]) \ <= self.max_duration) prob += sum([x[k] * candidate['bid'] for k, candidate in enumerate(self.candidates)] + [0]) prob.solve() for i in range(len(self.candidates)): if pp.value(x[i]) == 1: self.winners.append(VideoPodWinner(self.candidates[i])) return self.winners, pp.value(prob.objective)
def solve(definition): print >> sys.stderr, '-'*20, 'problem' print >> sys.stderr, definition if debug > 1: print >> sys.stderr, '-'*20, 'parse' exs, vars_, target, cat, mm = parse(definition) if debug > 1: print >> sys.stderr, '-'*20, 'setup' prob, target2, lpvar = setup(exs, vars_, target, cat, mm) if debug > 1: print >> sys.stderr, '-'*20, 'solve' status = prob.solve(pulp.GLPK(msg=0)) print >> sys.stderr, '-'*20, 'result' print pulp.LpStatus[status] if pulp.LpStatus[status] == 'Optimal': def sort_var_name(x, y): t = cmp(len(x), len(y)) return t if t != 0 else cmp(x, y) res = {} for n in sorted(vars_, sort_var_name): v = pulp.value(lpvar[n]) res[n] = v print n, ':', v print 'target:', eval(target, res), '=', target2
def export_res(self,queue_b): n = self.n tn = self.tn for i in xrange(n): for t in xrange(tn): queue_b[i].b[t] = int(math.ceil(pulp.value(self.varb[str(i)][str(t)])))
def calculate_V(self, s, agent_name): """ Calculate V for state s by maximizing it while minimizing opponents actions. Returns the maximium value of V """ max_v = pulp.LpProblem("Maximize V", pulp.LpMaximize) # Set V as variable to maximize v = pulp.LpVariable("v", 0.0, cat="Continuous") max_v += v actions = ['West', 'East','North', 'South','Wait'] # Create policy var for actions action_policy_vars = pulp.LpVariable.dicts("A",actions,lowBound =0.0, upBound = 1.0, cat="Continuous") # Probabilities sum to 1 max_v += sum([action_policy_vars[a] for a in actions]) == 1 for a in actions: max_v += action_policy_vars[a] >= 0.000000001 # add constraints as summation of actions given an opponent action are bigger than 0 for o in actions: max_v += sum([self.get_qvalue_minimax(s, agent_name, a, o) * action_policy_vars[a] for a in actions]) >= v # Solve maximization max_v.solve() #for i in actions: # if action_policy_vars[i].value() == 1.0: # print i return pulp.value(max_v.objective)
def solve(g): el = g.get_edge_list() nl = g.get_node_list() p = LpProblem('min_cost', LpMinimize) capacity = {} cost = {} demand = {} x = {} for e in el: capacity[e] = g.get_edge_attr(e[0], e[1], 'capacity') cost[e] = g.get_edge_attr(e[0], e[1], 'cost') for i in nl: demand[i] = g.get_node_attr(i, 'demand') for e in el: x[e] = LpVariable("x"+str(e), 0, capacity[e]) # add obj objective = lpSum (cost[e]*x[e] for e in el) p += objective # add constraints for i in nl: out_neig = g.get_out_neighbors(i) in_neig = g.get_in_neighbors(i) p += lpSum(x[(i,j)] for j in out_neig) -\ lpSum(x[(j,i)] for j in in_neig)==demand[i] p.solve() return x, value(objective)
def K_dominnace_check_2(self, u_d, v_d, _inequalities): """ :param u_d: a d-dimensional vector(list) like [ 8.53149891 3.36436796] :param v_d: tha same list like u_d :param _inequalities: list of constraints on d-dimensional Lambda Polytope like [[0, 1, 0], [1, -1, 0], [0, 0, 1], [1, 0, -1], [0.0, 1.4770889, -3.1250839]] :return: True if u is Kdominance to v regarding given _inequalities otherwise False """ _d = len(u_d) prob = LpProblem("Kdominance", LpMinimize) lambda_variables = LpVariable.dicts("l", range(_d), 0) for inequ in _inequalities: prob += lpSum([inequ[j + 1] * lambda_variables[j] for j in range(0, _d)]) + inequ[0] >= 0 prob += lpSum([lambda_variables[i] * (u_d[i]-v_d[i]) for i in range(_d)]) #prob.writeLP("show-Ldominance.lp") status = prob.solve() LpStatus[status] result = value(prob.objective) if result < 0: return False return True
def _solve_mip(mip,kind='CBC',params=dict(),msg=0) : start_time = time.time() # select solver for pl if kind == 'CPLEX' : if 'time_limit' in params : # pulp does currently not support a timelimit in 1.5.9 mip.solve(pl.CPLEX_CMD(msg=msg,timelimit=params['time_limit'])) else : mip.solve(pl.CPLEX_CMD(msg=msg)) elif kind == 'GLPK' : mip.solve(pl.GLPK_CMD(msg=msg)) elif kind == 'CBC' : options = [] for key in params : if key == 'time_limit' : options.extend(['sec',str(params['time_limit'])]) else : options.extend([str(key),str(params[key])]) 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 mip.status == 1 and msg : print('INFO: objective = '+str(pl.value(mip.objective)))
def _fill_solution(self, dmu_code, model_solution): ''' Fills given solution with data calculated for one DMU. Args: dmu_code (str): DMU code for which the LP was solved. model_solution (Solution): object where solution for one DMU will be written. ''' model_solution.orientation = self._concrete_model.get_orientation() model_solution.add_lp_status(dmu_code, self.lp_model.status) if self.lp_model.status == pulp.LpStatusOptimal: lambda_variables = dict() for dmu in self.input_data.DMU_codes: var = self._variables.get(dmu, None) if (var is not None and var.varValue is not None and abs(var.varValue) > ZERO_TOLERANCE): lambda_variables[dmu] = var.varValue if self._should_add_efficiency: model_solution.add_efficiency_score( dmu_code, self._concrete_model.process_obj_var (pulp.value(self.lp_model.objective))) model_solution.add_lambda_variables(dmu_code, lambda_variables) self._process_duals(dmu_code, self.input_data.input_categories, model_solution.add_input_dual) self._process_duals(dmu_code, self.input_data.output_categories, model_solution.add_output_dual)
def train(self): """Initialize and solve the optimization problem. The problem is solved in two steps. First, the algorithm searches for a network with the best possible fit. Second, the algorithm searches for the smallest possible network that returns the best fit found. """ # reset constraint set self.model.constraints.clear() # add problem constraints self.add_problem_constraints() # Optimize for error error_obj = self.error_objective_expression() self.model += error_obj sol = self.model.solve() if sol is pulp.LpStatusInfeasible: raise Exception("Infeasible model.") # Optimize for size best_fit_value = pulp.value(self.model.objective) self.model += error_obj == best_fit_value, 'fit_constraint' size_obj = self.size_objective_expression() self.model += size_obj sol = self.model.solve() if sol is pulp.LpStatusInfeasible: raise Exception("Infeasible model.")
def opt(C, X): orderNum = len(X) routeNum = len(C) routeIdx = range(routeNum) orderIdx = range(orderNum) # print routeIdx,orderIdx eps = 1.0 / 10 ** 7 print eps var_choice = lp.LpVariable.dicts('route', routeIdx, cat='Binary') # var_choice=lp.LpVariable.dicts('route',routeIdx,lowBound=0)#尝试松弛掉01变量 exceed_labor = lp.LpVariable('Number of routes exceed 1000', 0) prob = lp.LpProblem("lastMile", lp.LpMinimize) prob += exceed_labor * 100000 + lp.lpSum(var_choice[i] * C[i] for i in routeIdx) prob += lp.lpSum(var_choice[i] for i in routeIdx) <= 1000 + exceed_labor + eps for i in orderIdx: prob += lp.lpSum(var_choice[j] for j in X[i]) >= (1 - eps) prob.solve(lp.CPLEX(msg=0)) print "\n\nstatus:", lp.LpStatus[prob.status] if lp.LpStatus[prob.status] != 'Infeasible': obj = lp.value(prob.objective) print "\n\nobjective:", obj sol_list = [var_choice[i].varValue for i in routeIdx] print "\n\nroutes:", (sum(sol_list)) # print "\n\noriginal problem:\n",prob return obj, sol_list, lp.LpStatus[prob.status] else: return None, None, lp.LpStatus[prob.status]
def __init__(self,Distribution_2,Distribution_1): # Make the distributions condensed to make the LP problem easier to solve if possible Condense_Distribution(Distribution_1) Condense_Distribution(Distribution_2) self.left_margin = len(Distribution_1) self.right_margin = len(Distribution_2) # Formulated the Wasserstein Trasportation problem the two distribution # Flow variables from this will be used for the points on the geodesic try: print "Formulating LP..." tempLP = Wasserstein_Transportation(Distribution_1,Distribution_2) except Exception as e: print e raise ValueError('Cannot formulate LP') # Solve the returned transportation problem try: print "Solving LP..." pulp.GLPK().solve(tempLP) except Exception as e: print e raise ValueError('Cannot solve LP') self.supply_coordinates = [np.array(point[1]) for point in Distribution_1] # Get the coordinates of the final distribution self.demand_coordinates = [np.array(point[1]) for point in Distribution_2] # Get the coordinates of the starting distribution self.wasserstein_distance = pulp.value(tempLP.objective) # Save Wasserstein distance so the weighted sum of distance from the geodesic points to starting/ending distributions can be returned self.flow_matrix = Read_Wasserstein_Flow(tempLP, self.left_margin , self.right_margin) # Read flow variables to formulate geodesic coefficents
def path(self): if self._status != pulp.LpStatusOptimal: raise Exception("No optimal solution.") else: path_edges = [edge for edge in self.hypergraph.edges if pulp.value(self.edge_vars[edge.id]) == 1.0] return ph.Path(self.hypergraph, path_edges)
def solution(self): '''return set of variables that are True in solution''' sol = set() for name, var in self._vars.iteritems(): if var.aux: continue if pulp.value(self._mipvars[name]) > 0.5: sol.add(var) return sol
def _solve_balancing_ilp_pulp(A): import pulp x = [pulp.LpVariable('x%d' % i, lowBound=1, cat='Integer') for i in range(A.shape[1])] prob = pulp.LpProblem("chempy balancing problem", pulp.LpMinimize) prob += reduce(add, x) for expr in [pulp.lpSum([x[i]*e for i, e in enumerate(row)]) for row in A.tolist()]: prob += expr == 0 prob.solve() return [pulp.value(_) for _ in x]
def optimize(prob, choices, period, attract_start, attract_end, select_attract): prob.solve() optimized_schedule = [] if prob.status==1: for p in period: for a1 in attract_start: for a2 in attract_end: if pulp.value(choices[p][a1][a2])>0: optimized_schedule.append([int(p), select_attract[int(a1)], select_attract[int(a2)]]) return optimized_schedule
def score_range_image_level(p_fov, n_fov, p_diff, n_diff, acc_all, sens_all, spec_all, eps, n_diff_lower, score='acc'): """ Score range reconstruction at the image level Args: p_fov (int): number of positives under the FoV n_fov (int): number of negatives under the FoV p_diff (int): number of positives outside the FoV n_diff (int): number of negatives outside the FoV acc_all (float): accuracy in the entire image sens_all (float): sensitivity in the entire image spec_all (float): specificity in the entire image eps (float): numerical uncertainty n_diff_lower (int): the minimum number of negatives outside the FoV score (str): score to compute: 'acc'/'sens'/'spec' Returns: float, float, float: the mid-score, the worst case minimum and best case maximum values """ prob = pl.LpProblem("maximum", pl.LpMaximize) tp_fov = pl.LpVariable("tp_fov", 0, p_fov, pl.LpInteger) tn_fov = pl.LpVariable("tn_fov", 0, n_fov, pl.LpInteger) tp_diff = pl.LpVariable("tp_diff", 0, p_diff, pl.LpInteger) tn_diff = pl.LpVariable("tn_diff", n_diff_lower, n_diff, pl.LpInteger) prob += (tp_fov + tp_diff) * (1.0 / (p_fov + p_diff)) <= sens_all + eps prob += (tp_fov + tp_diff) * (-1.0 / (p_fov + p_diff)) <= -(sens_all - eps) prob += (tn_fov + tn_diff) * (1.0 / (n_fov + n_diff)) <= spec_all + eps prob += (tn_fov + tn_diff) * (-1.0 / (n_fov + n_diff)) <= -(spec_all - eps) prob += (tp_fov + tp_diff + tn_fov + tn_diff) * (1.0 / (p_fov + p_diff + n_fov + n_diff)) <= acc_all + eps prob += (tp_fov + tp_diff + tn_fov + tn_diff) * (-1.0 / (p_fov + p_diff + n_fov + n_diff)) <= -(acc_all - eps) if score == 'acc': prob += (tp_fov + tn_fov) * (1.0 / (p_fov + n_fov)) elif score == 'spec': prob += (tn_fov) * (1.0 / n_fov) elif score == 'sens': prob += (tp_fov) * (1.0 / p_fov) prob.solve() score_max = pl.value(prob.objective) prob = pl.LpProblem("minimum", pl.LpMinimize) tp_fov = pl.LpVariable("tp_fov", 0, p_fov, pl.LpInteger) tn_fov = pl.LpVariable("tn_fov", 0, n_fov, pl.LpInteger) tp_diff = pl.LpVariable("tp_diff", 0, p_diff, pl.LpInteger) tn_diff = pl.LpVariable("tn_diff", n_diff_lower, n_diff, pl.LpInteger) prob += (tp_fov + tp_diff) * (1.0 / (p_fov + p_diff)) <= sens_all + eps prob += (tp_fov + tp_diff) * (-1.0 / (p_fov + p_diff)) <= -(sens_all - eps) prob += (tn_fov + tn_diff) * (1.0 / (n_fov + n_diff)) <= spec_all + eps prob += (tn_fov + tn_diff) * (-1.0 / (n_fov + n_diff)) <= -(spec_all - eps) prob += (tp_fov + tp_diff + tn_fov + tn_diff) * (1.0 / (p_fov + p_diff + n_fov + n_diff)) <= acc_all + eps prob += (tp_fov + tp_diff + tn_fov + tn_diff) * (-1.0 / (p_fov + p_diff + n_fov + n_diff)) <= -(acc_all - eps) if score == 'acc': prob += (tp_fov + tn_fov) * (1.0 / (p_fov + n_fov)) elif score == 'spec': prob += (tn_fov) * (1.0 / n_fov) elif score == 'sens': prob += (tp_fov) * (1.0 / p_fov) prob.solve() score_min = pl.value(prob.objective) return (score_max + score_min) / 2.0, (score_max - score_min) / 2.0
from pulp import LpProblem, LpMaximize, LpVariable, LpStatus, value prob = LpProblem('Example', LpMaximize) x1 = LpVariable('x1', lowBound=0, cat='Integer') x2 = LpVariable('x2', lowBound=0, cat='Integer') x3 = LpVariable('x3', lowBound=0, cat='Integer') x4 = LpVariable('x4', lowBound=0, cat='Integer') x5 = LpVariable('x5', lowBound=0, cat='Integer') x6 = LpVariable('x6', lowBound=0, cat='Integer') x7 = LpVariable('x7', lowBound=0, cat='Integer') prob += 2 * x1 + 5 * x2 + 1 * x3 + 4 * x4 + 3 * x5 + 6 * x6 + 7 * x7 prob += x1 + x2 + 2 * x3 + 2 * x4 + x5 + x6 + x7 <= 1000 prob += 2 * x1 + 4 * x2 + 1 * x3 + 1 * x4 + 1 * x5 + 3 * x6 + 2 * x7 <= 2000 prob += 5000000 * x1 + 4000000 * x2 + 4000000 * x3 + 1500000 * x4 + 5000000 * x5 + 3500000 * x6 + 4500000 * x7 <= 3500000000 prob += 4 * x2 + 2 * x5 + 3 * x7 >= 1000 print(LpStatus[prob.status]) prob.solve() print(value(x1)) print(value(x2)) print(value(x3)) print(value(x4)) print(value(x5)) print(value(x6)) print(value(x7)) print(value(prob.objective))
# Define the problem prob = pulp.LpProblem("The Brewery Problem", pulp.LpMinimize) # Define the variables, MINIMUM ZERO x1 = pulp.LpVariable("Beer", 0) x2 = pulp.LpVariable("Ale", 0, cat="Continuous") # Objective function (NEGATIVE PRODUCTS) prob += -(23 * x1 + 13 * x2) # Constraints prob += 15 * x1 + 5 * x2 <= 480, "Corn availability" prob += 4 * x1 + 4 * x2 <= 160, "Hops availability" prob += 20 * x1 + 35 * x2 <= 1190, "Malt availability" # Write the problem on an .lp file prob.writeLP("Brewery.lp") # Solve --> prob.solve() AUTOMATIC SOLVER, or instead prob.solve(pulp.PULP_CBC_CMD(fracGap=1e-5, maxSeconds=500, threads=None)) # Status of the solution print("Status: ", pulp.LpStatus[prob.status]) # Optimal value of objective function print("Total revenue = ", -1 * pulp.value(prob.objective)) # Optimal value of variables for v in prob.variables(): print(v.name, " = ", v.varValue)
def main(): matriz_dado = Open('Dados') #Dados de entrada F = int(matriz_dado.pop(0)) #Número de fabricas C = int(matriz_dado.pop(0)) #Número de cidades CD = int(matriz_dado.pop(0)) #Número de centros de distribuicao p = float(matriz_dado.pop(0)) #Preço do cimento cc = float(matriz_dado.pop(0)) #Custo de transporte por caminhão cf = float(matriz_dado.pop(0)) #Custo de transporte por ferrovia #Cria os vetores de matrizes y = Matriz(CD, 0) z = Matriz(F, 0) x = Matriz(F, C) g = Matriz(F, CD) q = Matriz(CD, C) c = Matriz(F, 0) d = Matriz(C, 0) f = Matriz(CD, 0) cap = Matriz(F, 0) distij = Matriz(F, C) distkj = Matriz(CD, C) distik = Matriz(F, CD) #Capacidade da fabrica i for i in range(F): cap[i] = float(matriz_dado.pop(0)) #Custo da fabrica i for i in range(F): c[i] = float(matriz_dado.pop(0)) #Taxa anual for k in range(CD): f[k] = float(matriz_dado.pop(0)) matriz_demanda = Open('Demandas_cidades') #Demanda da cidade for j in range(C): d[j] = float(matriz_demanda.pop(0)) matriz_f_c = Open('Distancias_Fabricas_Cidades') matriz_f_cd = Open('Distancias_Fabricas_Centros') matriz_c_cd = Open('Distancias_Centro_Cidades') #Distancias das fabricas para as cidades for i in range(F): for j in range(C): distij[i][j] = float(matriz_f_c.pop(0)) #Distancias dos centros de distribuição para as cidades for k in range(CD): for j in range(C): distkj[k][j] = float(matriz_c_cd.pop(0)) #Distancias das dabricas para os centros de distribuição for i in range(F): for k in range(CD): distik[i][k] = float(matriz_f_cd.pop(0)) #Cria um problema de maximazação opt_model = pulp.LpProblem("Cadeia de Suprimento", pulp.LpMaximize) ### VARIAVEIS DE DECISAO for k in range(CD): y[k] = pulp.LpVariable('y' + str(k), lowBound=0, upBound=1, cat='Binary') for i in range(F): z[i] = pulp.LpVariable('z' + str(i), lowBound=0, upBound=1, cat='Binary') for i in range(F): for j in range(C): x[i][j] = pulp.LpVariable('x' + str(i) + str(j), lowBound=0, cat='Continuous') for i in range(F): for k in range(CD): g[i][k] = pulp.LpVariable('g' + str(i) + str(k), lowBound=0, cat='Continuous') for k in range(CD): for j in range(C): q[k][j] = pulp.LpVariable('q' + str(k) + str(j), lowBound=0, cat='Continuous') ###FUNÇÃO OBJETIVO opt_model += p * (pulp.lpSum( x[i][j] for i in range(F) for j in range(C))) + p * (pulp.lpSum( g[i][k] for i in range(F) for k in range(CD))) - (pulp.lpSum( c[i] * z[i] for i in range(F))) - (pulp.lpSum( f[k] * y[k] for k in range(CD))) - cc * (pulp.lpSum( x[i][j] * distij[i][j] for i in range(F) for j in range(C))) - cf * (pulp.lpSum([ g[i][k] * distik[i][k] for i in range(F) for k in range(CD) ])) - cc * (pulp.lpSum(q[k][j] * distkj[k][j] for k in range(CD) for j in range(C))) ### RESTRIÇÕES #Restricao 1 for j in range(C): opt_model += (pulp.lpSum(x[i][j] for i in range(F) for j in range(C))) + (pulp.lpSum( q[k][j] for k in range(CD) for j in range(C))) <= d[j] #Restricao 2 for k in range(CD): opt_model += (pulp.lpSum( q[k][j] for j in range(C))) <= (pulp.lpSum(cap[i] for i in range(F))) * y[k] #Restricao 3 for i in range(F): opt_model += (pulp.lpSum(g[i][k] for k in range(CD))) + (pulp.lpSum( x[i][j] for j in range(C))) <= cap[i] * z[i] #Escreve o modelo na pasta raiz opt_model.writeLP('Resricoes.txt') #Solve while True: opt_model.solve() if (pulp.LpStatus[opt_model.status] == "Optimal"): print("\nSOLUCAO OTIMA ENCONTRADA ########\n") print('Lucro Total = ' + str(pulp.value(opt_model.objective))) break else: print("SOLUCAO OTIMA NAO ENCONTRADA")
def BranchAndBound(T, CONSTRAINTS, VARIABLES, OBJ, MAT, RHS, branch_strategy=MOST_FRACTIONAL, search_strategy=DEPTH_FIRST, complete_enumeration=False, display_interval=None, binary_vars=True): if T.get_layout() == 'dot2tex': cluster_attrs = { 'name': 'Key', 'label': r'\text{Key}', 'fontsize': '12' } T.add_node('C', label=r'\text{Candidate}', style='filled', color='yellow', fillcolor='yellow') T.add_node('I', label=r'\text{Infeasible}', style='filled', color='orange', fillcolor='orange') T.add_node('S', label=r'\text{Solution}', style='filled', color='lightblue', fillcolor='lightblue') T.add_node('P', label=r'\text{Pruned}', style='filled', color='red', fillcolor='red') T.add_node('PC', label=r'\text{Pruned}$\\ $\text{Candidate}', style='filled', color='red', fillcolor='yellow') else: cluster_attrs = {'name': 'Key', 'label': 'Key', 'fontsize': '12'} T.add_node('C', label='Candidate', style='filled', color='yellow', fillcolor='yellow') T.add_node('I', label='Infeasible', style='filled', color='orange', fillcolor='orange') T.add_node('S', label='Solution', style='filled', color='lightblue', fillcolor='lightblue') T.add_node('P', label='Pruned', style='filled', color='red', fillcolor='red') T.add_node('PC', label='Pruned \n Candidate', style='filled', color='red', fillcolor='yellow') T.add_edge('C', 'I', style='invisible', arrowhead='none') T.add_edge('I', 'S', style='invisible', arrowhead='none') T.add_edge('S', 'P', style='invisible', arrowhead='none') T.add_edge('P', 'PC', style='invisible', arrowhead='none') T.create_cluster(['C', 'I', 'S', 'P', 'PC'], cluster_attrs) # The initial lower bound LB = -INFINITY # The number of LP's solved, and the number of nodes solved node_count = 1 iter_count = 0 lp_count = 0 if binary_vars: var = LpVariable.dicts("", VARIABLES, 0, 1) else: var = LpVariable.dicts("", VARIABLES) numCons = len(CONSTRAINTS) numVars = len(VARIABLES) # List of incumbent solution variable values opt = dict([(i, 0) for i in VARIABLES]) pseudo_u = dict((i, (OBJ[i], 0)) for i in VARIABLES) pseudo_d = dict((i, (OBJ[i], 0)) for i in VARIABLES) print("===========================================") print("Starting Branch and Bound") if branch_strategy == MOST_FRACTIONAL: print("Most fractional variable") elif branch_strategy == FIXED_BRANCHING: print("Fixed order") elif branch_strategy == PSEUDOCOST_BRANCHING: print("Pseudocost brancing") else: print("Unknown branching strategy %s" % branch_strategy) if search_strategy == DEPTH_FIRST: print("Depth first search strategy") elif search_strategy == BEST_FIRST: print("Best first search strategy") else: print("Unknown search strategy %s" % search_strategy) print("===========================================") # List of candidate nodes Q = PriorityQueue() # The current tree depth cur_depth = 0 cur_index = 0 # Timer timer = time.time() Q.push(0, -INFINITY, (0, None, None, None, None, None, None)) # Branch and Bound Loop while not Q.isEmpty(): infeasible = False integer_solution = False (cur_index, parent, relax, branch_var, branch_var_value, sense, rhs) = Q.pop() if cur_index is not 0: cur_depth = T.get_node_attr(parent, 'level') + 1 else: cur_depth = 0 print("") print("----------------------------------------------------") print("") if LB > -INFINITY: print("Node: %s, Depth: %s, LB: %s" % (cur_index, cur_depth, LB)) else: print("Node: %s, Depth: %s, LB: %s" % (cur_index, cur_depth, "None")) if relax is not None and relax <= LB: print("Node pruned immediately by bound") T.set_node_attr(parent, 'color', 'red') continue #==================================== # LP Relaxation #==================================== # Compute lower bound by LP relaxation prob = LpProblem("relax", LpMaximize) prob += lpSum([OBJ[i] * var[i] for i in VARIABLES]), "Objective" for j in range(numCons): prob += (lpSum([MAT[i][j]*var[i] for i in VARIABLES])<=RHS[j],\ CONSTRAINTS[j]) # Fix all prescribed variables branch_vars = [] if cur_index is not 0: sys.stdout.write("Branching variables: ") branch_vars.append(branch_var) if sense == '>=': prob += LpConstraint(lpSum(var[branch_var]) >= rhs) else: prob += LpConstraint(lpSum(var[branch_var]) <= rhs) print(branch_var, end=' ') pred = parent while not str(pred) == '0': pred_branch_var = T.get_node_attr(pred, 'branch_var') pred_rhs = T.get_node_attr(pred, 'rhs') pred_sense = T.get_node_attr(pred, 'sense') if pred_sense == '<=': prob += LpConstraint( lpSum(var[pred_branch_var]) <= pred_rhs) else: prob += LpConstraint( lpSum(var[pred_branch_var]) >= pred_rhs) print(pred_branch_var, end=' ') branch_vars.append(pred_branch_var) pred = T.get_node_attr(pred, 'parent') print() # Solve the LP relaxation prob.solve() lp_count = lp_count + 1 # Check infeasibility infeasible = LpStatus[prob.status] == "Infeasible" or \ LpStatus[prob.status] == "Undefined" # Print status if infeasible: print("LP Solved, status: Infeasible") else: print("LP Solved, status: %s, obj: %s" % (LpStatus[prob.status], value(prob.objective))) if (LpStatus[prob.status] == "Optimal"): relax = value(prob.objective) # Update pseudocost if branch_var != None: if sense == '<=': pseudo_d[branch_var] = (old_div( (pseudo_d[branch_var][0] * pseudo_d[branch_var][1] + old_div((T.get_node_attr(parent, 'obj') - relax), (branch_var_value - rhs))), (pseudo_d[branch_var][1] + 1)), pseudo_d[branch_var][1] + 1) else: pseudo_u[branch_var] = (old_div( (pseudo_u[branch_var][0] * pseudo_d[branch_var][1] + old_div((T.get_node_attr(parent, 'obj') - relax), (rhs - branch_var_value))), (pseudo_u[branch_var][1] + 1)), pseudo_u[branch_var][1] + 1) var_values = dict([(i, var[i].varValue) for i in VARIABLES]) integer_solution = 1 for i in VARIABLES: if (abs(round(var_values[i]) - var_values[i]) > .001): integer_solution = 0 break # Determine integer_infeasibility_count and # Integer_infeasibility_sum for scatterplot and such integer_infeasibility_count = 0 integer_infeasibility_sum = 0.0 for i in VARIABLES: if (var_values[i] not in set([0, 1])): integer_infeasibility_count += 1 integer_infeasibility_sum += min( [var_values[i], 1.0 - var_values[i]]) if (integer_solution and relax > LB): LB = relax for i in VARIABLES: # These two have different data structures first one #list, second one dictionary opt[i] = var_values[i] print("New best solution found, objective: %s" % relax) for i in VARIABLES: if var_values[i] > 0: print("%s = %s" % (i, var_values[i])) elif (integer_solution and relax <= LB): print("New integer solution found, objective: %s" % relax) for i in VARIABLES: if var_values[i] > 0: print("%s = %s" % (i, var_values[i])) else: print("Fractional solution:") for i in VARIABLES: if var_values[i] > 0: print("%s = %s" % (i, var_values[i])) #For complete enumeration if complete_enumeration: relax = LB - 1 else: relax = INFINITY if integer_solution: print("Integer solution") BBstatus = 'S' status = 'integer' color = 'lightblue' elif infeasible: print("Infeasible node") BBstatus = 'I' status = 'infeasible' color = 'orange' elif not complete_enumeration and relax <= LB: print("Node pruned by bound (obj: %s, UB: %s)" % (relax, LB)) BBstatus = 'P' status = 'fathomed' color = 'red' elif cur_depth >= numVars: print("Reached a leaf") BBstatus = 'fathomed' status = 'L' else: BBstatus = 'C' status = 'candidate' color = 'yellow' if BBstatus is 'I': if T.get_layout() == 'dot2tex': label = '\text{I}' else: label = 'I' else: label = "%.1f" % relax if iter_count == 0: if status is not 'candidate': integer_infeasibility_count = None integer_infeasibility_sum = None if status is 'fathomed': if T._incumbent_value is None: print('WARNING: Encountered "fathom" line before '+\ 'first incumbent.') T.AddOrUpdateNode(0, None, None, 'candidate', relax, integer_infeasibility_count, integer_infeasibility_sum, label=label, obj=relax, color=color, style='filled', fillcolor=color) if status is 'integer': T._previous_incumbent_value = T._incumbent_value T._incumbent_value = relax T._incumbent_parent = -1 T._new_integer_solution = True # #Currently broken # if ETREE_INSTALLED and T.attr['display'] == 'svg': # T.write_as_svg(filename = "node%d" % iter_count, # nextfile = "node%d" % (iter_count + 1), # highlight = cur_index) else: _direction = {'<=': 'L', '>=': 'R'} if status is 'infeasible': integer_infeasibility_count = T.get_node_attr( parent, 'integer_infeasibility_count') integer_infeasibility_sum = T.get_node_attr( parent, 'integer_infeasibility_sum') relax = T.get_node_attr(parent, 'lp_bound') elif status is 'fathomed': if T._incumbent_value is None: print('WARNING: Encountered "fathom" line before'+\ ' first incumbent.') print(' This may indicate an error in the input file.') elif status is 'integer': integer_infeasibility_count = None integer_infeasibility_sum = None T.AddOrUpdateNode(cur_index, parent, _direction[sense], status, relax, integer_infeasibility_count, integer_infeasibility_sum, branch_var=branch_var, branch_var_value=var_values[branch_var], sense=sense, rhs=rhs, obj=relax, color=color, style='filled', label=label, fillcolor=color) if status is 'integer': T._previous_incumbent_value = T._incumbent_value T._incumbent_value = relax T._incumbent_parent = parent T._new_integer_solution = True # Currently Broken # if ETREE_INSTALLED and T.attr['display'] == 'svg': # T.write_as_svg(filename = "node%d" % iter_count, # prevfile = "node%d" % (iter_count - 1), # nextfile = "node%d" % (iter_count + 1), # highlight = cur_index) if T.get_layout() == 'dot2tex': _dot2tex_label = {'>=': ' \geq ', '<=': ' \leq '} T.set_edge_attr( parent, cur_index, 'label', str(branch_var) + _dot2tex_label[sense] + str(rhs)) else: T.set_edge_attr(parent, cur_index, 'label', str(branch_var) + sense + str(rhs)) iter_count += 1 if BBstatus == 'C': # Branching: # Choose a variable for branching branching_var = None if branch_strategy == FIXED_BRANCHING: #fixed order for i in VARIABLES: frac = min(var[i].varValue - math.floor(var[i].varValue), math.ceil(var[i].varValue) - var[i].varValue) if (frac > 0): min_frac = frac branching_var = i # TODO(aykut): understand this break break elif branch_strategy == MOST_FRACTIONAL: #most fractional variable min_frac = -1 for i in VARIABLES: frac = min(var[i].varValue - math.floor(var[i].varValue), math.ceil(var[i].varValue) - var[i].varValue) if (frac > min_frac): min_frac = frac branching_var = i elif branch_strategy == PSEUDOCOST_BRANCHING: scores = {} for i in VARIABLES: # find the fractional solutions if (var[i].varValue - math.floor(var[i].varValue)) != 0: scores[i] = min(pseudo_u[i][0] * (1 - var[i].varValue), pseudo_d[i][0] * var[i].varValue) # sort the dictionary by value branching_var = sorted(list(scores.items()), key=lambda x: x[1])[-1][0] else: print("Unknown branching strategy %s" % branch_strategy) exit() if branching_var is not None: print("Branching on variable %s" % branching_var) #Create new nodes if search_strategy == DEPTH_FIRST: priority = (-cur_depth - 1, -cur_depth - 1) elif search_strategy == BEST_FIRST: priority = (-relax, -relax) elif search_strategy == BEST_ESTIMATE: priority = (-relax - pseudo_d[branching_var][0]*\ (math.floor(var[branching_var].varValue) -\ var[branching_var].varValue), -relax + pseudo_u[branching_var][0]*\ (math.ceil(var[branching_var].varValue) -\ var[branching_var].varValue)) node_count += 1 Q.push(node_count, priority[0], (node_count, cur_index, relax, branching_var, var_values[branching_var], '<=', math.floor(var[branching_var].varValue))) node_count += 1 Q.push(node_count, priority[1], (node_count, cur_index, relax, branching_var, var_values[branching_var], '>=', math.ceil(var[branching_var].varValue))) T.set_node_attr(cur_index, color, 'green') if T.root is not None and display_interval is not None and\ iter_count%display_interval == 0: T.display(count=iter_count) timer = int(math.ceil((time.time() - timer) * 1000)) print("") print("===========================================") print("Branch and bound completed in %sms" % timer) print("Strategy: %s" % branch_strategy) if complete_enumeration: print("Complete enumeration") print("%s nodes visited " % node_count) print("%s LP's solved" % lp_count) print("===========================================") print("Optimal solution") #print optimal solution for i in sorted(VARIABLES): if opt[i] > 0: print("%s = %s" % (i, opt[i])) print("Objective function value") print(LB) print("===========================================") if T.attr['display'] is not 'off': T.display(count=iter_count) T._lp_count = lp_count return opt, LB
def maximum_traded_volume(bids, *args, reservation_prices={}): """ Parameters ---------- bids : pd.DataFrame Collections of bids reservation_prices : dict of floats or None, (Default value = None) A maping from user ids to reservation prices. If no reservation price for a user is given, his bid will be assumed to be his true value. Returns ------- status : str Status of the optimization problem. Desired output is 'Optimal' objective: float Maximum tradable volume that can be obtained variables: dict A set of values achieving the objective. Maps a pair of bids to the quantity traded by them. Examples --------- >>> bm = pm.BidManager() >>> bm.add_bid(1, 3, 0) 0 >>> bm.add_bid(1, 2, 1) 1 >>> bm.add_bid(1.5, 1, 2, False) 2 >>> s, o, v = maximum_traded_volume(bm.get_df()) >>> s 'Optimal' >>> o 1.5 >>> v {(0, 2): 0.5, (1, 2): 1.0} """ model = pulp.LpProblem("Max aggregated utility", pulp.LpMaximize) buyers = bids.loc[bids['buying']].index.values sellers = bids.loc[~bids['buying']].index.values index = [(i, j) for i in buyers for j in sellers if bids.iloc[i, 1] >= bids.iloc[j, 1]] qs = pulp.LpVariable.dicts('q', index, lowBound=0, cat='Continuous') model += pulp.lpSum([qs[x[0], x[1]] for x in index]) for b in buyers: model += pulp.lpSum( qs[b, j] for j in sellers if (b, j) in index) <= bids.iloc[b, 0] for s in sellers: model += pulp.lpSum( qs[i, s] for i in buyers if (i, s) in index) <= bids.iloc[s, 0] model.solve() status = pulp.LpStatus[model.status] objective = pulp.value(model.objective) variables = {} for q in qs: v = qs[q].varValue variables[q] = v return status, objective, variables
def calculate_meal_4(products_json, diet_json, enhance): """Calculates meal with given 4 products.""" products_dictionary = json.loads(products_json) diets_dictionary = json.loads(diet_json) enhance_int = int(enhance) model = LpProblem(name="diet-minimization", sense=LpMinimize) product_1_kcal = products_dictionary["product1"]["kcal"] product_1_proteins = products_dictionary["product1"]["proteins"] product_1_carbs = products_dictionary["product1"]["carbs"] product_1_fats = products_dictionary["product1"]["fats"] product_2_kcal = products_dictionary["product2"]["kcal"] product_2_proteins = products_dictionary["product2"]["proteins"] product_2_carbs = products_dictionary["product2"]["carbs"] product_2_fats = products_dictionary["product2"]["fats"] product_3_kcal = products_dictionary["product3"]["kcal"] product_3_proteins = products_dictionary["product3"]["proteins"] product_3_carbs = products_dictionary["product3"]["carbs"] product_3_fats = products_dictionary["product3"]["fats"] product_4_kcal = products_dictionary["product4"]["kcal"] product_4_proteins = products_dictionary["product4"]["proteins"] product_4_carbs = products_dictionary["product4"]["carbs"] product_4_fats = products_dictionary["product4"]["fats"] x = LpVariable("prod_1_100g", products_dictionary["product1"]["min_weight"], products_dictionary["product1"]["max_weight"]) y = LpVariable("prod_2_100g", products_dictionary["product2"]["min_weight"], products_dictionary["product2"]["max_weight"]) z = LpVariable("prod_3_100g", products_dictionary["product3"]["min_weight"], products_dictionary["product3"]["max_weight"]) w = LpVariable("prod_4_100g", products_dictionary["product4"]["min_weight"], products_dictionary["product4"]["max_weight"]) A = (product_1_kcal + (enhance_int * product_1_proteins) + (enhance_int * product_1_fats) + (enhance_int * product_1_carbs)) B = (product_2_kcal + (enhance_int * product_2_proteins) + (enhance_int * product_2_fats) + (enhance_int * product_2_carbs)) C = (product_3_kcal + (enhance_int * product_3_proteins) + (enhance_int * product_3_fats) + (enhance_int * product_3_carbs)) D = (product_4_kcal + (enhance_int * product_4_proteins) + (enhance_int * product_4_fats) + (enhance_int * product_4_carbs)) E = (diets_dictionary["kcal"] + (enhance_int * diets_dictionary["proteins"]) + (enhance_int * diets_dictionary["carbs"]) + (enhance_int * diets_dictionary["fats"])) optimization_function = A * x + B * y + C * z + D * w - E model += (A * x + B * y + C * z + D * w - E >= 0) model += optimization_function solved_model = model.solve() print("<<<<SPLITTER>>>>") results = { "ingridients": [{ "id": products_dictionary["product1"]["id"], "weight": value(x) }, { "id": products_dictionary["product2"]["id"], "weight": value(y) }, { "id": products_dictionary["product3"]["id"], "weight": value(z) }, { "id": products_dictionary["product4"]["id"], "weight": value(w) }], "fit_function": { "score": value(model.objective), "fit_func_calories_coeff": 1, "fit_func_proteins_coeff": enhance_int, "fit_func_carbs_coeff": enhance_int, "fit_func_fats_coeff": enhance_int } } print(json.dumps(results)) return results
def _var_sol(self, var: Union[LpVariable, Var]) -> float: """Method to obtain the solution of a decision variable""" return value(var) if self.optimizer == 'pulp' else var.x
# Define PuLP variables to solve quantities = pulp.LpVariable.dicts("quantity", dealers, lowBound=0, cat=pulp.LpInteger) is_orders = pulp.LpVariable.dicts("orders", dealers, cat=pulp.LpBinary) """ This is an example of implementing an IP model with binary variables the correct way. """ # Initialize the model with constraints model = pulp.LpProblem("A cost minimization problem", pulp.LpMinimize) model += sum([variable_costs[i]*quantities[i] + fixed_costs[i]*is_orders[i] for i in dealers]), \ "Minimize portfolio cost" model += sum([quantities[i] for i in dealers]) == 150, \ "Total contracts required" model += is_orders["X"]*30 <= quantities["X"] <= \ is_orders["X"]*100, "Boundary of total volume of X" model += is_orders["Y"]*30 <= quantities["Y"] <= \ is_orders["Y"]*90, "Boundary of total volume of Y" model += is_orders["Z"]*30 <= quantities["Z"] <= \ is_orders["Z"]*70, "Boundary of total volume of Z" model.solve() print "Minimization Results:" for variable in model.variables(): print variable, "=", variable.varValue print "Total cost: %s" % pulp.value(model.objective)
]) <= available_flow[k] # upstream cannot exceed downstream # need k by i downstream proportions matrix for k in basins: downstream_basins = list(downstream_connectivity_df.index[ downstream_connectivity_df[k] == 1]) for j in downstream_basins: Riparian_LP += basin_proportions[j] <= basin_proportions[k] # SOLVE USING PULP SOLVER Riparian_LP.solve() print("Status: ", pulp.LpStatus[Riparian_LP.status]) # for v in Riparian_LP.variables(): # print(v.name, "=", v.varValue) print("Objective = ", pulp.value(Riparian_LP.objective)) # basin demand dictionary basin_demand = { basins[k]: (np.matmul(riparian_basin_user_matrix, riparian_demand_data)[k]) for k, basin in enumerate(basins) } # this loop is necessary to turn LP output into values basin_allocation = [] for k, basin in enumerate(basins): basin_allocation.append(basin_proportions[basin].value() * basin_demand[basin]) # print("Basin Total Allocations", basin_allocation) # build output table
def weak_rev_lin_con(crn, eps, ubound): m = crn.n_complexes n = crn.n_species # Y is n by m Y = np.array(crn.complex_matrix).astype(np.float64) # Ak is m by m Ak = np.array(crn.kinetic_matrix).astype(np.float64) # M is n by m M = Y.dot(Ak) print("Input CRN defined by\nY =\n", Y) print("\nM =\n", M) print("\nAk =\n", Ak) print( "\nComputing linearly conjugate network with min deficiency ... START\n" ) # Ranges for iteration col_range = range(1, m + 1) row_range = range(1, n + 1) # Set up problem model object prob = LpProblem("Weakly Reversible Linearly Conjugate Network", LpMaximize) # Get a list of all off-diagonal entries to use later to greatly # simplify loops off_diag = [(i, j) for i, j in product(col_range, repeat=2) if i != j] # Decision variables for matrix A, only need off-diagonal since A # has zero-sum columns A = LpVariable.dicts("A", [(i, j) for i in col_range for j in col_range]) Ah = LpVariable.dicts("Ah", [(i, j) for i in col_range for j in col_range]) # Decision variables for the diagonal of T T = LpVariable.dicts("T", row_range, eps, ubound) # Binary variables for counting partitions used and assigning complexes to linkage classes delta = LpVariable.dicts("delta", off_diag, 0, 1, "Integer") # Objective prob += -lpSum(delta[i, j] for (i, j) in off_diag) # Y*A = T*M for i in row_range: for j in col_range: prob += lpSum(Y[i - 1, k - 1] * A[k, j] for k in col_range) == M[i - 1, j - 1] * T[i] # A and Ah have zero-sum columns for j in col_range: prob += lpSum(A[i, j] for i in col_range) == 0 prob += lpSum(Ah[i, j] for i in col_range) == 0 prob += lpSum(Ah[j, i] for i in col_range) == 0 # Off-diagonal entries are nonnegative and are switch on/off by delta[i,j] for (i, j) in off_diag: # A constraints prob += A[i, j] >= 0 prob += A[i, j] - eps * delta[i, j] >= 0 prob += A[i, j] - ubound * delta[i, j] <= 0 # Ah constraints prob += Ah[i, j] >= 0 prob += Ah[i, j] - eps * delta[i, j] >= 0 prob += Ah[i, j] - ubound * delta[i, j] <= 0 # Diagonal entries of A, Ah are non-positive for j in col_range: prob += A[j, j] <= 0 prob += Ah[j, j] <= 0 status = prob.solve(solver=CPLEX()) #print(prob) # Problem successfully solved, report results if status == 1: # Get solutions to problem Tsol = np.zeros((n, n)) Asol = np.zeros((m, m)) for i in col_range: for j in col_range: Asol[i - 1, j - 1] = value(A[i, j]) for i in row_range: Tsol[i - 1, i - 1] = value(T[i]) print("\nA =\n", Asol) print("\nT =\n", Tsol) else: print("No solution found")
def get_expected_revenue(revman): return pulp.value(revman.objective)
stat = prob.solve(PULP_CBC_CMD(msg=0)) if (stat == 1): for v in prob.variables(): if (v.varValue != 0): craftedItems[v.name] += v.varValue Materials["Cloth"] -= math.ceil(clothCost[v.name] * v.varValue * (1 - RRR[Focus])) Materials["Metal"] -= math.ceil(metalCost[v.name] * v.varValue * (1 - RRR[Focus])) Materials["Wood"] -= math.ceil(woodCost[v.name] * v.varValue * (1 - RRR[Focus])) Materials["Leather"] -= math.ceil( leatherCost[v.name] * v.varValue * (1 - RRR[Focus])) totalFame += value(prob.objective) generatedFame = value(prob.objective) else: generatedFame = 0 print("Total fame generated = ", totalFame) if Type == "A": fameTree = {"Imbuer": 0, "Blacksmith": 0, "Fletcher": 0} for v in craftedItems: if (craftedItems[v] != 0): fameTree[itemTree[v]] += craftedItems[v] * FameGenerated[Tier][ itemType[v]] for t in fameTree:
s_p = 2 l_p = 7 # contribution of each product v_s = 2 v_l = 3 m_s = 10 m_l = 50 # target v_t = 120 m_t = 880 # count variables (solido_count and liquidex_count) s_c = pulp.LpVariable("s_c", 0, 1000, 'Integer') l_c = pulp.LpVariable("l_c", 1, 1000, 'Integer') # Contraints problem += s_c * v_s + l_c * v_l >= v_t problem += s_c * m_s + l_c * m_l >= m_t # Objective (total price) problem += s_c * s_p + l_c * l_p print(problem) problem.solve() print('Solido: ', pulp.value(s_c)) print('Liquidex:', pulp.value(l_c))
'''Defining variables''' #Integer var_name = plp.LpVariable.dicts('Name', ((i) for i in iterator), upBound = None, lowBound = None, cat = plp.LpInteger) #dictionary of variables var_name = plp.LpVariable('Name', upBound = None, lowBound = None, cat = plp.LpInteger) #single varible #Binary var_name = plp.LpVariable.dicts('Name', ((i) for i in iterator), cat = plp.LpBinary) #dictionary of variables var_name = plp.LpVariable('Name', cat = plp.LpBiary) #single varible '''Defining constraints''' cons = {i: model.addConstraint(plp.LpConstraint(e = var_name, sense = plp.LpConstraintGE. rhs = 0, name = 'Name_'+i)) for i in iterator} #Greater than cons = {i: model.addConstraint(plp.LpConstraint(e = var_name, sense = plp.LpConstraintLE. rhs = 0, name = 'Name_'+i)) for i in iterator} #Less than '''Objective''' model += plp.lpSum(var_name[i] for i in iterator) '''Priniting the model''' print (model) '''Solving''' model.solve(solver) '''Printing problem status''' print (plp.LpStatus[model.status]) '''Printing variables''' for i in model.variables(): print (str(i.name) + '=' + str(i.varValue)) '''Printing Objective''' print (plp.value(model.objective))
# 各项用时约束 for i in range(nb_logs): problem += day[i] * log_info[i, 0] <= total_time/4 * (1 - sleeping/24/60) problem += night[i] * night_info[i, 0] <= total_time/4 * (sleeping/24/60) if sleeping > 0: problem += day[i] <= np.floor((24 * 60 - sleeping)/log_info[i, 0]) * total_full_day problem += night[i] <= total_full_day if sleeping > 0: problem += lp.lpSum(night) >= total_full_day * 4 solved = problem.solve() if solved != 1: print({-1: '目标定的太大啦,臣妾做不到啊', -2: '资源太多啦,这辈子也用不完啊'}[solved]) exit(-2) total = lp.value(total_full_day) print('天数:%.1f\n' % total) chosen_list = [] total += 0.001 if total == 0 else 0 for i in range(nb_logs): d, n = lp.value(day[i]) / total, lp.value(night[i]) / total d = d > 0.01 and d or 0 n = n > 0.01 and n or 0 if d > 0 or n > 0: # chosen_list.append({'mission': LogInfo[i][0], 'day': d, 'night': n}) chosen_list.append({'mission': LogInfo[i][0], 'day': d*log_info[i][0]/60, 'night': n*night_info[i][0]/60}) lines = ['关卡', '白天', '晚上'] for i in chosen_list: lines[0] += '\t%7s' % i['mission']
def solve(self, **kwargs): solver_name = kwargs.get("solver", "cplex").lower() timelimit = int(kwargs.get("timelimit", "3600")) _log.info(f"called solve with the following parameters: {kwargs}") # UB on the number of instances of a certain type instances_UB = { vm_type: self._get_ub(vm_type) for vm_type in self.physical.vm_options } # instances on which a virtual node u may be placed feasible_instances = { u: self._get_feasible_instances(u) for u in self.virtual.nodes() } vm_used = pulp.LpVariable.dicts( "vm_used", ((vm_type, vm_id) for vm_type in self.physical.vm_options for vm_id in range(instances_UB[vm_type])), cat=pulp.LpBinary, ) node_mapping = pulp.LpVariable.dicts( "node_mapping", ((u, vm_type, vm_id) for u in self.virtual.nodes() for vm_type in feasible_instances[u] for vm_id in range(instances_UB[vm_type])), cat=pulp.LpBinary, ) # problem definition mapping_ILP = pulp.LpProblem("Packing ILP", pulp.LpMinimize) # objective function mapping_ILP += pulp.lpSum( (self.physical.hourly_cost(vm_type) * vm_used[(vm_type, vm_id)] for (vm_type, vm_id) in vm_used)) # Assignment of a virtual node to an EC2 instance for u in self.virtual.nodes(): mapping_ILP += ( pulp.lpSum((node_mapping[(u, vm_type, vm_id)] for vm_type in feasible_instances[u] for vm_id in range(instances_UB[vm_type]))) == 1, f"assignment of node {u}", ) for (vm_type, vm_id) in vm_used: # CPU cores capacity constraints mapping_ILP += ( pulp.lpSum((self.virtual.req_cores(u) * node_mapping[(u, vm_type, vm_id)] for u in self.virtual.nodes() if vm_type in feasible_instances[u])) <= self.physical.cores(vm_type) * vm_used[vm_type, vm_id], f"core capacity of instance {vm_type, vm_id}", ) # memory capacity constraints mapping_ILP += ( pulp.lpSum((self.virtual.req_memory(u) * node_mapping[(u, vm_type, vm_id)] for u in self.virtual.nodes() if vm_type in feasible_instances[u])) <= self.physical.memory(vm_type) * vm_used[vm_type, vm_id], f"memory capacity of instance {vm_type, vm_id}", ) solver = self._get_solver(solver_name, timelimit) mapping_ILP.setSolver(solver) # solve the ILP status = pulp.LpStatus[mapping_ILP.solve()] obj_value = pulp.value(mapping_ILP.objective) if status == "Infeasible": self.status = Infeasible return Infeasible elif (status == "Not Solved" or status == "Undefined") and (not obj_value or sum( round(node_mapping[(u, vm_type, vm_id)].varValue) for (u, vm_type, vm_id) in node_mapping) != self.virtual.number_of_nodes()): self.status = NotSolved return NotSolved if solver_name == "cplex": self.current_val = round( solver.solverModel.solution.MIP.get_best_objective(), 2) elif solver_name == "gurobi": self.current_val = round(mapping_ILP.solverModel.ObjBound, 2) else: self.current_val = 0 assignment_ec2_instances = self.build_ILP_solution(node_mapping) self.solution = Solution.build_solution(self.virtual, self.physical, assignment_ec2_instances) self.status = Solved return Solved
def V2G_optimization(): # initiate the problem statement model = lp.LpProblem('Minimize_Distribution_level_Peak_Valley_Difference', lp.LpMinimize) #define optimization variables veh_V2G = range(n_V2G_Veh) time_Interval = range(24) chargeprofiles = lp.LpVariable.dicts('charging_profiles', ((i, j) for i in veh_V2G for j in time_Interval), lowBound=0, upBound=power_managed_Uppper) chargestates = lp.LpVariable.dicts('charging_states', ((i, j) for i in veh_V2G for j in time_Interval), cat='Binary') dischargeprofiles = lp.LpVariable.dicts('discharging_profiles', ((i, j) for i in veh_V2G for j in time_Interval), lowBound=power_V2G_Lower, upBound=0) dischargestates = lp.LpVariable.dicts('discharging_states', ((i, j) for i in veh_V2G for j in time_Interval), cat='Binary') total_load = lp.LpVariable.dicts('total_load', time_Interval, lowBound=0) max_load = lp.LpVariable('max_load', lowBound=0) min_load = lp.LpVariable('min_load', lowBound=0) # define objective function #model += max_load - min_load model += max_load # define constraints for t in time_Interval: # constraint 1 & 2: to identify the max and min loads model += total_load[t] <= max_load #model += total_load[t] >= min_load for t in time_Interval: # constraint 3: calculate the total load at each time interval t model += lp.lpSum([chargeprofiles[i, t]] for i in veh_V2G) + lp.lpSum([ dischargeprofiles[i, t] * discharge_efficiency for i in veh_V2G ]) + base_Load[t] + unmanaged_Load[t] == total_load[ t] #need to plus base loads for i in veh_V2G: # constraint 4: constraint on charging powers for each EV: only optimize the charge profile between start and end charging time temp_start = v2g_startingTime[i] temp_end = v2g_endingTime[i] if temp_start >= temp_end: for t in range(temp_end): model += chargestates[i, t] + dischargestates[i, t] <= 1 model += chargeprofiles[ i, t] <= chargestates[i, t] * power_managed_Uppper model += chargeprofiles[ i, t] >= chargestates[i, t] * power_managed_Lower model += dischargeprofiles[ i, t] <= dischargestates[i, t] * power_V2G_Upper model += dischargeprofiles[ i, t] >= dischargestates[i, t] * power_V2G_Lower for t in range(temp_end, temp_start, 1): model += chargeprofiles[i, t] == 0 model += chargestates[i, t] == 0 model += dischargeprofiles[i, t] == 0 model += dischargestates[i, t] == 0 for t in range(temp_start, 24, 1): model += chargestates[i, t] + dischargestates[i, t] <= 1 model += chargeprofiles[ i, t] <= chargestates[i, t] * power_managed_Uppper model += chargeprofiles[ i, t] >= chargestates[i, t] * power_managed_Lower model += dischargeprofiles[ i, t] <= dischargestates[i, t] * power_V2G_Upper model += dischargeprofiles[ i, t] >= dischargestates[i, t] * power_V2G_Lower if temp_start < temp_end: for t in range(temp_start): model += chargeprofiles[i, t] == 0 model += chargestates[i, t] == 0 model += dischargeprofiles[i, t] == 0 model += dischargestates[i, t] == 0 for t in range(temp_start, temp_end, 1): model += chargestates[i, t] + dischargestates[i, t] <= 1 model += chargeprofiles[ i, t] <= chargestates[i, t] * power_managed_Uppper model += chargeprofiles[ i, t] >= chargestates[i, t] * power_managed_Lower model += dischargeprofiles[ i, t] <= dischargestates[i, t] * power_V2G_Upper model += dischargeprofiles[ i, t] >= dischargestates[i, t] * power_V2G_Lower for t in range(temp_end, 24, 1): model += chargeprofiles[i, t] == 0 model += chargestates[i, t] == 0 model += dischargeprofiles[i, t] == 0 model += dischargestates[i, t] == 0 for i in veh_V2G: # constraint 5: SOC constraint, cannot be greater than 1, end_SOC must be above certain levels temp_start = v2g_startingTime[i] temp_end = v2g_endingTime[i] temp_startSOC = v2g_startingSOC[i] if temp_start >= temp_end: for t in range(temp_start + 1, 24, 1): temp_timer = range(temp_start, t, 1) model += temp_startSOC + lp.lpSum( [chargeprofiles[i,tn] * charge_efficiency/batteryCapacity] for tn in temp_timer) \ + lp.lpSum( [dischargeprofiles[i,tn] *(1/batteryCapacity)] for tn in temp_timer) <=1 #need to divide 4! for t in range(0, temp_end + 1, 1): temp_timer = range(0, t, 1) model += temp_startSOC + lp.lpSum( [chargeprofiles[i,tn] * charge_efficiency/batteryCapacity] for tn in range(temp_start, 24,1)) + lp.lpSum( [chargeprofiles[i,tn] * charge_efficiency/batteryCapacity] for tn in temp_timer) \ + lp.lpSum( [dischargeprofiles[i,tn] *(1/ batteryCapacity)] for tn in range(temp_start, 24,1)) + lp.lpSum( [dischargeprofiles[i,tn] *(1/batteryCapacity)] for tn in temp_timer) <=1 #need to divide 4 #if end_SOC == 1: # incrementSOC=v2g_distance[i]/batteryRange # model += lp.lpSum([chargeprofiles[i, tn] * charge_efficiency / batteryCapacity] for tn in range(temp_start, 24, 1)) + lp.lpSum([chargeprofiles[i, tn] * charge_efficiency / batteryCapacity] for tn in temp_timer) \ # + lp.lpSum([dischargeprofiles[i, tn] *(1/ batteryCapacity)] for tn in range(temp_start, 24, 1)) + lp.lpSum([dischargeprofiles[i, tn] *(1/ batteryCapacity)] for tn in temp_timer) >= incrementSOC # need to divide 4 if end_SOC == 2: model += temp_startSOC + lp.lpSum([chargeprofiles[i, tn] * charge_efficiency / batteryCapacity] for tn in range(temp_start, 24, 1)) + lp.lpSum([chargeprofiles[i, tn] * charge_efficiency / batteryCapacity] for tn in temp_timer) \ + lp.lpSum([dischargeprofiles[i, tn] *(1/ batteryCapacity)] for tn in range(temp_start, 24, 1)) + lp.lpSum([dischargeprofiles[i, tn] *(1/ batteryCapacity)] for tn in temp_timer) ==1 if temp_start < temp_end: for t in range(temp_start + 1, temp_end + 1, 1): temp_timer = range(temp_start, t, 1) model += temp_startSOC + lp.lpSum( [chargeprofiles[i,tn] * charge_efficiency/batteryCapacity] for tn in temp_timer) \ + lp.lpSum( [dischargeprofiles[i,tn] *(1/batteryCapacity)] for tn in temp_timer) <=1 #need to divide by 4 #if end_SOC == 1: # incrementSOC=v2g_distance[i]/batteryRange # model += lp.lpSum( [chargeprofiles[i,tn] * charge_efficiency/batteryCapacity] for tn in temp_timer)\ # +lp.lpSum( [dischargeprofiles[i,tn] *(1/batteryCapacity)] for tn in temp_timer) >= incrementSOC # need to divide 4 if end_SOC == 2: model += temp_startSOC + lp.lpSum([chargeprofiles[i, tn] * charge_efficiency / batteryCapacity] for tn in range(temp_start, 24, 1)) + lp.lpSum([chargeprofiles[i, tn] * charge_efficiency / batteryCapacity] for tn in temp_timer)\ + lp.lpSum([dischargeprofiles[i, tn] *(1/batteryCapacity)] for tn in range(temp_start, 24, 1)) + lp.lpSum([dischargeprofiles[i, tn] *(1/batteryCapacity)] for tn in temp_timer)==1 #print(model) #status=model.solve(lp.COIN(maxSeconds=2500)) status = model.solve() print(lp.LpStatus[status]) print(lp.value(max_load)) return chargeprofiles, dischargeprofiles, total_load
def SolveWithReluxation(self, game_type, league='ps', timeLimit=None, solverName=None, threads=1, option=[], initialPosition=None, initialSolution=False): """ This is a function to solve 0-1 integer problem which aim to compute suchedule with minimized distance. Parameters ---------- game_type : str The type of played game. Regular Game before inter game : 'r_pre' Regular Game after inter game : 'r_post' Inter league : 'i' league : str League name Pacific league : 'p' Central league : 's' timeLimit : int Time limit for solver in seconds. solverName : int Solver's name you use 0 : CBC 1 : CPLEX threads : int Threads for solver(default : 1) options : list Options for solver (default : []) initialPosition : list Initial position of every team (default : None) initialSolution : bool If true, start with initial value Returns ------- status : int Status of solved problem 1 : Optimal 0 : Not solved -1 : Infeasible -2 : Unbounded -3 : Undefined objective : int Objective value of solved problem v : list Solution of this problem. """ # 定数 if game_type == 'i': I = self.K else: I = self.Teams[league] S = self.S[game_type] D = self.D total_game = self.total_game[game_type] # 問題の宣言 problem = pulp.LpProblem('scheduling', pulp.LpMinimize) # 変数の生成 v = pulp.LpVariable.dicts('v', (S, I, I), 0, 1, 'Integer') e = pulp.LpVariable.dicts('e', (S, I, I, I), 0, 1, 'Integer') penal1 = pulp.LpVariable.dicts('p1', (I, I), lowBound=0) penal2 = pulp.LpVariable.dicts('p2', (S, I), lowBound=0) penal3 = pulp.LpVariable.dicts('p2', (S, I, I), lowBound=0) # 目的関数の設定 obj = pulp.lpSum([ D[j][k] * e[s][i][j][k] for i in I for j in I for k in I for s in S ]) obj += 100 * ( pulp.lpSum([penal1[i][j] for i in I for j in I]) + pulp.lpSum([penal2[s][i] for s in S for i in I]) + pulp.lpSum([penal3[s][i][j] for s in S for i in I for j in I])) if initialPosition: for i in I: obj += pulp.lpSum( [D[initialPosition[i]][j] * v[0][i][j] for j in I]) problem += obj # 制約式を入れる """制約4,6,8を緩和させる """ for i in I: for j in I: for k in I: for s in S[1:]: # e[s][i][j][k]が定義を満たすように制約を入れる problem += 1 - v[ s - 1][i][j] - v[s][i][k] + e[s][i][j][k] >= 0 problem += v[s - 1][i][j] - e[s][i][j][k] >= 0 problem += v[s][i][k] - e[s][i][j][k] >= 0 for s in S: for i in I: # 垂直に足して見てね!パワポの制約⑦ problem += pulp.lpSum([v[s][j][i] for j in I]) <= 2 for i in I: J = list(set(I) - {i}) for s in S: # v[s][i][i]の決め方。パワポで言う制約① problem += v[s][i][i] - pulp.lpSum([v[s][j][i] for j in J]) == 0 for i in I: J = list(set(I) - {i}) # 総試合数に関する制約。パワポで言う制約② problem += pulp.lpSum([v[s][i][j] for j in I for s in S]) == total_game # ホームゲームとビジターゲームの試合数を揃える。パワポで言う制約③ problem += (pulp.lpSum([v[s][i][j] for s in S for j in J]) - pulp.lpSum([v[s][i][i] for s in S]) == 0) for s in S: for i in I: # 1日必ず1試合する。パワポで言う制約⑤ problem += pulp.lpSum([v[s][i][j] for j in I]) == 1 for i in I: for j in I: # 各対戦カードにおけるホームとビジターの試合数をなるべく揃える。パワポで言う制約④ if i != j: problem += pulp.lpSum( [v[s][i][j] for s in S]) - pulp.lpSum( [v[s][j][i] for s in S]) + penal1[i][j] + penal1[j][i] <= 1 problem += pulp.lpSum( [v[s][i][j] for s in S]) - pulp.lpSum( [v[s][j][i] for s in S]) + penal1[i][j] + penal1[j][i] >= -1 problem += pulp.lpSum( [v[s][i][j] for s in S]) + penal1[i][j] <= self.ub[game_type] problem += pulp.lpSum( [v[s][i][j] for s in S]) + penal1[i][j] >= self.lb[game_type] for s in S[:-2]: for i in I: for j in I: # 連戦はしない。パワポで言う制約⑥ if i != j: problem += pulp.lpSum( [v[t][i][j] + v[t][j][i] for t in range(s, s + 3)]) + penal3[s][i][j] <= 1 for s in S[:-2]: for i in I: # ホームは連続二連ちゃんまで!パワポの制約⑧ problem += pulp.lpSum([v[t][i][i] for t in range(s, s + 3) ]) + penal2[s][i] <= 2 if game_type == 'i': L = self.Teams['p'] J = self.Teams['s'] for s in S: for i in L: # 自分のリーグに属するチームとは試合を行わないと言う制約。パワポの制約⑨ for j in L: if i != j: problem += v[s][i][j] == 0 # もう一方のリーグのチームと一回ずつ試合をするという制約。パワポの制約11 for j in J: problem += v[s][i][j] <= ( 1 - pulp.lpSum([v[t][j][i] for t in range(s)])) for i in J: # 自分のリーグに属するチームとは試合を行わないと言う制約。パワポの制約⑨ for j in J: if i != j: problem += v[s][i][j] == 0 # もう一方のリーグのチームと一回ずつ試合をするという制約。パワポの制約11 for j in L: problem += v[s][i][j] <= ( 1 - pulp.lpSum([v[t][j][i] for t in range(s)])) # ビジターで試合をしている時はホームで試合をしてはいけない。パワポの制約⑩ # v[s][i][i]=1かv[s][i][j]=1の何か一方が成立する for s in S: for i in L: problem += v[s][i][i] + pulp.lpSum([v[s][i][j] for j in J]) <= 1 for j in J: problem += v[s][j][j] + pulp.lpSum([v[s][j][i] for i in L]) <= 1 if initialSolution: v_initial = utils.Load(game_type + "_" + league + '.pkl') for s in S: for i in I: for j in I: v[s][i][j].setInitialValue(v_initial[s][i][j].value()) # solverの設定 # デフォルトは cbc solver if solverName == 0: solver = pulp.PULP_CBC_CMD(msg=1, threads=threads, options=option, maxSeconds=timeLimit, warmStart=True) elif solverName == 1: solver = pulp.CPLEX_CMD(msg=1, timeLimit=timeLimit, options=option, threads=threads, warmStart=True) status = problem.solve(solver) return status, pulp.value(problem.objective), v
def result(self): """ Using Word Mover's Distance algorithm and the pre-trained word vector to calculate similarity scores :return: the similarity score of target text and comparable texts in text list """ def tokens_to_fracdict(tokens): """ Decompose sentences to tokens :param tokens: a list of tokens to handle :return: a dictionary of {token: frequency of token} """ cntdict = defaultdict(lambda: 0) for token in tokens: cntdict[token] += 1 totalcnt = sum(cntdict.values()) return { token: float(cnt) / totalcnt for token, cnt in cntdict.items() } def word_mover_distance_probspec(first_sent_tokens, second_sent_tokens, wvmodel, lpFile=None): """ apply Word Mover's Distance algorithm :param first_sent_tokens: target text :param second_sent_tokens: comparable text (each text in the text list) :param wvmodel: the pre-trained word vector model :param lpFile: a file to store the result :return: a pulp LpProblem (will yield the result in the last part of <result> function) """ all_tokens = list(set(first_sent_tokens + second_sent_tokens)) wordvecs = {} for token in all_tokens: try: wordvecs[token] = wvmodel[token] except: wordvecs[token] = 0 first_sent_buckets = tokens_to_fracdict(first_sent_tokens) second_sent_buckets = tokens_to_fracdict(second_sent_tokens) T = pulp.LpVariable.dicts('T_matrix', list(product(all_tokens, all_tokens)), lowBound=0) prob = pulp.LpProblem('WMD', sense=pulp.LpMinimize) prob += pulp.lpSum([ T[token1, token2] * euclidean(wordvecs[token1], wordvecs[token2]) for token1, token2 in product(all_tokens, all_tokens) ]) for token2 in second_sent_buckets: prob += pulp.lpSum([ T[token1, token2] for token1 in first_sent_buckets ]) == second_sent_buckets[token2] for token1 in first_sent_buckets: prob += pulp.lpSum([ T[token1, token2] for token2 in second_sent_buckets ]) == first_sent_buckets[token1] if lpFile != None: prob.writeLP(lpFile) prob.solve() return prob def normalize(text): """ remove punctuation, lowercase, stem :param text: :return: a list of normalized words """ stop_words = set(stopwords.words('english')) - set( ['no', 'not', 'nor']) # drop 'no', 'not', and 'nor' remove_punctuation_map = dict( (ord(char), None) for char in string.punctuation) res = nltk.word_tokenize( text.lower().translate(remove_punctuation_map)) return [w for w in res if w not in stop_words] res = [] for i in range(0, len(self.text_list)): prob = word_mover_distance_probspec(normalize(self.target_text), normalize(self.text_list[i]), self.w2v_model) res.append(1 - pulp.value(prob.objective) / 5) return res # the similarity score based on Word Mover's Distance algorithm
vs = {} for (i, j) in keys: name = "W_%d_%d" % (i, j) names[i, j] = name var = LpVariable(name) vs[i, j] = var system += var >= 1.0 for i, row in enumerate(rows): expr = 0 for j, key in enumerate(keys): value = row.get(key, 0) expr += value * vs[key] #print(expr) system += expr == 0.0 #system += vs[3, 1] >= vs[2, 2] # Infeasible at N=9 #system += vs[5, 1] >= vs[4, 2] # Infeasible at N=25 system += vs[4, 2] >= vs[3, 3] # Infeasible at N=64 status = system.solve() s = LpStatus[status] print("pulp:", s) if s == "Infeasible": return if 0: for key in keys: v = vs[key] print(v, "=", value(v))
#condition 1 for i in range(0, num_courses): sum_xi=0 for j in range(0, num_classes): sum_xi+= x[i][j] lp_prob += sum_xi ==1 #condition 2 for j in range(0, num_classes): sum_xj=0 for i in range(0, num_courses): sum_xj+= x[i][j] lp_prob += sum_xj <=1 #condition 3 sum_T=0; for i in range(0, num_courses): for j in range(0, num_classes): if(course_cap[i]>class_cap[j]): sum_T += x[i][j] lp_prob += sum_T ==0 #solve problem lp_prob.solve() #print resutls for v in lp_prob.variables(): print(v.name, "=", v.varValue) print("Total Cost =", math.ceil(pulp.value(lp_prob.objective)))
prob=pulp.LpProblem("The Diet Problem", pulp.LpMinimize) #create a dictionary to store problem variables lp_foods=pulp.LpVariable.dicts("Food",food_dict.keys(),0) #create the objective function prob += pulp.lpSum([food_dict[key]['Cholesterol']*lp_foods[key] for key in food_dict.keys()]), "Total Cost of Foods per person" #add constraints to problem #prob += pulp.lpSum([food_dict[key][]*lp_foods[key] for key in food_dict.keys()])<= , "" #prob += pulp.lpSum([food_dict[key][]*lp_foods[key] for key in food_dict.keys()]) >= , "" for (idx, row) in df_constraints_t.iterrows(): print(row.loc[1]) #prob += pulp.lpSum([food_dict[key][idx+1]*lp_foods[key] for key in food_dict.keys()])<= row.loc[1], "" #prob += pulp.lpSum([food_dict[key][idx+1]*lp_foods[key] for key in food_dict.keys()]) >=row.loc[0] , "" #export to lp file prob.writeLP("diet_model_pt3.lp") pulp.LpSolverDefault.msg = 1 prob.solve() #print status of the problem, each foods optimum value, and the total cost print ("Status:", pulp.LpStatus[prob.status]) for v in prob.variables(): if(v.varValue != 0.0): print (v.name, "=", v.varValue) print ("Total Cost of Foods per person = ", pulp.value(prob.objective))
def portfolio_byvalue(weights, steps, min_values, max_values=1e9, total_portfolio_value=10000): """ For a long only portfolio, convert the continuous weights to a discrete allocation using Mixed Integer Linear Programming. This function assumes that we buy some asset based on value instead of shares, and there is a limit of minimum value and increasing step. :param weights: continuous weights generated from the ``efficient_frontier`` module :type weights: dict :param min_values: the minimum value for each asset :type min_values: int/float or dict :param max_values: the maximum value for each asset :type max_values: int/float or dict :param steps: the minimum value increase for each asset :type steps: int/float or dict :param total_portfolio_value: the desired total value of the portfolio, defaults to 10000 :type total_portfolio_value: int/float, optional :raises TypeError: if ``weights`` is not a dict :return: the number of value of each ticker that should be purchased, along with the amount of funds leftover. :rtype: (dict, float) """ import pulp if not isinstance(weights, dict): raise TypeError("weights should be a dictionary of {ticker: weight}") if total_portfolio_value <= 0: raise ValueError("total_portfolio_value must be greater than zero") if isinstance(steps, numbers.Real): steps = {k: steps for k in weights} if isinstance(min_values, numbers.Real): min_values = {k: min_values for k in weights} if isinstance(max_values, numbers.Real): max_values = {k: max_values for k in weights} m = pulp.LpProblem("PfAlloc", pulp.LpMinimize) vals = {} realvals = {} usevals = {} etas = {} abss = {} remaining = pulp.LpVariable("remaining", 0) for k, w in weights.items(): if steps.get(k): vals[k] = pulp.LpVariable("x_%s" % k, 0, cat="Integer") realvals[k] = steps[k] * vals[k] etas[k] = w * total_portfolio_value - realvals[k] else: realvals[k] = vals[k] = pulp.LpVariable("x_%s" % k, 0) etas[k] = w * total_portfolio_value - vals[k] abss[k] = pulp.LpVariable("u_%s" % k, 0) usevals[k] = pulp.LpVariable("b_%s" % k, cat="Binary") m += etas[k] <= abss[k] m += -etas[k] <= abss[k] m += realvals[k] >= usevals[k] * min_values.get(k, steps.get(k, 0)) m += realvals[k] <= usevals[k] * max_values.get(k, 1e18) m += remaining == total_portfolio_value - pulp.lpSum(realvals.values()) m += pulp.lpSum(abss.values()) + remaining m.solve() results = {k: pulp.value(val) for k, val in realvals.items()} return results, remaining.varValue
# import the library pulp as p import pulp as p # Create a LP Minimization problem Lp_prob = p.LpProblem('Problem', p.LpMinimize) # Create problem Variables x = p.LpVariable("x", lowBound=0) # Create a variable x >= 0 y = p.LpVariable("y", lowBound=0) # Create a variable y >= 0 # Objective Function Lp_prob += 3 * x + 5 * y # Constraints: Lp_prob += 2 * x + 3 * y >= 12 Lp_prob += -x + y <= 3 Lp_prob += x >= 4 Lp_prob += y <= 3 # Display the problem print(Lp_prob) status = Lp_prob.solve() # Solver print(p.LpStatus[status]) # The solution status # Printing the final solution print(p.value(x), p.value(y), p.value(Lp_prob.objective))
def score_range_aggregated_rom(p_fov, n_fov, p_diff, n_diff, acc_all, sens_all, spec_all, eps, n_diff_lower, score='acc'): """ Score range reconstruction for aggregated figures with the Ratio-of-Means approach Args: p_fov (np.array): number of positives under the FoV n_fov (np.array): number of negatives under the FoV p_diff (np.array): number of positives outside the FoV n_diff (np.array): number of negatives outside the FoV acc_all (float): accuracy in the entire image sens_all (float): sensitivity in the entire image spec_all (float): specificity in the entire image eps (float): numerical uncertainty n_diff_lower (np.array): the minimum number of negatives outside the FoV score (str): score to compute: 'acc'/'sens'/'spec' Returns: float, float, float: the mid-score, the worst case minimum and best case maximum values """ prob = pl.LpProblem("maximum", pl.LpMaximize) tp_fovs = [ pl.LpVariable("tp_fov" + str(i), 0, p_fov[i], pl.LpInteger) for i in range(len(p_fov)) ] tn_fovs = [ pl.LpVariable("tn_fov" + str(i), 0, n_fov[i], pl.LpInteger) for i in range(len(n_fov)) ] tp_diffs = [ pl.LpVariable("tp_diff" + str(i), 0, p_diff[i], pl.LpInteger) for i in range(len(p_diff)) ] tn_diffs = [ pl.LpVariable("tn_diff" + str(i), n_diff_lower[i], n_diff[i], pl.LpInteger) for i in range(len(n_diff)) ] sens_all_plus = sum([tp_fovs[i] + tp_diffs[i] for i in range(len(p_fov)) ]) * (1.0 / (np.sum(p_fov + p_diff))) spec_all_plus = sum([tn_fovs[i] + tn_diffs[i] for i in range(len(p_fov)) ]) * (1.0 / (np.sum(n_fov + n_diff))) acc_all_plus = sum([ tn_fovs[i] + tn_diffs[i] + tp_fovs[i] + tp_diffs[i] for i in range(len(p_fov)) ]) * (1.0 / (np.sum(n_fov + n_diff + p_fov + p_diff))) sens_all_minus = sum([tp_fovs[i] + tp_diffs[i] for i in range(len(p_fov)) ]) * (-1.0 / (np.sum(p_fov + p_diff))) spec_all_minus = sum([tn_fovs[i] + tn_diffs[i] for i in range(len(p_fov)) ]) * (-1.0 / (np.sum(n_fov + n_diff))) acc_all_minus = sum([ tn_fovs[i] + tn_diffs[i] + tp_fovs[i] + tp_diffs[i] for i in range(len(p_fov)) ]) * (-1.0 / (np.sum(n_fov + n_diff + p_fov + p_diff))) prob += sens_all_plus <= sens_all + eps prob += sens_all_minus <= -(sens_all - eps) prob += spec_all_plus <= spec_all + eps prob += spec_all_minus <= -(spec_all - eps) prob += acc_all_plus <= acc_all + eps prob += acc_all_minus <= -(acc_all - eps) if score == 'acc': prob += sum([tp_fovs[i] + tn_fovs[i] for i in range(len(p_fov)) ]) * (1.0 / np.sum(p_fov + n_fov)) elif score == 'spec': prob += sum([tn_fovs[i] for i in range(len(p_fov))]) * (1.0 / np.sum(n_fov)) elif score == 'sens': prob += sum([tp_fovs[i] for i in range(len(p_fov))]) * (1.0 / np.sum(p_fov)) prob.solve() score_max = pl.value(prob.objective) prob = pl.LpProblem("minimum", pl.LpMinimize) tp_fovs = [ pl.LpVariable("tp_fov" + str(i), 0, p_fov[i], pl.LpInteger) for i in range(len(p_fov)) ] tn_fovs = [ pl.LpVariable("tn_fov" + str(i), 0, n_fov[i], pl.LpInteger) for i in range(len(n_fov)) ] tp_diffs = [ pl.LpVariable("tp_diff" + str(i), 0, p_diff[i], pl.LpInteger) for i in range(len(p_diff)) ] tn_diffs = [ pl.LpVariable("tn_diff" + str(i), n_diff_lower[i], n_diff[i], pl.LpInteger) for i in range(len(n_diff)) ] sens_all_plus = sum([tp_fovs[i] + tp_diffs[i] for i in range(len(p_fov)) ]) * (1.0 / (np.sum(p_fov + p_diff))) spec_all_plus = sum([tn_fovs[i] + tn_diffs[i] for i in range(len(p_fov)) ]) * (1.0 / (np.sum(n_fov + n_diff))) acc_all_plus = sum([ tn_fovs[i] + tn_diffs[i] + tp_fovs[i] + tp_diffs[i] for i in range(len(p_fov)) ]) * (1.0 / (np.sum(n_fov + n_diff + p_fov + p_diff))) sens_all_minus = sum([tp_fovs[i] + tp_diffs[i] for i in range(len(p_fov)) ]) * (-1.0 / (np.sum(p_fov + p_diff))) spec_all_minus = sum([tn_fovs[i] + tn_diffs[i] for i in range(len(p_fov)) ]) * (-1.0 / (np.sum(n_fov + n_diff))) acc_all_minus = sum([ tn_fovs[i] + tn_diffs[i] + tp_fovs[i] + tp_diffs[i] for i in range(len(p_fov)) ]) * (-1.0 / (np.sum(n_fov + n_diff + p_fov + p_diff))) prob += sens_all_plus <= sens_all + eps prob += sens_all_minus <= -(sens_all - eps) prob += spec_all_plus <= spec_all + eps prob += spec_all_minus <= -(spec_all - eps) prob += acc_all_plus <= acc_all + eps prob += acc_all_minus <= -(acc_all - eps) if score == 'acc': prob += sum([tp_fovs[i] + tn_fovs[i] for i in range(len(p_fov)) ]) * (1.0 / np.sum(p_fov + n_fov)) elif score == 'spec': prob += sum([tn_fovs[i] for i in range(len(p_fov))]) * (1.0 / np.sum(n_fov)) elif score == 'sens': prob += sum([tp_fovs[i] for i in range(len(p_fov))]) * (1.0 / np.sum(p_fov)) prob.solve() score_min = pl.value(prob.objective) return (score_min + score_max) / 2.0, score_min, score_max
def ilp_redundant_multicast(topology, source, destinations, k=2, get_lower_bound=False): # ENHANCE: use_multicommodity_flow=False, """Uses pulp and our ILP formulation to create k redundant multicast trees from the source to all the destinations on the given topology. NOTE: this assumes nodes in the topology are represented as strings! :param get_lower_bound: if True, simply returns the lower bound of the overlap for k trees as computed by the relaxation """ relaxed = get_lower_bound var_type = pulp.LpContinuous if relaxed else pulp.LpBinary # Extract strings to work with pulp more easily # edges = [edge_to_str(e) for e in topology.edges()] edges = list(topology.edges()) vertices = [str(v) for v in topology.nodes()] multicast_trees = ["T%d" % i for i in range(k)] # First, convert topology and parameters into variables # To construct the multicast trees, we need TE variables that determine # if edge e is used for tree t edge_selection = pulp.LpVariable.dicts("Edge", (edges, multicast_trees), 0, 1, var_type) # OBJECTIVE FUNTION: sums # shared edges pair-wise betweend all redundant trees # That is, the total cost is sum_{links}{shared^2} where shared = # trees sharing this link # To linearize the objective function, we need to generate ET^2 variables # that count the overlap of the trees for a given edge # NOTE: since the pair-wise selection of the trees is symmetrical, # we only look at the lower diagonal half of the 'matrix' to reduce # variables pairwise_edge_tree_choices = [(e, t1, t2) for e in edges for t1 in multicast_trees for t2 in multicast_trees if t2 <= t1] # print "\n".join([str(a) for a in pairwise_edge_tree_choices]) overlap_costs = dict() for e, t1, t2 in pairwise_edge_tree_choices: overlap_costs.setdefault(e, dict()).setdefault(t1, dict())[t2] = \ pulp.LpVariable("Overlap_%s,%s_%s_%s" % (e[0], e[1], t1, t2), 0, 1, var_type) # To ensure each destination is reached by all the multicast trees, # we need a variable to determine if an edge is being used on the path # to a particular destination for a particular tree. # NOTE: this edge-based variable is DIRECTED despite the path being undirected # it means that a unit of flow is selected from u to v _flipped_edges = zip(*reversed(zip(*edges))) _flipped_edges.extend(edges) _sources, _dests = zip(*_flipped_edges) path_selection = pulp.LpVariable.dicts( "Path", (_sources, _dests, destinations, multicast_trees), 0, 1, var_type) # TODO: set the starting values of some variables (destination flows and edges?) # using var.setInitialValue problem = pulp.LpProblem("Redundant Multicast Topology", pulp.LpMinimize) # OBJECTIVE FUNTION: # Since we're only computing the lower-half diagonal of this, we need to double the proper lower half problem += pulp.lpSum([overlap_costs[e][t][t] for e in edges for t in multicast_trees]) + \ 2 * pulp.lpSum([overlap_costs[e][t1][t2] for e, t1, t2 in pairwise_edge_tree_choices if t1 != t2]),\ "Pair-wise overlap among trees" # CONSTRAINTS: # These ~1.5*E*T^2 constraints help linearize the overlap_costs components of the objective function. # It counts the lower-diagonal overlap, multiplying the resulting sum by 2, and adding the sum over diagonal for e, t1, t2 in pairwise_edge_tree_choices: # This ensures the overlap is 0 if the edge not selected by a tree problem += overlap_costs[e][t1][t2] <= edge_selection[e][t1],\ "OverlapRequirement1_%s_%s_%s" % (e, t1, t2) # LOWER DIAGONAL MATRIX FORMULATION: same as above constraint for t2 if t1 != t2: problem += overlap_costs[e][t1][t2] <= edge_selection[e][t2],\ "OverlapRequirement2_%s_%s_%s" % (e, t1, t2) # FULL MATRIX FORMULATION: # Since we have an undirected graph and are counting the overlap 'twice', # simply ensure the overlap matrix is mirrored # problem += overlap_costs[e][t1][t2] == overlap_costs[e][t2][t1], \ # This ensures the cost is 1 if overlap problem += overlap_costs[e][t1][t2] >= edge_selection[e][t1] + edge_selection[e][t2] - 1,\ "OverlapRequirement3_%s_%s_%s" % (e, t1, t2) # These 3 flow constraints ensure each destination has a path to it on each tree, # i.e. each multicast tree covers the terminals. # NOTE: we have an undirected graph but the flow constraints are directed for t in multicast_trees: for d in destinations: # First, the source and destination should have 1 total unit # of outgoing and incoming flow, respectively problem += pulp.lpSum([path_selection[source][v][d][t] for v in topology.neighbors(source)]) == 1,\ "SourceFlowRequirement_%s_%s" % (t, d) problem += pulp.lpSum([path_selection[v][d][d][t] for v in topology.neighbors(d)]) == 1,\ "DestinationFlowRequirement_%s_%s" % (t, d) # Then, every other 'interior' vertex should have a balanced in and out flow. # Really, both should be either 0 or 1 each for v in vertices: if v == d or v == source: continue problem += pulp.lpSum([path_selection[u][v][d][t] for u in topology.neighbors(v) if u != v]) ==\ pulp.lpSum([path_selection[v][u][d][t] for u in topology.neighbors(v) if u != v]),\ "InteriorFlowRequirement_%s_%s_%s" % (t, d, v) # This constraint simply ensures an edge counts as selected on a tree # when it has been selected for a path to a destination along that tree # in order to satisfy the flow constraints. # NOTE: if the edge is path-selected in either direction, it counts as selected for the tree # NOTE: this constraint implies that we cannot have path_selection[u][v][d][t] = 1 = path_selection[v][u][d][t] for e in edges: for t in multicast_trees: for d in destinations: u, v = e # problem += path_selection[e][d][t] <= edge_selection[e][t],\ problem += path_selection[u][v][d][t] + path_selection[v][u][d][t] <= edge_selection[e][t],\ "EdgeSelectionRequirement_%s_%s_%s" % (e,d,t) # Now we can solve the problem problem.solve() log.info("#Variables: %d" % len(problem.variables())) log.info("#Constraints: %d" % len(problem.constraints)) log.info("Status: %s" % pulp.LpStatus[problem.status]) cost = pulp.value(problem.objective) log.info("Cost: %f" % cost) # should be 7 for C(4) + 2 graph with 1 dest if get_lower_bound: return cost else: # Lastly, construct multicast trees from the edge_selection variables and return the results # We use subgraph in order to ensure the attributes remain final_trees = [] for t in multicast_trees: res = topology.edge_subgraph(e for e in edges if edge_selection[e][t].value()) final_trees.append(res) assert nx.is_tree(res) and all( nx.has_path(res, source, d) for d in destinations) return final_trees
#2.6 ensures vehicle capacity not exceeded for i in range(len(locations)): prob += demands[i] <= y[i] <= Q,"" prob += y[i] >= demands[i],"" print("Begin solver: ", time.time()-start_clock) # The problem is solved using PuLP's choice of Solver prob.solve() # The status of the solution is printed to the screen print("Status:", pulp.LpStatus[prob.status]) print("Time elapsed (s): ", time.time() - start_clock) print("Time elapsed (min): ",(time.time() - start_clock)/60) #print routes generated fig = plt.figure() ax = fig.add_subplot(111) ax.scatter([i[0] for i in locations],[j[1] for j in locations]) for i in range(0,len(locations)): for j in range(0, len(locations)): if pulp.value(x[i][j]) == 1: print(i, " - ", j) ax.plot((locations[i][0], locations[j][0]), (locations[i][1], locations[j][1]), 'ro-') ''' stuff happening wrong between 10 and 2 ''' for i in range(len(locations)): print(i,": ",pulp.value(y[i]))
def lp_solve(self, weight_of_corner=1, weight_of_sym=0, sym_pairs=None): # # alert: pulp will automatically transfer node's name into str and replace some special # chars into '_', and will throw a error if there are variables' name duplicated. # import pulp prob = pulp.LpProblem() # minimize var_dict = coll.defaultdict(lambda: coll.defaultdict(dict)) for u, v, he_id in self.flow_network.edges: var_dict[u][v][he_id] = pulp.LpVariable( f'{u}%{v}%{he_id}', self.flow_network[u][v][he_id]['lowerbound'], self.flow_network[u][v][he_id]['capacity'], pulp.LpInteger) objs = [] for he in self.planar.dcel.half_edge_dict.values(): lf, rf = he.twin.inc.id, he.inc.id objs.append(self.flow_network[lf][rf][he.id]['weight'] * var_dict[lf][rf][he.id]) # bend points' cost if weight_of_corner != 0: for v in self.planar.G: if self.planar.G.degree(v) == 2: (f1, he1_id), (f2, he2_id) = [ (f, key) for f, keys in self.flow_network.adj[v].items() for key in keys ] x = var_dict[v][f1][he1_id] y = var_dict[v][f2][he2_id] p = pulp.LpVariable(x.name + "%temp", None, None, pulp.LpInteger) prob.addConstraint(x - y <= p) prob.addConstraint(y - x <= p) objs.append(weight_of_corner * p) # non symmetric cost if weight_of_sym != 0: if sym_pairs: for u, v in sym_pairs: if u != v: faces1 = { face.id for face in self.planar.dcel.vertex_dict[u].surround_faces() } faces2 = { face.id for face in self.planar.dcel.vertex_dict[v].surround_faces() } for f in faces1 & faces2: nodes_id = self.planar.dcel.face_dict[f].nodes_id n = len(nodes_id) u_succ = nodes_id[(nodes_id.index(u) + 1) % n] v_succ = nodes_id[(nodes_id.index(v) + 1) % n] he_u = self.planar.dcel.half_edge_dict[u, u_succ] he_v = self.planar.dcel.half_edge_dict[v, v_succ] x, y = var_dict[u][f][he_u.id], var_dict[v][f][ he_v.id] p = pulp.LpVariable(x.name + y.name + "%temp", None, None, pulp.LpInteger) prob.addConstraint(x - y <= p) prob.addConstraint(y - x <= p) objs.append(weight_of_sym * p) for v in self.planar.G: if self.planar.G.degree(v) == 3: for f, keys in self.flow_network.adj[v].items(): if len(keys) == 2: he1_id, he2_id = list(keys) x = var_dict[v][f][he1_id] y = var_dict[v][f][he2_id] p = pulp.LpVariable(x.name + y.name + "%temp", None, None, pulp.LpInteger) prob.addConstraint(x - y <= p) prob.addConstraint(y - x <= p) objs.append(weight_of_sym * p) prob += pulp.lpSum(objs), "number of bends in graph" for f in self.planar.dcel.face_dict: prob += self.flow_network.nodes[f]['demand'] == pulp.lpSum([ var_dict[v][f][he_id] for v, _, he_id in self.flow_network.in_edges(f, keys=True) ]) for v in self.planar.G: prob += -self.flow_network.nodes[v]['demand'] == pulp.lpSum([ var_dict[v][f][he_id] for _, f, he_id in self.flow_network.out_edges(v, keys=True) ]) state = prob.solve() if state == 1: # update flow_dict # code here works only when nodes are represented by str, likes '(1, 2)' for var in prob.variables(): if 'temp' not in var.name: lVar = var.name.split('%') if len(lVar) == 3: # u, v, he_id = map(trans, l) # change str to tuple !!!!!!!!! u, v, he_id = [item.replace('_', ' ') for item in lVar] he_id = eval(he_id) self.flow_dict[u][v][he_id] = int(var.varValue) return pulp.value(prob.objective) else: return 2**32
def schedule(request): # Form'da seçilen personel ve bölümlerin çekilmesi staffs_string_list = request.GET.getlist('staff') divisions_string_list = request.GET.getlist('division') # Çekilen listelerin string formatından integer formatına dönüştürülmesi selected_staffs = [] selected_divisions = [] for i in staffs_string_list: selected_staffs.append(int(i)) for i in divisions_string_list: selected_divisions.append(int(i)) # Datanın okunması data = pd.read_excel('Data/data_V2.xlsx', index_col=0) data.reset_index(drop=True, inplace=True) # Personel ve Bölüm isimlerinin Filtereleme için Datadan alınması staff_dict = dict( zip(data['Personel Ad Soyad'].index, data['Personel Ad Soyad'].values)) division_dict = dict( zip( data.drop('Personel Ad Soyad', axis=1).T.reset_index()['index'].index, data.drop('Personel Ad Soyad', axis=1).T.reset_index()['index'].values)) # Optimizasyonda kullanılacak olan kişi ve bölüm isimlerinin alınması staff_opt_list = [staff_dict[i] for i in selected_staffs] division_opt_list = [division_dict[i] for i in selected_divisions] # Seçilen Kişi ve Bölümlere göre Datanın filtrelenmesi names = data[data['Personel Ad Soyad'].isin( staff_opt_list)]['Personel Ad Soyad'] data = data[data['Personel Ad Soyad'].isin(staff_opt_list)].filter( items=division_opt_list, axis=1) data['Personel Ad Soyad'] = names # Kişi, Bölüm ve Performans bilgilenin, Opt için tutulması staff = dict( zip(data['Personel Ad Soyad'].reset_index().index, data['Personel Ad Soyad'].values)) division = dict( zip( data.drop('Personel Ad Soyad', axis=1).T.reset_index()['index'].index, data.drop('Personel Ad Soyad', axis=1).T.reset_index()['index'].values)) performance = np.array(data.drop('Personel Ad Soyad', axis=1).values).astype(int) # OPTİMİZASYON PROBLEMİNİN TANIMLANMASI problem = pulp.LpProblem('Staff_Assigment_Problem', pulp.LpMaximize) # DEĞİŞKENLERİN TANIMLANMASI X_assign = pulp.LpVariable.dicts('Assign', (staff, division), lowBound=0, upBound=1, cat=pulp.LpBinary) # AMAÇ FONKSİYONUNUN TANIMLANMASI problem += pulp.lpSum( [performance[i][j] * X_assign[i][j] for i in staff for j in division]) # KISITLARIN TANIMLANMASI number_of_staff = len(staff.keys()) number_of_division = len(division.keys()) # Staff <= Division if number_of_staff <= number_of_division: # Her lokasyonda MAKSIMUM 1 kişi olsun. for j in division: problem += pulp.lpSum([X_assign[i][j] for i in staff]) <= 1 # Her çalışan KESİNLİKLE ve SADECE 1 bölüme atansın. for i in staff: problem += pulp.lpSum([X_assign[i][j] for j in division]) == 1 # Staff > Division elif number_of_staff > number_of_division: # Her lokasyonda MINIMUM 1 kişi olsun. for j in division: problem += pulp.lpSum([X_assign[i][j] for i in staff]) >= 1 # Her çalışan KESİNLİKLE ve SADECE 1 bölüme atansın. for i in staff: problem += pulp.lpSum([X_assign[i][j] for j in division]) == 1 # PROBLEMİN ÇÖZÜMÜ VE ÇIKTILARI problem.solve() objective_score = pulp.value(problem.objective) problem_status = pulp.LpStatus[problem.status] # Eşleştirilen kişi ve bölümlerin listeye atanması (id olarak) staff_list = [] division_list = [] assignment_list = [] for v in problem.variables(): if v.varValue == 1: staff_list.append(int(v.name.split('_')[-2])) division_list.append(int(v.name.split('_')[-1])) assignment_list.append(v.varValue) # id listesinin isim ve bölüm listesine çevirilmesi division_result_list = [division[i] for i in division_list] staff_result_list = [staff[i] for i in staff_list] result_list = zip(staff_result_list, division_result_list) # Sayfaya gönderilecekler: context = { 'staffs': selected_staffs, 'divisions': selected_divisions, 'objective_score': objective_score, 'problem_status': problem_status, 'division_result_list': division_result_list, 'staff_result_list': staff_result_list, 'result_list': result_list } return render(request, 'schedule.html', context=context)