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 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(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 make_into_lp_problem(good_for, N): """ Helper function for solve_with_lp_and_reduce() N --- number of isoform sequences good_for --- dict of <isoform_index> --> list of matched paths index """ prob = LpProblem("The Whiskas Problem",LpMinimize) # each good_for is (isoform_index, [list of matched paths index]) # ex: (0, [1,2,4]) # ex: (3, [2,5]) variables = [LpVariable(str(i),0,1,LpInteger) for i in xrange(N)] # objective is to minimize sum_{Xi} prob += sum(v for v in variables) # constraints are for each isoform, expressed as c_i * x_i >= 1 # where c_i = 1 if x_i is matched for the isoform # ex: (0, [1,2,4]) becomes t_0 = x_1 + x_2 + x_4 >= 1 for t_i, p_i_s in good_for: #c_i_s = [1 if i in p_i_s else 0 for i in xrange(N)] prob += sum(variables[i]*(1 if i in p_i_s else 0) for i in xrange(N)) >= 1 prob.writeLP('cogent.lp') return prob
def pi_solve(pi, Q, s): # The 'prob' variable will contain the problem data. prob = LpProblem('FindPi', LpMinimize) a0 = LpVariable('a0', 0.0) # the minimum is 0.0 a1 = LpVariable('a1', 0.0) # the minimum is 0.0 a2 = LpVariable('a2', 0.0) # the minimum is 0.0 a3 = LpVariable('a3', 0.0) # the minimum is 0.0 a4 = LpVariable('a4', 0.0) # the minimum is 0.0 v = LpVariable('v', 0.0) # The objective function is added to 'prob' first prob += v, "to minimize" # constraints prob += a0 * Q[s,0,0] + a1 * Q[s,1,0] + a2 * Q[s,2,0] + a3 * Q[s,3,0] + a4 * Q[s,4,0] <= v, 'constraint 1' prob += a0 * Q[s,0,1] + a1 * Q[s,1,1] + a2 * Q[s,2,1] + a3 * Q[s,3,1] + a4 * Q[s,4,1] <= v, 'constraint 2' prob += a0 * Q[s,0,2] + a1 * Q[s,1,2] + a2 * Q[s,2,2] + a3 * Q[s,3,2] + a4 * Q[s,4,2] <= v, 'constraint 3' prob += a0 * Q[s,0,3] + a1 * Q[s,1,3] + a2 * Q[s,2,3] + a3 * Q[s,3,3] + a4 * Q[s,4,3] <= v, 'constraint 4' prob += a0 * Q[s,0,4] + a1 * Q[s,1,4] + a2 * Q[s,2,4] + a3 * Q[s,3,4] + a4 * Q[s,4,4] <= v, 'constraint 5' prob += 1.0*a0 + 1.0*a1 + 1.0*a2 + 1.0*a3 + 1.0*a4 == 1, 'constraint 6' prob.solve() pi_prime = [a.varValue for a in prob.variables()[:5]] return np.array(pi_prime)
def get_linear_program_solution(self, c, b, A, x): prob = LpProblem("myProblem", LpMinimize) prob += lpSum([xp*cp for xp, cp in zip(x, c)]), "Total Cost of Ingredients per can" for row, cell in zip(A, b): prob += lpSum(ap*xp for ap, xp in zip(row, x)) <= cell solved = prob.solve() return prob
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 fuelSolution(airports): for i in range(len(airports)): airports[i].previous = airports[i-1] problem = LpProblem('Flight', LpMinimize) problem+=sum(airport.fuelcost*airport.refuel for airport in airports), 'Cost' for ap in airports: problem+= ap.min_fuel + ap.refuel <= ap.startingFuel, 'Min Fuel %s' % ap.startingFuel problem+= ap.startingFuel == ap.previous.startingFuel + ap.refuel - ap.distance*(1 + (ap.startingFuel + ap.previous.startingFuel - ap.refuel)/(2.*rate)), 'Takeoff Fuel Level %s' % ap.startingFuel problem.solve() return problem
def knapsack01(obj, weights, capacity): """ 0/1 knapsack solver, maximizes profit. weights and capacity integer """ debug_subproblem = False assert len(obj) == len(weights) n = len(obj) if n == 0: return 0, [] if debug_subproblem: relaxation = LpProblem('relaxation', LpMaximize) relax_vars = [str(i) for i in range(n)] var_dict = LpVariable.dicts("", relax_vars, 0, 1, LpBinary) relaxation += (lpSum(var_dict[str(i)] * weights[i] for i in range(n)) <= capacity) relaxation += lpSum(var_dict[str(i)] * obj[i] for i in range(n)) relaxation.solve() relax_obj = value(relaxation.objective) solution = [i for i in range(n) if var_dict[str(i)].varValue > tol ] print relax_obj, solution c = [[0]*(capacity+1) for i in range(n)] added = [[False]*(capacity+1) for i in range(n)] # c [items, remaining capacity] # important: this code assumes strictly positive objective values for i in range(n): for j in range(capacity+1): if (weights[i] > j): c[i][j] = c[i-1][j] else: c_add = obj[i] + c[i-1][j-weights[i]] if c_add > c[i-1][j]: c[i][j] = c_add added[i][j] = True else: c[i][j] = c[i-1][j] # backtrack to find solution i = n-1 j = capacity solution = [] while i >= 0 and j >= 0: if added[i][j]: solution.append(i) j -= weights[i] i -= 1 return c[n-1][capacity], solution
def pe185(): """ Modelling as an integer programming problem. Then using PuLP to solve it. It's really fast, just 0.24 seconds. For details, see https://pythonhosted.org/PuLP/index.html """ from pulp import LpProblem, LpVariable, LpMinimize, LpInteger, lpSum, value constraints = [ ('2321386104303845', 0), ('3847439647293047', 1), ('3174248439465858', 1), ('8157356344118483', 1), ('6375711915077050', 1), ('6913859173121360', 1), ('4895722652190306', 1), ('5616185650518293', 2), ('4513559094146117', 2), ('2615250744386899', 2), ('6442889055042768', 2), ('2326509471271448', 2), ('5251583379644322', 2), ('2659862637316867', 2), ('5855462940810587', 3), ('9742855507068353', 3), ('4296849643607543', 3), ('7890971548908067', 3), ('8690095851526254', 3), ('1748270476758276', 3), ('3041631117224635', 3), ('1841236454324589', 3) ] VALs = map(str, range(10)) LOCs = map(str, range(16)) choices = LpVariable.dicts("Choice", (LOCs, VALs), 0, 1, LpInteger) prob = LpProblem("pe185", LpMinimize) prob += 0, "Arbitrary Objective Function" for s in LOCs: prob += lpSum([choices[s][v] for v in VALs]) == 1, "" for c, n in constraints: prob += lpSum([choices[str(i)][v] for i,v in enumerate(c)]) == n, "" prob.writeLP("pe185.lp") prob.solve() res = int(''.join(v for s in LOCs for v in VALs if value(choices[s][v]))) # answer: 4640261571849533 return res
def get_best_assignments(self, row): df = self.assignments[(self.assignments.FromIcao == row['FromIcao']) & (self.assignments.ToIcao == row['ToIcao']) & (self.assignments.Amount <= row['Seats'])] if not len(df): return None prob = LpProblem("Knapsack problem", LpMaximize) w_list = df.Amount.tolist() p_list = df.Pay.tolist() x_list = [LpVariable('x{}'.format(i), 0, 1, 'Integer') for i in range(1, 1 + len(w_list))] prob += sum([x * p for x, p in zip(x_list, p_list)]), 'obj' prob += sum([x * w for x, w in zip(x_list, w_list)]) <= row['Seats'], 'c1' prob.solve() return df.iloc[[i for i in range(len(x_list)) if x_list[i].varValue]]
def solve_under_coverage(graph, min_coverage=80): prob = LpProblem("granularity selection", LpMinimize) codelet_vars = LpVariable.dicts("codelet", graph, lowBound=0, upBound=1, cat=LpInteger) # Objective function: minimize the total replay cost of selected codelets # Compute replay time for n,d in graph.nodes(data=True): d['_total_replay_cycles'] = 0 for inv in d['_invocations']: d['_total_replay_cycles'] = d['_total_replay_cycles'] + float(inv["Invivo (cycles)"]) prob += lpSum([codelet_vars[n]*d['_total_replay_cycles'] for n,d in graph.nodes(data=True)]) # and with good coverage prob += (lpSum([codelet_vars[n]*d['_coverage'] for n,d in graph.nodes(data=True)]) >= min_coverage) # selected codelets should match for n,d in graph.nodes(data=True): if not d['_matching']: prob += codelet_vars[n] == 0 # Finally we should never include both the children and the parents for dad in graph.nodes(): for son in graph.nodes(): if not dad in nx.ancestors(graph, son): continue # We cannot select dad and son at the same time prob += codelet_vars[dad] + codelet_vars[son] <= 1 #prob.solve(GLPK()) prob.solve() if (LpStatus[prob.status] != 'Optimal'): raise Unsolvable() for v in prob.variables(): assert v.varValue == 1.0 or v.varValue == 0.0 if v.varValue == 1.0: for n,d in graph.nodes(data=True): if ("codelet_"+str(n)) == v.name: d["_selected"] = True yield n
def setup(self, statement): self.problem = LpProblem(statement, LpMinimize) self.problem += sum(self.variables.values()) for a, b in combinations(self.candidates, 2): ab = a + b ba = b + a if ab in statement and ba in statement: # The statement itself contains the ordering information. pass elif ab in statement: self.constrainGreater(ab, ba) elif ba in statement: self.constrainGreater(ba, ab) #else: # self.constrainEqual(ab, ba) prev = None for rank in statement.split(">"): pairs = rank.split("=") if prev: self.constrainGreater(prev, pairs[0]) for n in range(len(pairs) - 1): self.constrainEqual(pairs[n], pairs[n+1]) prev = pairs[-1]
def get_optimal_routes(sources, destinations): sources = collections.OrderedDict([(x['id'], x) for x in sources]) destinations = collections.OrderedDict([(x['id'], x) for x in destinations]) sources_points = [{'lat': x['lat'], 'lng': x['lng']} for x in sources.values()] destinations_points = [{'lat': x['lat'], 'lng': x['lng']} for x in destinations.values()] source_ids = [str(x['id']) for x in sources.values()] dest_ids = [str(x['id']) for x in destinations.values()] demand = {str(x['id']): convert_int(x['num_students']) for x in sources.values()} supply = {str(x['id']): convert_int(x['num_students']) for x in destinations.values()} log.info("Calling gmaps api...") distances = gmaps.distance_matrix(origins=sources_points, destinations=destinations_points, mode='walking') costs = {} for i, origin in enumerate(distances['rows']): origin_costs = {} for j, entry in enumerate(origin['elements']): origin_costs[dest_ids[j]] = entry['duration']['value'] costs[source_ids[i]] = origin_costs prob = LpProblem("Evaucation Routing for Schools",LpMinimize) routes = [(s,d) for s in source_ids for d in dest_ids] route_lookup = {'Route_{}_{}'.format(x.replace(' ','_'),y.replace(' ','_')):(x,y) for (x,y) in routes} route_vars = LpVariable.dicts("Route",(source_ids,dest_ids),0,None,LpInteger) prob += lpSum([route_vars[w][b]*(costs[w][b]**2) for (w,b) in routes]) for dest in dest_ids: prob += lpSum([route_vars[source][dest] for source in source_ids]) <= supply[dest], "Students going to {} is <= {}".format(dest, supply[dest]) for source in source_ids: prob += lpSum([route_vars[source][dest] for dest in dest_ids]) == demand[source], "Students leaving {} is {}".format(source, demand[source]) log.info("Optimizing routes...") prob.solve() if prob.status != 1: raise Exception("Algorithm could not converge to a solution") result = [] for v in prob.variables(): src, dst = route_lookup[v.name] value = v.value() result.append({'src': sources[src], 'dst': destinations[dst], 'value': int(value)}) return result
def _recurse(work_pairs, mae, grace=None): req = grace or 1.0 demands = { 'morning': mae[0], 'afternoon': mae[1], 'exam': mae[2], } total_avg = float(sum([demands[i] for i in SHIFTS])) / work_pairs total_low, total_high = floor(total_avg), ceil(total_avg) work_pair_count = work_pairs avgs = [float(demands[i]) / work_pair_count for i in SHIFTS] lows = [floor(a) for a in avgs] highs = [ceil(a) for a in avgs] target = req * total_avg * float(sum([COSTS[i] for i in SHIFTS])) / len(SHIFTS) prob = LpProblem("Work Distribution", LpMinimize) var_prefix = "shift" shift_vars = LpVariable.dicts(var_prefix, SHIFTS, 0, cat=LpInteger) prob += lpSum([COSTS[i] * shift_vars[i] for i in SHIFTS]), "cost of combination" prob += lpSum([COSTS[i] * shift_vars[i] for i in SHIFTS]) >= target, "not too good" prob += lpSum([shift_vars[i] for i in SHIFTS]) >= total_low, "low TOTAL" prob += lpSum([shift_vars[i] for i in SHIFTS]) <= total_high, "high TOTAL" for shift, low, high in zip(SHIFTS, lows, highs): prob += lpSum([shift_vars[shift]]) >= low, "low %s" % shift prob += lpSum([shift_vars[shift]]) <= high, "high %s" % shift prob.solve(GLPK_CMD(msg=0)) if not LpStatus[prob.status] == 'Optimal': next_grace = req - 0.1 assert 0.0 < next_grace return _recurse(work_pairs, mae, next_grace) new_mae = [0, 0, 0] solution = [0, 0, 0] for v in prob.variables(): for pos, name in enumerate(SHIFTS): if v.name == "%s_%s" % (var_prefix, name): solution[pos] = v.varValue new_mae[pos] = mae[pos] - solution[pos] return (PairAlloc(solution), work_pairs - 1) + tuple(new_mae)
def create_prob(self, sense=LpMaximize, use_glpk=False): # create the LP self.prob = LpProblem('OptKnock', sense=sense) if use_glpk: self.prob.solver = solvers.GLPK() else: self.prob.solver = solvers.CPLEX(msg=self.verbose) if not self.prob.solver.available(): raise Exception("CPLEX not available")
def find_optimal_strategy(states, controls, costs, kernels, solver=None): """ :param states: Number of system states (X) :param controls: Number of system controls (U) :param сosts: Cost matrix |X| x |U| :param kernels: Transition kernels. Dimensionality |X| x |X| x |U| """ tolerance = 10e-15 X = range(states) U = range(controls) R = costs Q = kernels # Check costs # Check num of rows assert(len(R) == states) for row in R: # Check num of cols assert(len(row) == controls) # Check kernels # Check num of rows assert(len(Q) == states) for row in Q: # Check num of cols assert(len(row) == states) for items in row: # Check num of items assert(len(items) == controls) # Check if distribution is normed for dist in zip(*row): assert(sum(dist)-1 < tolerance) # LP object optm = LpProblem("Optimal strategy", sense=LpMinimize) # Variables (continuous in range [0, 1]) Z = [[LpVariable("z({},{})".format(x, u), 0, 1) \ for u in U] for x in X] # Objective optm.objective = sum(np.dot(Z[x], R[x]) for x in X) # Constraints for x in X: cn = (sum(Z[x]) == sum(Q[y][x][u]*Z[y][u] for u in U for y in X)) optm.add(cn) cn = sum(Z[x][u] for u in U for x in X) == 1 optm.add(cn) optm.solve(solver) return [(x, u) for u in U for x in X if value(Z[x][u]) != 0]
def runLPP(lines): # reads the data from the CSV file into the LPP variables, ingredients, servingsPerBlock, costsPerServing = [], [], [], [] for row in lines: # read in the variables from the lines variables.append(LpVariable("x_" + row[1], 0, None, LpInteger)) ingredients.append(row[0]) servingsPerBlock.append(float(row[2])) costsPerServing.append(float(row[3])) variables.append(LpVariable("s", 0)) # read in the upper and lower bounds for aLCM minServe = lines[0][4] maxServe = lines[0][5] # makes the new LP Problem problem = LpProblem("Approximate LCM", LpMinimize) # serving constraints: specifies the interval in which the approximate # LCM may lie min_constraint = variables[-1] >= float(minServe) max_constraint = variables[-1] <= float(maxServe) problem += min_constraint problem += max_constraint # block constraints: there must be enough of each ingredient for the # ultimate optimal number for v in range(len(variables) - 1): min_constraint = variables[v] * servingsPerBlock[v] >= variables[-1] problem += min_constraint pps = 0.0 # price per serving for i in range(len(variables) - 1): pps += costsPerServing[i] # add objective function to be minimized (waste) obj_fn = 0 * variables[0] for i in range(len(variables) - 1): obj_fn += variables[i] * costsPerServing[i] * servingsPerBlock[i] obj_fn -= variables[-1] * pps problem += obj_fn # add the objective funciton to the problem problem.solve() # runs the linear programming problem return [variables, costsPerServing, obj_fn]
def lp(self): a_name = [] p_name = [] n_name = [] a = [] p = [] n = [] for i in range(self.att): a_name.append('a_' + str(i)) for h in range(self.h): p_name.append('p_' + str(h)) for m in range(self.m): n_name.append('n_' + str(m)) a = [LpVariable(a_name[i]) for i in range(self.att)] b = LpVariable('b') p = [LpVariable(p_name[i],0) for i in range(self.h)] n = [LpVariable(n_name[i],0) for i in range(self.m)] #set objective function and constrains prob = LpProblem("myProblem",LpMinimize) sumP = 0 sumN = 0 for i in range(self.h): sumX = 0 for j in range(self.att): sumX -= a[j] * self.H[i,j] prob += sumX + b + 1 <= p[i] sumP += p[i] for i in range(self.m): sumX = 0 for j in range(self.att): sumX += a[j] * self.M[i,j] prob += sumX - b + 1 <= n[i] sumN += n[i] prob += (1/h) * sumP + (1/m) * sumN status = prob.solve() for i in range(self.att): self.a.append(pulp.value(a[i])) self.b = pulp.value(b)
def pulp_solve(A, b, c, bounds): problem = LpProblem(sense = pulp.constants.LpMaximize) x = [LpVariable('x' + str(i + 1), bound['low_bound'], bound['up_bound'], LpInteger) for i, bound in enumerate(bounds)] problem += lpSum(ci * xi for ci, xi in zip(c, x)) for ai, bi in zip(A, b): problem += lpSum(aij * xj for aij, xj in zip(ai, x)) == bi status = problem.solve() return (pulp.constants.LpStatus[status], [variable.varValue for variable in problem.sortedVariables()], problem.objective.value())
def pulp_solve(A, b, c): problem = LpProblem(sense = pulp.constants.LpMaximize) x = [LpVariable('x' + str(i + 1), 0, None, LpInteger) for i in xrange(len(c))] problem += lpSum(ci * xi for ci, xi in zip(c, x)) for ai, bi in zip(A, b): problem += lpSum(aij * xj for aij, xj in zip(ai, x)) == bi status = problem.solve() return (pulp.constants.LpStatus[status], [variable.varValue for variable in problem.sortedVariables()], problem.objective.value())
def build_problem(self, model): """ Create and store solver-specific internal structure for the given model. Arguments: model : ConstraintBasedModel """ problem = LpProblem(sense=LpMaximize) problem.setSolver(SELECTED_SOLVER) #create variables lpvars = {r_id: LpVariable(r_id, lb, ub) for r_id, (lb, ub) in model.bounds.items()} #create constraints table = model.metabolite_reaction_lookup_table() for m_id in model.metabolites: problem += lpSum([coeff * lpvars[r_id] for r_id, coeff in table[m_id].items()]) == 0, m_id self.problem = problem self.var_ids = model.reactions.keys() self.constr_ids = model.metabolites.keys()
def pulp_solver(G, h, A, b, c, n): # First, create a variable for each of the columsn of G and A. # # pre-condition: G and A have the same number of columns. # # The second argument specifies a lower bound for the variable, so we can # safely ignore the inequality constraints given by G and h. variables = [LpVariable('s{}'.format(i), 0) for i in range(G.shape[1])] # LpVariable has a second argument that allows you to specify a lower bound # for the variable (for example, x1 >= 0). We don't specify nonnegativity # here, because it is already specified by the inequality constraints G and # h. #variables = [LpVariable('s{}'.format(i)) for i in range(G.shape[1])] # Next, create a problem context object and add the objective function c to # it. The first object added to LpProblem is implicitly interpreted as the # objective function. problem = LpProblem('fraciso', LpMinimize) # The np.dot() function doesn't like mixing numbers and LpVariable objects, # so we compute the dot product ourselves. # #problem += np.dot(variables, c), 'Dummy objective function' problem += _pulp_dot_product(c, variables), 'Dummy objective function' # Add each equality constraint to the problem context. for i, (row, b_value) in enumerate(zip(A, b)): #problem += np.dot(row, variables), 'Constraint {}'.format(i) # Convert the row to a list so pulp has an easier time dealing with it. row_as_list = np.asarray(row).flatten().tolist() dot_product = _pulp_dot_product(row_as_list, variables) problem += dot_product == b_value, 'Constraint {}'.format(i) solver_backend = GLPK() #solver_backend = COIN() problem.solve(solver_backend) if problem.status == LpStatusOptimal: # PuLP is silly and sorts the variables by name before returning them, # so we need to re-sort them in numerical order. solution = [s.varValue for s in sorted(problem.variables(), key=lambda s: int(s.name[1:]))] return True, solution # TODO status could be unknown here, but we're currently ignoring that return False, None
def test_pulp_016(self): # zero objective prob = LpProblem("test016", const.LpMinimize) x = LpVariable("x", 0, 4) y = LpVariable("y", -1, 1) z = LpVariable("z", 0) w = LpVariable("w", 0) prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7, "c3" prob += w >= 0, "c4" prob += lpSum([0, 0]) <= 0, "c5" print("\t Testing zero objective") pulpTestCheck(prob, self.solver, [const.LpStatusOptimal])
def test_pulp_014(self): # repeated name prob = LpProblem("test014", const.LpMinimize) x = LpVariable("x", 0, 4) y = LpVariable("x", -1, 1) z = LpVariable("z", 0) w = LpVariable("w", 0) prob += x + 4 * y + 9 * z, "obj" prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7, "c3" prob += w >= 0, "c4" print("\t Testing repeated Names") if self.solver.__class__ in [ COIN_CMD, COINMP_DLL, PULP_CBC_CMD, CPLEX_CMD, CPLEX_DLL, CPLEX_PY, GLPK_CMD, GUROBI_CMD, PULP_CHOCO_CMD, CHOCO_CMD, MIPCL_CMD, MOSEK, SCIP_CMD, ]: try: pulpTestCheck( prob, self.solver, [const.LpStatusOptimal], { x: 4, y: -1, z: 6, w: 0 }, ) except PulpError: # these solvers should raise an error pass else: pulpTestCheck(prob, self.solver, [const.LpStatusOptimal], { x: 4, y: -1, z: 6, w: 0 })
def vrp(g, nv, capa, demand='demand', cost='cost'): """ 運搬経路問題 入力 g: グラフ(node:demand, edge:cost) nv: 運搬車数 capa: 運搬車容量 demand: 需要の属性文字 cost: 費用の属性文字 出力 運搬車ごとの頂点対のリスト """ from pulp import LpProblem, LpBinary, lpDot, lpSum, value from itertools import islice rv = range(nv) m = LpProblem() x = [{(i, j): addvar(cat=LpBinary) for i, j in g.edges()} for _ in rv] w = [[addvar() for i in g.nodes()] for _ in rv] m += lpSum(g.adj[i][j][cost] * lpSum(x[v][i, j] for v in rv) for i, j in g.edges()) for v in rv: xv, wv = x[v], w[v] m += lpSum(xv[0, j] for j in g.nodes() if j) == 1 for h in g.nodes(): m += wv[h] <= capa m += lpSum(xv[i, j] for i, j in g.edges() if i == h) \ == lpSum(xv[i, j] for i, j in g.edges() if j == h) for i, j in g.edges(): if i == 0: m += wv[j] >= g.node[j][demand] - capa * (1 - xv[i, j]) else: m += wv[j] >= wv[i] + g.node[j][demand] - capa * (1 - xv[i, j]) for h in islice(g.nodes(), 1, None): m += lpSum(x[v][i, j] for v in rv for i, j in g.edges() if i == h) == 1 if m.solve() != 1: return None return [[(i, j) for i, j in g.edges() if value(x[v][i, j]) > 0.5] for v in rv]
def pulp_mosaic(v_num, h_num, ch_num, box_array): from pulp import LpProblem, lpSum, lpDot, value, LpStatus from ortoolpy import addbinvars import time start = time.time() print("Calculate the optimal combination") print("Variables : {}".format(v_num * h_num * ch_num)) if box_array.shape != (v_num, h_num, ch_num): raise Exception("shape does not match!!") # 変数宣言 variable = np.array(addbinvars(v_num, h_num, ch_num)) # 目的関数の最小化 prob = LpProblem() # 目的関数の設定 prob += (box_array * variable).sum() # 制約条件の設定 for ch in range(ch_num): prob += variable[:, :, ch].sum() <= 1 for v in range(v_num): for h in range(h_num): prob += variable[v, h, :].sum() == 1 # 問題を解く prob.solve() if LpStatus[prob.status] != "Optimal": raise Exception("could not be optimized!!") else: print("status = " + LpStatus[prob.status]) # 最適化された変数の値を抽出 opt_var = np.vectorize(value)(variable).astype(int) # 全体で最小となるインデックスの組み合わせ bit_index = np.empty((v_num, h_num), dtype=np.int32) for v in range(v_num): for h in range(h_num): bit_index[v, h] = np.where(opt_var[v, h, :] == 1)[0] elapsed_time = time.time() - start print("elapsed_time:{0}".format(elapsed_time) + "[sec]") return bit_index
def optimize( assets, gas_price, electricity_price, site_steam_demand, site_power_demand ): prob = LpProblem('cost minimization', LpMinimize) net_grid = LpVariable('net_power_to_site', -100, 100) prob += sum([asset.gas_burnt() for asset in assets]) * gas_price \ + net_grid * electricity_price prob += sum([asset.steam_generated() for asset in assets]) \ - sum([asset.steam_consumed() for asset in assets]) \ == site_steam_demand, 'steam_balance' prob += sum([asset.power_generated() for asset in assets]) \ - sum([asset.power_consumed() for asset in assets]) \ + net_grid == site_power_demand, 'power_balance' # constraints on the asset min & maxes for asset in assets: prob += asset.cont - asset.ub * asset.binary <= 0 prob += asset.lb * asset.binary - asset.cont <= 0 prob.solve() info = generate_outputs( assets, site_steam_demand, site_power_demand, net_grid ) return info
def create_model(self, warmStart=False, beta=0.0, alpha=0.9): """Creates the stochastic program as a integer linear program in pulp Parameters ---------- warmStart : bool, optional if set to true does not recreate variables, so that previous solutions can be used as a starting point (default is False) beta : float, optional weight of value-at-risk, between 0.0 and 1.0 (default is 0.0) alpha : float, optional only used when beta is not 0.0, for a given α ∈ (0, 1), the value-at-risk, VaR, is equal to the largest value η ensuring that the probability of obtaining a profit less than η is lower than 1 − α (default is 0.9) """ self._beta = float(beta) self._alpha = float(alpha) self._model = LpProblem(name="vehicle-reposition", sense=LpMaximize) if not warmStart: self._create_variables() self._create_objectives() self._create_constraints() for constraint_group in self._constraints.values(): for constraint in constraint_group: self._model += constraint if self._beta != 0.0: self._model += (1 - self._beta ) * self._expected_profit + self._beta * self._eta else: self._model += self._expected_profit
def LP_set_cover(X, F): start = time.clock() var_name = ["S" + str(x) for x in range(len(F))] lp = LpProblem("The Problem of set cover", LpMinimize) lp_vars = LpVariable.dicts("lp", var_name, lowBound=0, upBound=1, cat=LpContinuous) all_occur = [] for x in X: occur = {} for index, f in enumerate(F): if x in f: occur["S" + str(index)] = 1 else: occur["S" + str(index)] = 0 all_occur.append(occur) C_S={} for x in range(len(F)): C_S["S" + str(x)]=len(F[x]) lp += lpSum([lp_vars[i] for i in var_name]) for occur in all_occur: lp += lpSum([occur[i] * lp_vars[i] for i in var_name]) >= 1 solve_state=lp.solve() result = [] max_count = max([sum(occur.values()) for occur in all_occur]) for v in lp.variables(): if v.varValue > (1.0/max_count): result.append(F[int(v.name[4:])]) elapsed = (time.clock() - start) F_set = set() for i in result: F_set = F_set | i _check = X == F_set print("\n-------------------") print("Test LP_set_cover Time used:%s, F'size:%s"%(elapsed,len(X))) print("C's size: %d \ncover all elements in X:%s" % (len(result), _check))
def create_problem(self, filename=None, use_no_fit=False): if self.polygons is None: raise ValueError('You must create the data before the model!') self.use_no_fit = use_no_fit self.problem = LpProblem('polygons_packing', LpMinimize) self.w = LpVariable('w', 0) self.tx = LpVariable.dicts('tx', range(self.N), 0) self.ty = LpVariable.dicts('ty', range(self.N), 0) # objective self.problem.setObjective(self.w) # w constraints widths = [ np.max(pol[:, 0]) - np.min(pol[:, 0]) for pol in self.polygons ] for i in range(self.N): self.problem += self.w - self.tx[i] >= widths[ i], f"w_constraint_{i}" # height constraints heights = [ np.max(pol[:, 1]) - np.min(pol[:, 1]) for pol in self.polygons ] for i in range(self.N): self.problem += self.ty[ i] <= self.H - heights[i], f"height_constraint_{i}" self._add_non_overl_constr() if filename is not None: self.problem.writeLP(filename)
def min_vertex_cover_ilp(G): """Return a smallest vertex cover in the graph G. This method uses an ILP to solve for a smallest vertex cover. Specifically, the ILP minimizes .. math:: \\sum_{v \\in V} x_v subject to .. math:: x_v + x_u \\geq 1 \\mathrm{for all } \\{u, v\\} \\in E x_v \\in \\{0, 1\\} \\mathrm{for all } v \\in V where *V* and *E* are the vertex and edge sets of *G*. Parameters ---------- G : NetworkX graph An undirected graph. Returns ------- set A set of nodes in a smallest vertex cover. """ prob = LpProblem('min_vertex_cover', LpMinimize) variables = { node: LpVariable('x{}'.format(i + 1), 0, 1, LpBinary) for i, node in enumerate(G.nodes()) } # Set the total domination number objective function prob += lpSum([variables[n] for n in variables]) # Set constraints for edge in G.edges(): prob += variables[edge[0]] + variables[edge[1]] >= 1 prob.solve() solution_set = {node for node in variables if variables[node].value() == 1} return solution_set
def getOverallEfficiency(r): # Model Building model = LpProblem('CRS_model', LpMinimize) # 建立一個新的model,命名為model # Decision variables Building theta_r = LpVariable(f'theta_r') lambda_k = LpVariable.dicts(f'lambda_k', lowBound=0, indexs=K) # Objective Function setting model += theta_r # Constraints setting for i in I: model += lpSum([lambda_k[k] * X[i][k] for k in K]) <= theta_r * float(X[i][K[r]]) for j in J: model += lpSum([lambda_k[k] * Y[j][k] for k in K]) >= float(Y[j][K[r]]) # Model solving model.solve() return f'{K[r]}:{round(value(model.objective), 3)}\n', value( model.objective)
def model_0(self, betsum, k): # 期待値を最大にする model = LpProblem(name='horse', sense=LpMaximize) model += lpSum(o * v * p for o, p, v in zip(self.odds, self.pro, self.V)) # 総ベット枚数が最初に引数で渡したベット枚数を超えないようにする model += lpSum(v for v in self.V) <= betsum for i in range(self.l): # ベット枚数は最小でも1枚はかける model += self.V[i] >= k return model
def test_pulp_015(self): # zero constraint prob = LpProblem("test015", const.LpMinimize) x = LpVariable("x", 0, 4) y = LpVariable("y", -1, 1) z = LpVariable("z", 0) w = LpVariable("w", 0) prob += x + 4 * y + 9 * z, "obj" prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7, "c3" prob += w >= 0, "c4" prob += lpSum([0, 0]) <= 0, "c5" print("\t Testing zero constraint") pulpTestCheck(prob, self.solver, [const.LpStatusOptimal], {x: 4, y: -1, z: 6, w: 0})
def test_export_solver_dict_LP(self): prob = LpProblem("test_export_dict_LP", const.LpMinimize) x = LpVariable("x", 0, 4) y = LpVariable("y", -1, 1) z = LpVariable("z", 0) w = LpVariable("w", 0) prob += x + 4 * y + 9 * z, "obj" prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7, "c3" prob += w >= 0, "c4" data = self.solver.to_dict() solver1 = get_solver_from_dict(data) print("\t Testing continuous LP solution - export solver dict") pulpTestCheck(prob, solver1, [const.LpStatusOptimal], {x: 4, y: -1, z: 6, w: 0})
def solve_set_covering(num_terms, protein): """ Find minimum number of proteins needed to reconstruct annotation set for a given protein using integer programming - set covering problem :param num_terms: number of terms :type num_terms: int :param protein: protein annotations data :type protein: list :return: minimum number of proteins needed to reconstruct annotation set :rtype: np.float """ c = [1 for i in range(num_terms)] x_name = ['x_' + str(i + 1) for i in range(num_terms)] x = [ LpVariable(name=x_name[i], lowBound=0, upBound=1, cat='Binary') for i in range(num_terms) ] problem = LpProblem('set_covering', LpMinimize) z = LpAffineExpression([(x[i], c[i]) for i in range(num_terms)]) for i in protein: problem += sum([x[j] for j in i]) >= 1 problem += z problem.solve() return np.sum([value(i) for i in x])
def liniary_optimization(max_or_min: int = 1): model = LpProblem(name="current_task", sense=max_or_min2) x = {i: LpVariable(name="x{}".format(i), lowBound=0) for i in range(1, 5)} model += (1*x[1] + 1*x[2] + 1*x[3] + 1*x[4] <= 50, "manpower") model += (3*x[1] + 2*x[2] + 1*x[3] + 0*x[4] <= 100, "material_A") model += (0*x[1] + 1*x[2] + 2*x[3] + 3*x[4] <= 90, "material_B") objective_function = 20*x[1] + 12*x[2] + 40*x[3] + 25*x[4] model += objective_function print(model) model.solve() print("status: {}, {}".format(model.status, LpStatus[model.status])) print("objective: {}".format(model.objective.value())) for var in model.variables(): print("{}: {}".format(var.name, var.value())) for name, constraint in model.constraints.items(): print("{}: {}".format(name, constraint.value()))
def test_pulp_100(self): """ Test the ability to sequentially solve a problem """ # set up a cubic feasible region prob = LpProblem("test100", const.LpMinimize) x = LpVariable("x", 0, 1) y = LpVariable("y", 0, 1) z = LpVariable("z", 0, 1) obj1 = x + 0 * y + 0 * z obj2 = 0 * x - 1 * y + 0 * z prob += x <= 1, "c1" if self.solver.__class__ in [CPLEX_DLL, COINMP_DLL, GUROBI]: print("\t Testing Sequential Solves") status = prob.sequentialSolve([obj1, obj2], solver=self.solver) pulpTestCheck( prob, self.solver, [[const.LpStatusOptimal, const.LpStatusOptimal]], sol={x: 0, y: 1}, status=status, )
def test_infeasible_problem__is_not_valid(self): """Given a problem where x cannot converge to any value given conflicting constraints, assert that it is invalid.""" name = self._testMethodName prob = LpProblem(name, const.LpMaximize) x = LpVariable("x") prob += 1 * x prob += x >= 2 # Constraint x to be more than 2 prob += x <= 1 # Constraint x to be less than 1 if self.solver.name in ["GUROBI_CMD"]: pulpTestCheck( prob, self.solver, [ const.LpStatusNotSolved, const.LpStatusInfeasible, const.LpStatusUndefined, ], ) else: pulpTestCheck( prob, self.solver, [const.LpStatusInfeasible, const.LpStatusUndefined] ) self.assertFalse(prob.valid())
def test_export_json_LP(self): name = self._testMethodName prob = LpProblem(name, const.LpMinimize) x = LpVariable("x", 0, 4) y = LpVariable("y", -1, 1) z = LpVariable("z", 0) w = LpVariable("w", 0) prob += x + 4 * y + 9 * z, "obj" prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7, "c3" prob += w >= 0, "c4" filename = name + ".json" prob.toJson(filename, indent=4) var1, prob1 = LpProblem.fromJson(filename) try: os.remove(filename) except: pass x, y, z, w = [var1[name] for name in ["x", "y", "z", "w"]] print("\t Testing continuous LP solution - export JSON") pulpTestCheck( prob1, self.solver, [const.LpStatusOptimal], {x: 4, y: -1, z: 6, w: 0} )
def run_optimisation(self): # Declare problem instance, max/min problem self.prob = LpProblem("Squad", LpMaximize) # Declare decision variable - 1 if a player is part of the squad else 0 self.decision = LpVariable.matrix("decision", list(self.data_length), 0, 1, LpInteger) # Objective function -> Maximize specified optimisation parameter self.prob += lpSum(self.opt_list[i] * self.decision[i] for i in self.data_length) # Constraint definition self.add_constraints() # solve problem self.prob.solve() # extract selected players and return return [ self.id_list[i] for i in self.data_length if self.decision[i].varValue ]
def maximum_cut(g, weight="weight"): """ 最大カット問題 入力 g: グラフ(node:weight) weight: 重みの属性文字 出力 カットの重みの合計と片方の頂点番号リスト """ m = LpProblem(sense=LpMaximize) v = [addvar(cat=LpBinary) for _ in g.nodes()] u = [] for i in range(g.number_of_nodes()): for j in range(i + 1, g.number_of_nodes()): w = g.get_edge_data(i, j, {weight: None}).get(weight, 1) if w: t = addvar() u.append(w * t) m += t <= v[i] + v[j] m += t <= 2 - v[i] - v[j] m += lpSum(u) if m.solve() != 1: return None return value(m.objective), [i for i, x in enumerate(v) if value(x) > 0.5]
def prepare_problem(A, b, c): """ Создаёт проблемы по заданным матрице A, вектору b и оптимизируемой функции """ problem = LpProblem(sense = pulp.constants.LpMaximize) x_list = [LpVariable("x" + str(i + 1), 0) for i in xrange(len(A[0]))] problem += lpSum(ci * xi for ci, xi in zip(c, x_list)) for aj, bj in zip(A, b): problem += lpSum([aij * xi for aij, xi in zip(aj, x_list)]) == bj return problem
def run_linear_program(self, forecasts, initial_charge, freq, verbose): """creates battery model and runs it""" timestep = freq_to_timestep(freq) # used to index timesteps idx = range(0, len(forecasts)) self.prob = LpProblem("battery_cost_minimization", LpMinimize) variables = self.setup_vars(idx) imports = variables["imports"] exports = variables["exports"] charges = variables["charges"] losses = variables["losses"] # the objective function we are minimizing self.prob += lpSum( [imports[i] * forecasts[i] for i in idx[:-1]] + [-(exports[i] - losses[i]) * forecasts[i] for i in idx[:-1]]) # initial charge assert initial_charge <= self.capacity assert initial_charge >= 0 self.prob += charges[0] == initial_charge # last item in the index isn't used because the last timestep only # represents the final charge level - no import or export is done for i in idx[:-1]: # energy balance across two time periods self.prob += (charges[i + 1] == charges[i] + (imports[i] - exports[i]) / timestep) # constrain battery charge level self.prob += charges[i] <= self.capacity self.prob += charges[i] >= 0 self.prob += losses[i] == exports[i] * (1 - self.efficiency) solver = pulp.PULP_CBC_CMD(msg=0) solver.solve(self.prob) opt_results = { "name": "optimization_results", "status": LpStatus[self.prob.status], } if verbose: print(f" {self}, {opt_results['status']}") return idx, variables
def build_sudoku_problem(): # The values, rows and cols sequences all follow this form values = range(9) rows = range(9) columns = range(9) # The boxes list is created, with the row and column index of each square in each box boxes = [] for i in range(3): for j in range(3): box = [(rows[3 * i + k], columns[3 * j + l]) for k in range(3) for l in range(3)] boxes.append(box) # The problem variable is created to contain the problem data problem = LpProblem("Sudoku Problem", LpMinimize) # The problem variables are created choices = LpVariable.dicts("Choice", (rows, columns, values), 0, 1, LpBinary) # The arbitrary objective function is added problem += 0, "Arbitrary Objective Function" # A constraint ensuring that only one value can be in each square is created for r in rows: for c in columns: problem += lpSum( choices[r][c][v] for v in values) == 1, "unique_val_" + str(r) + '_' + str(c) # The row, column and box constraints are added for each value for v in values: for r in rows: problem += lpSum( choices[r][c][v] for c in columns) == 1, "row_" + str(v) + '_' + str(r) for c in columns: problem += lpSum( choices[r][c][v] for r in rows) == 1, "col_" + str(v) + '_' + str(c) for box_index, b in enumerate(boxes): problem += lpSum( choices[r][c][v] for (r, c) in b) == 1, "box_" + str(v) + '_' + str(box_index) return problem, choices, values, rows, columns
def test_pulp_020(self): # MIP prob = LpProblem("test020", const.LpMinimize) x = LpVariable("x", 0, 4) y = LpVariable("y", -1, 1) z = LpVariable("z", 0, None, const.LpInteger) prob += x + 4 * y + 9 * z, "obj" prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7.5, "c3" print("\t Testing MIP solution") pulpTestCheck(prob, self.solver, [const.LpStatusOptimal], { x: 3, y: -0.5, z: 7 })
def test_pulp_018(self): # Long name in lp prob = LpProblem("test018", const.LpMinimize) x = LpVariable("x" * 90, 0, 4) y = LpVariable("y" * 90, -1, 1) z = LpVariable("z" * 90, 0) w = LpVariable("w" * 90, 0) prob += x + 4 * y + 9 * z, "obj" prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7, "c3" prob += w >= 0, "c4" if self.solver.__class__ in [PULP_CBC_CMD, COIN_CMD]: print("\t Testing Long lines in LP") pulpTestCheck(prob, self.solver, [const.LpStatusOptimal], {x: 4, y: -1, z: 6, w: 0}, use_mps=False)
def test_timeLimit(self): name = self._testMethodName prob = LpProblem(name, const.LpMinimize) x = LpVariable("x", 0, 4) y = LpVariable("y", -1, 1) z = LpVariable("z", 0) w = LpVariable("w", 0) prob += x + 4 * y + 9 * z, "obj" prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7, "c3" prob += w >= 0, "c4" self.solver.timeLimit = 20 # CHOCO has issues when given a time limit if self.solver.name != 'PULP_CHOCO_CMD': pulpTestCheck(prob, self.solver, [const.LpStatusOptimal], {x: 4, y: -1, z: 6, w: 0})
def test_pulp_011(self): # Continuous Maximisation prob = LpProblem("test011", const.LpMaximize) x = LpVariable("x", 0, 4) y = LpVariable("y", -1, 1) z = LpVariable("z", 0) w = LpVariable("w", 0) prob += x + 4 * y + 9 * z, "obj" prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7, "c3" prob += w >= 0, "c4" print("\t Testing maximize continuous LP solution") pulpTestCheck( prob, self.solver, [const.LpStatusOptimal], {x: 4, y: 1, z: 8, w: 0} )
def test_pulp_019(self): # divide prob = LpProblem("test019", const.LpMinimize) x = LpVariable("x", 0, 4) y = LpVariable("y", -1, 1) z = LpVariable("z", 0) w = LpVariable("w", 0) prob += x + 4 * y + 9 * z, "obj" prob += (2 * x + 2 * y).__div__(2.0) <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7, "c3" prob += w >= 0, "c4" print("\t Testing LpAffineExpression divide") pulpTestCheck( prob, self.solver, [const.LpStatusOptimal], {x: 4, y: -1, z: 6, w: 0} )
def test_export_solver_json(self): if self.solver.name == "CPLEX_DLL": warnings.warn("CPLEX_DLL does not like being exported") return name = self._testMethodName prob = LpProblem(name, const.LpMinimize) x = LpVariable("x", 0, 4) y = LpVariable("y", -1, 1) z = LpVariable("z", 0) w = LpVariable("w", 0) prob += x + 4 * y + 9 * z, "obj" prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7, "c3" prob += w >= 0, "c4" self.solver.mip = True logFilename = name + ".log" if self.solver.name == "CPLEX_CMD": self.solver.optionsDict = dict( gapRel=0.1, gapAbs=1, maxMemory=1000, maxNodes=1, threads=1, logPath=logFilename, warmStart=True, ) elif self.solver.name in ["GUROBI_CMD", "COIN_CMD", "PULP_CBC_CMD"]: self.solver.optionsDict = dict(gapRel=0.1, gapAbs=1, threads=1, logPath=logFilename, warmStart=True) filename = name + ".json" self.solver.toJson(filename, indent=4) solver1 = getSolverFromJson(filename) try: os.remove(filename) except: pass print("\t Testing continuous LP solution - export solver JSON") pulpTestCheck(prob, solver1, [const.LpStatusOptimal], { x: 4, y: -1, z: 6, w: 0 })
def test_pulp_023(self): # Initial value (fixed) prob = LpProblem("test023", const.LpMinimize) x = LpVariable("x", 0, 4) y = LpVariable("y", -1, 1) z = LpVariable("z", 0, None, const.LpInteger) prob += x + 4 * y + 9 * z, "obj" prob += x + y <= 5, "c1" prob += x + z >= 10, "c2" prob += -y + z == 7.5, "c3" solution = {x: 4, y: -0.5, z: 7} for v in [x, y, z]: v.setInitialValue(solution[v]) v.fixValue() self.solver.optionsDict["warmStart"] = True print("\t Testing fixing value in MIP solution") pulpTestCheck(prob, self.solver, [const.LpStatusOptimal], solution)
def __init__(self,name='analysis',verbose=False): self.lpProblem = LpProblem() self.lpVariables = {} self.lpObjective = {} self.predictionMap = {} self.objectiveValue = None self.rowNames= [] self.columnNames= [] self.configFile = '' self.statusCode = None self.verbose = verbose self.useLimitTag = False self.mpsLogFile = False self.ignoreBadReferences = False self.Mip = True self.scip_path = ":" + os.environ["HOME"] + "/bin"
def __init__(self, home_list, work_list, util_matrix): """ Input a list of utils utils = [ #Works #1 2 3 4 5 [2,4,5,2,1],#A Homes [3,1,3,2,3] #B ] """ self.util_matrix = util_matrix self.homes = dict((home, home.houses) for home in home_list) self.works = dict((work, work.jobs) for work in work_list) self.utils = makeDict([home_list, work_list], util_matrix, 0) # Creates the 'prob' variable to contain the problem data self.prob = LpProblem("Residential Location Choice Problem", LpMinimize) # Creates a list of tuples containing all the possible location choices self.choices = [(h, w) for h in self.homes for w in self.works.keys()] # A dictionary called 'volumes' is created to contain the referenced variables(the choices) self.volumes = LpVariable.dicts("choice", (self.homes, self.works), 0, None, LpContinuous) # The objective function is added to 'prob' first self.prob += ( lpSum([self.volumes[h][w] * self.utils[h][w] for (h, w) in self.choices]), "Sum_of_Transporting_Costs", ) # The supply maximum constraints are added to prob for each supply node (home) for h in self.homes: self.prob += ( lpSum([self.volumes[h][w] for w in self.works]) <= self.homes[h], "Sum_of_Products_out_of_Home_%s" % h, ) # The demand minimum constraints are added to prob for each demand node (work) for w in self.works: self.prob += ( lpSum([self.volumes[h][w] for h in self.homes]) >= self.works[w], "Sum_of_Products_into_Work%s" % w, )
def __generar_restricciones(self): X = LpVariable.dicts('X', self.variables, cat = LpBinary) self.cursado = LpProblem("Cursado",LpMaximize) # "\n\n Restricciones de dia-modulo\n\n" i = 1 for r in self.r1.values(): self.cursado += lpSum([X["".join(x)] for x in r]) <= 1, \ "_1C" + str(i).zfill(3) i += 1 #"\n\n Restricciones de cursado completo\n\n" for r in self.r2.values(): self.cursado += int(r[0][0]) *X[r[0][1]+r[0][2]] == lpSum([X["".join(x[1:])] for x in r]), \ "_2C" + str(i).zfill(3) i += 1 #""" #"\n\n Restricciones 1 sola comision\n\n" for r in self.r3.values(): self.cursado += int(r[0][0]) *X[r[0][1]] == lpSum([X["".join(x[1:])] for x in r]), \ "_3C" + str(i).zfill(3) i += 1 #"\n\n Restricciones de Colision\n\n" for r in self.r4.values(): self.cursado += lpSum([X["".join(x)] for x in r]) <= 1, \ "_4C" + str(i).zfill(3) i += 1 #"\n\n Restricciones de franja horaria\n\n" for r in [x + "" for x in ["".join(x) for x in self.r5]]: self.cursado += X[r] == 0, \ "_5C" + str(i).zfill(3) i += 1 self.X = X
class GenericSeparation(object): def __init__(self, origProb, x0): self.prob = origProb self.iter = 1 self.x0 = x0 self.var = origProb.variablesDict() self.dim = len(self.var) self.currentXtremePoint = {} self.solver = None self.c = dict(list((v.name,c) for v,c in origProb.objective.iteritems())) for v in self.var: if v in self.c: continue else: self.c[v] = 0.0 self.generate_separation_problem() self.piCurrent = dict([(v.name, 0) for v in self.var.values()]) self.piPrevious = dict([(v.name, 0) for v in self.var.values()]) self.extremePoints = [] self.f = Figure() def generate_separation_problem(self): self.sepProb = LpProblem (name='separation '+self.prob.name, sense=LpMinimize) self.pi = dict(list((v,LpVariable('pi'+v, None, None, LpContinuous, None)) for v in self.var)) self.sepProb += lpSum(self.pi[v]*self.x0[v] for v in self.var) def generate_xtreme_point(self): obj = LpConstraintVar() for v in self.prob.variables(): obj.addVariable(v, self.piCurrent[v.name]) self.prob.setObjective(obj) self.prob.solve() #solvers.COIN_CMD.solve(self.prob) for v in self.var: self.currentXtremePoint[v] = self.var[v].value() if self.output == 1: currentXtremePointList = self.currentXtremePoint.items() currentXtremePointList.sort() for v in currentXtremePointList: print v[0]+'\t', v[1] self.extremePoints.append(self.currentXtremePoint.values()) return self.prob.objective.value() def add_inequality(self): # change this, you should not access sense directly call a method self.sepProb += lpSum (self.currentXtremePoint[v]*self.pi[v] for v in self.var) >= 1 def separate(self, output = False, p = None): self.output = output while True: print 'Iteration ', self.iter if self.generate_xtreme_point() >= 1-EPS: break self.add_inequality() if self.output: print "Separation problem solution status:", LpStatus[self.sepProb.solve()] for v in self.var: if self.pi[v].value() is not None: print self.pi[v].name+'\t\t', self.pi[v].value() else: print self.pi[v].name+'\t\t', 0 self.piPrevious = deepcopy(self.piCurrent) for v in self.var: if self.pi[v].value() is not None: self.piCurrent[v] = self.pi[v].value() else: self.piCurrent[v] = 0 self.iter += 1 if p is not None: self.f.initialize() self.f.add_polyhedron(p, label = 'Polyhedron P') xList = (self.x0.values()[0], self.x0.values()[1]) if len(self.extremePoints) > 2: pp = Polyhedron2D(points = self.extremePoints) self.f.add_polyhedron(pp, color = 'red', linestyle = 'dashed', label = 'Convex Hull of Generated Points') elif len(self.extremePoints) == 1: self.f.add_point(self.extremePoints[0], radius = 0.05, color = 'green') self.f.add_text(self.extremePoints[0][0]-0.5, self.extremePoints[0][1]-0.08, '$x^0$') else: self.f.add_line_segment(self.extremePoints[0], self.extremePoints[1], color = 'red', linestyle = 'dashed', label = 'Convex Hull of Generated Points') self.f.set_xlim(p.plot_min[0], p.plot_max[0]) self.f.set_ylim(p.plot_min[1], p.plot_max[1]) self.f.add_point(xList, radius = 0.05, color = 'red') self.f.add_text(xList[0]-0.5, xList[1]-0.08, '$x^*$') dList = (self.piCurrent.values()[0], self.piCurrent.values()[1]) self.f.add_line(dList, 1, p.plot_max, p.plot_min, color = 'green', linestyle = 'dashed', label = 'Separating Hyperplane') self.f.show() if self.output: print self.sepProb.objective.value()
def generate_separation_problem(self): self.sepProb = LpProblem (name='separation '+self.prob.name, sense=LpMinimize) self.pi = dict(list((v,LpVariable('pi'+v, None, None, LpContinuous, None)) for v in self.var)) self.sepProb += lpSum(self.pi[v]*self.x0[v] for v in self.var)
class TransProblem(object): def __init__(self, home_list, work_list, util_matrix): """ Input a list of utils utils = [ #Works #1 2 3 4 5 [2,4,5,2,1],#A Homes [3,1,3,2,3] #B ] """ self.util_matrix = util_matrix self.homes = dict((home, home.houses) for home in home_list) self.works = dict((work, work.jobs) for work in work_list) self.utils = makeDict([home_list, work_list], util_matrix, 0) # Creates the 'prob' variable to contain the problem data self.prob = LpProblem("Residential Location Choice Problem", LpMinimize) # Creates a list of tuples containing all the possible location choices self.choices = [(h, w) for h in self.homes for w in self.works.keys()] # A dictionary called 'volumes' is created to contain the referenced variables(the choices) self.volumes = LpVariable.dicts("choice", (self.homes, self.works), 0, None, LpContinuous) # The objective function is added to 'prob' first self.prob += ( lpSum([self.volumes[h][w] * self.utils[h][w] for (h, w) in self.choices]), "Sum_of_Transporting_Costs", ) # The supply maximum constraints are added to prob for each supply node (home) for h in self.homes: self.prob += ( lpSum([self.volumes[h][w] for w in self.works]) <= self.homes[h], "Sum_of_Products_out_of_Home_%s" % h, ) # The demand minimum constraints are added to prob for each demand node (work) for w in self.works: self.prob += ( lpSum([self.volumes[h][w] for h in self.homes]) >= self.works[w], "Sum_of_Products_into_Work%s" % w, ) def solve(self): # The problem data is written to an .lp file self.prob.writeLP("ResidentialLocationChoiceProblem.lp") # The problem is solved using PuLP's choice of Solver self.prob.solve(solvers.GLPK()) # print the utility matrix print "Utility Matrix", self.util_matrix # The status of the solution is printed to the screen print "Status:", LpStatus[self.prob.status] # The optimised objective function value is printed to the screen print "Total Utility = ", value(self.prob.objective) def get_solution(self): # put the solution variables into a dict sol_var = {} for vol in self.prob.variables(): sol_var[vol.name] = vol.varValue # construct the solution dict opt_sol = {} for home in self.homes: for work in self.works: key = "choice" + "_" + str(home) + "_" + str(work) opt_sol[(work, home)] = sol_var[key] print (work, home), opt_sol[(work, home)] return opt_sol
cur_index, parent, branch_var, 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 "" print "Node: %s, Depth: %s, LB: %s" %(cur_index,cur_depth,LB) #==================================== # 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: print "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,