def ilp(prods, n_prods, alpha): S1, S2, S3, S4 = segregate(prods, n_prods, alpha) x = np.array([0.0 for i in range(n_prods)]) d = 0 for prod in S1: x[prod.index] = 1 d = d + (prod.q - alpha) rev = [-1.0 for i in range(n_prods)] qdiff = [-1.0 for i in range(n_prods)] for prod in S2: ind = prod.index rev[ind] = prod.r qdiff[ind] = prod.q - alpha for prod in S3: ind = prod.index rev[ind] = prod.r qdiff[ind] = prod.q - alpha m = Model('ilp') m.verbose = False y = [m.add_var(var_type=BINARY) for i in range(n_prods)] m.objective = maximize(xsum(rev[i] * y[i] for i in range(n_prods))) m += xsum(qdiff[i] * y[i] for i in range(n_prods)) >= -1 * d m.optimize() selected = np.array([y[i].x for i in range(n_prods)]) import pdb pdb.set_trace() selected = np.floor(selected + 0.01) import pdb pdb.set_trace() return x + selected, d
def test_cutting_stock(solver: str): n = 10 # maximum number of bars L = 250 # bar length m = 4 # number of requests w = [187, 119, 74, 90] # size of each item b = [1, 2, 2, 1] # demand for each item # creating the model model = Model(solver_name=solver) x = {(i, j): model.add_var(obj=0, var_type=INTEGER, name="x[%d,%d]" % (i, j)) for i in range(m) for j in range(n)} y = { j: model.add_var(obj=1, var_type=BINARY, name="y[%d]" % j) for j in range(n) } # constraints for i in range(m): model.add_constr(xsum(x[i, j] for j in range(n)) >= b[i]) for j in range(n): model.add_constr(xsum(w[i] * x[i, j] for i in range(m)) <= L * y[j]) # additional constraints to reduce symmetry for j in range(1, n): model.add_constr(y[j - 1] >= y[j]) # optimizing the model model.optimize() # sanity tests assert model.status == OptimizationStatus.OPTIMAL assert abs(model.objective_value - 3) <= 1e-4 assert sum(x.x for x in model.vars) >= 5
def mip_optimization(cal_df, y, constrain=3, daily_weights=None): """Mixed integer linear programming optimization with constraints. Args: y (numpy.ndarray): sum of daily features (dim=#ofdays) constrain (int): minimum days in office daily_weights (array): weighting of days, e.g. if you prefer to come on mondays Return: """ # daily weighting u = np.ones(len(y)) if daily_weights == None else daily_weights I = range(len(y)) # idx for days for summation m = Model("knapsack") # MIP model w = [m.add_var(var_type=BINARY) for i in I] # weights to optimize m.objective = maximize(xsum(y[i] * w[i] for i in I)) # optimization function m += xsum(w[i] * u[i] for i in I) <= constrain # constraint m.optimize() #selected = [i for i in I if w[i].x >= 0.99] selected = [w[i].x for i in I] df = pd.DataFrame(columns=["home_office"], index=cal_df.index, data={'home_office': selected}) return df
def optimal_split(self, ratio=0.5): """Function that returns the optimal split for a certain ratio of the potential (default to 0.5) Keyword Arguments: ratio {float} -- The ratio of the potential needed (default: {0.5}) Returns: list tuple -- Returns the tuple (A, B) representing the partitions. """ if (sum(self.game_state) == 1): if (randint(1, 100) <= 50): return self.game_state, [0] * (self.K + 1) else: return [0] * (self.K + 1), self.game_state else: m = Model("") x = [m.add_var(var_type=INTEGER) for i in self.game_state] m.objective = minimize( sum([ 2**(-(self.K - i)) * c for c, i in zip(x, range(self.K + 1)) ]) - ratio * self.potential(self.game_state)) for i in range(len(x)): m += 0 <= x[i] m += x[i] <= self.game_state[i] m += sum([ 2**(-(self.K - i)) * c for c, i in zip(x, range(self.K + 1)) ]) >= ratio * self.potential(self.game_state) m.optimize() Abis = [0] * (self.K + 1) for i in range(len(x)): Abis[i] = int(x[i].x) B = [z - a for z, a in zip(self.game_state, Abis)] return Abis, B
def test_knapsack(solver: str): p = [10, 13, 18, 31, 7, 15] w = [11, 15, 20, 35, 10, 33] c, I = 47, range(len(w)) m = Model("knapsack", solver_name=solver) x = [m.add_var(var_type=BINARY) for i in I] m.objective = maximize(xsum(p[i] * x[i] for i in I)) m += xsum(w[i] * x[i] for i in I) <= c, "cap" m.optimize() assert m.status == OptimizationStatus.OPTIMAL assert round(m.objective_value) == 41 m.constr_by_name("cap").rhs = 60 m.optimize() assert m.status == OptimizationStatus.OPTIMAL assert round(m.objective_value) == 51 # modifying objective function m.objective = m.objective + 10 * x[0] + 15 * x[1] assert abs(m.objective.expr[x[0]] - 20) <= 1e-10 assert abs(m.objective.expr[x[1]] - 28) <= 1e-10
def test_linexpr_x(solver: str, val: int): m = Model("bounds", solver_name=solver) x = m.add_var(lb=0, ub=2 * val) y = m.add_var(lb=val, ub=2 * val) obj = x - y assert obj.x is None # No solution yet. m.objective = maximize(obj) m.optimize() assert m.status == OptimizationStatus.OPTIMAL assert round(m.objective_value) == val assert round(x.x) == 2 * val assert round(y.x) == val # Check that the linear expression value is equal to the same expression # calculated from the values of the variables. assert abs((x + y).x - (x.x + y.x)) < TOL assert abs((x + 2 * y).x - (x.x + 2 * y.x)) < TOL assert abs((x + 2 * y + x).x - (x.x + 2 * y.x + x.x)) < TOL assert abs((x + 2 * y + x + 1).x - (x.x + 2 * y.x + x.x + 1)) < TOL assert abs((x + 2 * y + x + 1 + x / 2).x - (x.x + 2 * y.x + x.x + 1 + x.x / 2)) < TOL
def do_matching(graph, visualize=True): print("Starting model") weights = dict() graph = {int(key): graph[key] for key in graph} E = set() V = graph.keys() for v in V: original = v for u, weight in graph[original]: s, t = (u, v) if u < v else (v, u) edge = (s, t) E.add(edge) weights[original, u] = weight if visualize: graph = nx.Graph() graph.add_nodes_from(V) graph.add_edges_from(E) nx.draw_kamada_kawai(graph) plt.show() model = Model("Maximum matching") edge_vars = {e: model.add_var(var_type=BINARY) for e in E} for v in V: model += xsum(edge_vars[s, t] for s, t in E if v in [s, t]) <= 1 model.objective = maximize( xsum( xsum(((weights[edge] + weights[edge[1], edge[0]]) / 2) * edge_vars[edge] for edge in E) for edge in E)) model.optimize(max_seconds=300) return sorted([e for e in E if edge_vars[e].x > .01])
def min_unproportionality_allocation(utilities: Dict[int, List[float]], m: Model) -> None: """ Computes (one of) the item allocation(s) which minimizes global unproportionality (observe we only sum unproportionality when it is larger than 0). :param utilities: the dictionary representing the utility profile, where each key is an agent and its value an array of floats such that the i-th float is the utility of the i-th item for the key-agent. :param m: the MIP model to optimize. :return: a dictionary mapping to each agent the bundle which has been assigned to her so that unproportionality is minimized. """ agents, items = len(utilities), len(list(utilities.values())[0]) dummies = [ m.add_var(name='dummy_{}'.format(agent), var_type=CONTINUOUS) for agent in range(agents) ] m.objective = minimize( xsum( m.var_by_name('dummy_{}'.format(agent)) for agent in range(agents))) for agent in range(agents): m += m.var_by_name('dummy_{}'.format(agent)) >= 0 m += m.var_by_name('dummy_{}'.format(agent)) >= (sum(utilities[agent][item] for item in range(items)) / agents)\ - (sum(utilities[agent][item] * m.var_by_name('assign_{}_{}'.format(item ,agent)) for item in range(items))) m.optimize()
def __init__(self, model: mip.Model): if model.status == mip.OptimizationStatus.LOADED: logger.debug("model not runned yet, checking if feasible or not") model.emphasis = 1 # feasibility model.preprocess = 1 # -1 automatic, 0 off, 1 on. model.optimize() assert (model.status == mip.OptimizationStatus.INFEASIBLE ), "model is not linear infeasible" self.model = model
def do_matching_stable(graph, visualize=True, individual=1, communal=10000000): print("Starting model") weights = dict() graph = {int(key): graph[key] for key in graph} E = set() V = graph.keys() inputs = {v: [] for v in V} outputs = {v: [] for v in V} for v in V: original = v for u, weight in graph[original]: s, t = (u, v) if u < v else (v, u) edge = (s, t) E.add(edge) weights[(original, u)] = weight outputs[original].append(u) inputs[u].append(original) if visualize: graph = nx.Graph() graph.add_nodes_from(V) graph.add_edges_from(E) nx.draw_kamada_kawai(graph) plt.show() model = Model("Rogue Couples based") edge_vars = {e: model.add_var(var_type=BINARY) for e in E} undirected = dict() for e in E: undirected[e] = edge_vars[e] undirected[e[1], e[0]] = edge_vars[e] rogue_vars = {e: model.add_var(var_type=BINARY) for e in E} partners = dict() for v in V: partners[v] = model.add_var() partners[v] = xsum(edge_vars[s, t] for s, t in E if v in [s, t]) model += partners[v] <= 1 for (u, v), rogue_var in rogue_vars.items(): v_primes = [ vp for vp in outputs[u] if weights[(u, vp)] < weights[(u, v)] ] u_primes = [ up for up in outputs[v] if weights[(v, up)] < weights[(v, u)] ] model += 1 - partners[v] - partners[u] + xsum( undirected[u, vp] for vp in v_primes) + xsum(undirected[up, v] for up in u_primes) <= rogue_var model.objective = maximize(individual * xsum( ((weights[edge] + weights[edge[1], edge[0]]) / 2) * edge_vars[edge] for edge in E) - communal * xsum(rogue_vars[edge] for edge in E)) model.optimize(max_seconds=300) return sorted([e for e in E if edge_vars[e].x > .01])
def test_variable_bounds(solver: str, val: int): m = Model("bounds", solver_name=solver) x = m.add_var(var_type=INTEGER, lb=0, ub=2 * val) y = m.add_var(var_type=INTEGER, lb=val, ub=2 * val) m.objective = maximize(x - y) m.optimize() assert m.status == OptimizationStatus.OPTIMAL assert round(m.objective_value) == val assert round(x.x) == 2 * val assert round(y.x) == val
def test_queens(solver: str): """MIP model n-queens""" n = 50 queens = Model("queens", MAXIMIZE, solver_name=solver) queens.verbose = 0 x = [[ queens.add_var("x({},{})".format(i, j), var_type=BINARY) for j in range(n) ] for i in range(n)] # one per row for i in range(n): queens += xsum(x[i][j] for j in range(n)) == 1, "row({})".format(i) # one per column for j in range(n): queens += xsum(x[i][j] for i in range(n)) == 1, "col({})".format(j) # diagonal \ for p, k in enumerate(range(2 - n, n - 2 + 1)): queens += ( xsum(x[i][j] for i in range(n) for j in range(n) if i - j == k) <= 1, "diag1({})".format(p), ) # diagonal / for p, k in enumerate(range(3, n + n)): queens += ( xsum(x[i][j] for i in range(n) for j in range(n) if i + j == k) <= 1, "diag2({})".format(p), ) queens.optimize() assert queens.status == OptimizationStatus.OPTIMAL # "model status" # querying problem variables and checking opt results total_queens = 0 for v in queens.vars: # basic integrality test assert v.x <= TOL or v.x >= 1 - TOL total_queens += v.x # solution feasibility rows_with_queens = 0 for i in range(n): if abs(sum(x[i][j].x for j in range(n)) - 1) <= TOL: rows_with_queens += 1 assert abs(total_queens - n) <= TOL # "feasible solution" assert rows_with_queens == n # "feasible solution"
def possible(c, n, history): model = Model() model.verbose = 0 assign = [[model.add_var(var_type=BINARY) for j in range(c)] for i in range(n)] for i in range(n): model += xsum(assign[i][j] for j in range(c)) == 1 for (tab, sc) in history: model += xsum(assign[i][tab[i]] for i in range(n)) == sc model.optimize() tab = [max([(assign[i][j].x, j) for j in range(c)])[1] for i in range(n)] return tab
def do_matching_double_matches(graph, wants_two_matches=None): print("Starting model") weights = dict() graph = {int(key): graph[key] for key in graph} E = set() V = graph.keys() if not wants_two_matches: wants_two_matches = {v: True for v in V} inputs = {v: [] for v in V} outputs = {v: [] for v in V} for v in V: original = v for u, weight in graph[original]: s, t = (u, v) if u < v else (v, u) edge = (s, t) E.add(edge) weights[(original, u)] = weight outputs[original].append(u) inputs[u].append(original) model = Model("Allow double matches based") edge_vars = {e: model.add_var(var_type=BINARY) for e in E} undirected = dict() for e in E: undirected[e] = edge_vars[e] undirected[e[1], e[0]] = edge_vars[e] is_best = {e: model.add_var(var_type=BINARY) for e in undirected.keys()} penalty = {v: model.add_var(var_type=BINARY) for v in V} happiness = {v: model.add_var() for v in V} epsilon = .0000001 C = 1e3 for v in V: model += xsum(edge_vars[s, t] for s, t in E if v in [s, t]) <= 1 + penalty[v] * wants_two_matches[v] model += happiness[v] <= xsum(edge_vars[s, t] for s, t in E if v in [s, t]) * C if outputs[v]: model += xsum(is_best[(v, m)] for m in outputs[v]) == 1 for m in outputs[v]: model += happiness[v] <= undirected[(v, m)] * weights[ (v, m)] + (1 - is_best[(v, m)]) * C else: happiness[v] <= 0 model.objective = maximize( xsum(happiness[v] for v in V) - epsilon * xsum(penalty[v] for v in V)) model.optimize(max_seconds=300) return sorted([e for e in E if edge_vars[e].x > .01])
def __init__(self, model: mip.Model): if model.status == mip.OptimizationStatus.LOADED: print("model not runned yet, checking if feasible or not") model.emphasis = 1 # feasibility model.preprocess = 1 # -1 automatic, 0 off, 1 on. model.optimize() assert ( model.status == mip.OptimizationStatus.INFEASIBLE ), "model is not linear infeasible" self.model = model self.iis_num_iterations = 0 self.iis_iterations = [] self.relax_slack_iterations = []
def test_mip_file(solver: str, instance: str): """Tests optimization of MIP models stored in .mps or .lp files""" m = Model(solver_name=solver) # optional file for optimal LP basis bas_file = "" iname = "" for ext in EXTS: if instance.endswith(ext): bas_file = instance.replace(ext, ".bas") if not exists(bas_file): bas_file = "" iname = basename(instance.replace(ext, "")) break assert iname in BOUNDS.keys() lb = BOUNDS[iname][0] ub = BOUNDS[iname][1] assert lb <= ub + TOL has_opt = abs(ub - lb) <= TOL max_dif = max(max(abs(ub), abs(lb)) * 0.01, TOL) m.read(instance) if bas_file: m.verbose = True m.read(bas_file) m.optimize(relax=True) print("Basis loaded!!! Obj value: %f" % m.objective_value) m.optimize(max_nodes=MAX_NODES) if m.status in [OptimizationStatus.OPTIMAL, OptimizationStatus.FEASIBLE]: assert m.num_solutions >= 1 m.check_optimization_results() assert m.objective_value >= lb - max_dif if has_opt and m.status == OptimizationStatus.OPTIMAL: assert abs(m.objective_value - ub) <= max_dif elif m.status == OptimizationStatus.NO_SOLUTION_FOUND: assert m.objective_bound <= ub + max_dif else: assert m.status not in [ OptimizationStatus.INFEASIBLE, OptimizationStatus.INT_INFEASIBLE, OptimizationStatus.UNBOUNDED, OptimizationStatus.ERROR, OptimizationStatus.CUTOFF, ] assert m.objective_bound <= ub + max_dif
def solve_zero_one_linear_program(c, A, b, solver): """Minimize c*x x is binary A*c <= b """ assert A.shape[1] == c.shape[0] assert A.shape[1] == b.shape[0] out = None if solver == "cvxpy": start = time.time() print("Solving integer program of shape {}...".format(A.shape)) # The variable we are solving for selection = cvxpy.Variable(c.shape[0], boolean=True) weight_constraint = A * selection <= b # We tell cvxpy that we want to maximize total utility # subject to weight_constraint. All constraints in # cvxpy must be passed as a list problem = cvxpy.Problem(cvxpy.Minimize(c * selection), [weight_constraint]) # Solving the problem problem.solve(solver=cvxpy.GLPK_MI, verbose=True) print("Integer program solved in {}!".format(time.time() - start)) out = np.array(list(problem.solution.primal_vars.values())[0], dtype=bool) elif solver == "mip": m = Model() x = [m.add_var(var_type=BINARY) for i in range(len(c))] m.objective = minimize(xsum(c[i] * x[i] for i in range(len(c)))) for i in range(A.shape[0]): m += xsum(A[i, j] * x[j] for j in range(len(c))) <= b[i] m.optimize() out = np.array([x[i].x >= 0.99 for i in range(len(c))]) elif solver == "approximate": print("using approximate solution") solution = linprog(c=c, A_ub=A, b_ub=b) out = remove_overlapping_in_order(A=A, out=np.round(solution.x) > 0) else: raise ValueError("Solver {} not recognized".format(solver)) assert out is not None return out
def solveTSP(adjMatrixSubGraph, listPath, nodeKantor, listNode, mapIdxToNode, mapNodeToIdx): model = Model() listNode.insert(0, nodeKantor) n = len(listNode) # add variable x = [[model.add_var(var_type=BINARY) for j in range(n)] for i in range(n)] y = [model.add_var() for i in range(n)] # add objective function model.objective = minimize( xsum(adjMatrixSubGraph[mapNodeToIdx[listNode[i]]][mapNodeToIdx[ listNode[j]]] * x[i][j] for i in range(n) for j in range(n))) V = set(range(n)) # constraint : leave each city only once for i in V: model += xsum(x[i][j] for j in V - {i}) == 1 # constraint : enter each city only once for i in V: model += xsum(x[j][i] for j in V - {i}) == 1 # subtour elimination for (i, j) in product(V - {0}, V - {0}): if i != j: model += y[i] - (n + 1) * x[i][j] >= y[j] - n # optimizing model.optimize(max_seconds=30) res = [] # checking if a solution was found if model.num_solutions: print("SOLUTION FOUND") for i in range(n): for j in range(n): if (x[i][j].x == 1): print( listNode[i], " ", listNode[j], " : ", listPath[mapNodeToIdx[listNode[i]]][mapNodeToIdx[ listNode[j]]]) res.append((listNode[i], listNode[j])) else: print("gak ketemu") return res
def solve(active: list, centers: list, sets: list, M: int) -> list: N, K = len(active), len(sets) ### model and variables m = Model(sense=MAXIMIZE, solver_name=CBC) # whether the ith set is picked x = [m.add_var(name=f"x{i}", var_type=BINARY) for i in range(K)] # whether the ith point is covered y = [m.add_var(name=f"y{i}", var_type=BINARY) for i in range(N)] ### constraints m += xsum(x) == M, "number_circles" for i in range(N): # if yi is covered, at least one set needs to have it included = [x[k] for k in range(K) if active[i] in sets[k]] m += xsum(included) >= y[i], f"inclusion{i}" ### objective: maximize number of circles covered m.objective = xsum(y[i] for i in range(N)) m.emphasis = 2 # emphasize optimality m.verbose = 1 status = m.optimize() circles = [centers[i] for i in range(K) if x[i].x >= 0.99] covered = {active[i] for i in range(N) if y[i].x >= 0.99} return circles, covered
def test_float(solver: str, val: int): m = Model("bounds", solver_name=solver) x = m.add_var(lb=0, ub=2 * val) y = m.add_var(lb=val, ub=2 * val) obj = x - y # No solution yet. __float__ MUST return a float type, so it returns nan. assert obj.x is None assert math.isnan(float(obj)) m.objective = maximize(obj) m.optimize() assert m.status == OptimizationStatus.OPTIMAL # test vars. assert x.x == float(x) assert y.x == float(y) # test linear expressions. assert float(x + y) == (x + y).x
def do_matching_two_round(graph): print("Starting model") weights = dict() graph = {int(key): graph[key] for key in graph} E = set() V = graph.keys() inputs = {v: [] for v in V} outputs = {v: [] for v in V} for v in V: original = v for u, weight in graph[original]: s, t = (u, v) if u < v else (v, u) edge = (s, t) E.add(edge) weights[(original, u)] = weight outputs[original].append(u) inputs[u].append(original) model = Model("Rogue Couples based") edge_vars = {e: model.add_var(var_type=BINARY) for e in E} undirected = dict() for e in E: undirected[e] = edge_vars[e] undirected[e[1], e[0]] = edge_vars[e] second_vars = {e: model.add_var(var_type=BINARY) for e in E} partners = dict() second_round_partners = dict() for v in V: partners[v] = model.add_var() model += partners[v] == xsum(edge_vars[s, t] for s, t in E if v in [s, t]) model += partners[v] <= 1 for v in V: second_round_partners[v] = model.add_var() model += second_round_partners[v] == xsum(second_vars[s, t] for s, t in E if v in [s, t]) model += second_round_partners[v] <= 1 for e in E: u, v = e model += second_vars[(u, v)] <= 2 - partners[v] - partners[u] model.objective = maximize( xsum(((weights[edge] + weights[edge[1], edge[0]]) / 2) * (edge_vars[edge] + second_vars[edge]) for edge in E)) model.optimize(max_seconds=1000) return sorted([e for e in E if edge_vars[e].x > .01] + [e for e in E if second_vars[e].x > .01])
class NaiveMIPModel: m: Model = None customer_facility_map: List[List[Var]] = None facility_customer_map: List[List[Var]] = None def __init__(self, facilities: List[Facility], customers: List[Customer]): self.m = Model('NaiveFacilityMIP', solver_name=CBC) self.customer_facility_map = [[self.m.add_var(var_type=BINARY) for facility in range(len(facilities))] for customer in range(len(customers))] self.facility_customer_map = list(zip(*self.customer_facility_map)) for customer in range(len(customers)): self.m.add_constr(xsum(self.customer_facility_map[customer]) == 1) for facility in range(len(facilities)): self.m.add_constr(xsum([customers[index].demand * variable for index, variable in enumerate(self.facility_customer_map[facility])]) <= facilities[facility].capacity) facility_enabled = [self.m.add_var(var_type=BINARY) for facility in range(len(facilities))] for facility in range(len(facilities)): for customer in range(len(customers)): self.m.add_constr(self.facility_customer_map[facility][customer] <= facility_enabled[facility]) self.m.objective = xsum([facilities[f].setup_cost * facility_enabled[f] for f in range(len(facilities))]) + \ xsum([euclideam_length(facilities[facility].location, customers[customer].location) * self.facility_customer_map[facility][customer] for facility in range(len(facilities)) for customer in range(len(customers))]) self.m.verbose = True self.m.max_seconds = 60 * 20 def optimize(self): self.m.optimize() def get_best_score(self): return self.m.objective_value def get_solution(self): solution = [] for customer in self.customer_facility_map: for index, facility in enumerate(customer): if facility.x >= 0.99: solution.append(index) break return solution
def Int_Knapsack(f,d, V_d, Kf): p = list(np.ones((len(V_d),),dtype=int)) m = Model("knapsack") #x = [m.add_var(var_type=BINARY) for i in list(V_d.keys())] x = [(i,m.add_var(var_type=BINARY)) for i in list(V_d.keys())] m.objective = maximize(xsum(p[i] * x[i][1] for i in range(len(x)))) m += xsum(V_d[x[i][0]] * x[i][1] for i in range(len(x))) <= Kf[f] m.optimize() #selected = [i for i in list(V_d.keys()) if x[i].x >= 0.99] selected = [x[i][0] for i in range(len(x)) if x[i][1].x >= 0.99] #print("selected items: {}".format(selected)) y=(d,selected,f) return y #sol = Int_Knapsack(f,d,V_d, Kf)
def max_utilitarian_welfare_allocation(utilities: Dict[int, List[float]], m: Model) -> None: """ Computes (one of) the item allocation(s) which maximizes utilitarian welfare, returning the optimized model. :param utilities: the dictionary representing the utility profile, where each key is an agent and its value an array of floats such that the i-th float is the utility of the i-th item for the key-agent. :param m: the MIP model which represents the integer linear program. """ agents, items = len(utilities), len(list(utilities.values())[0]) m.objective = maximize( xsum(utilities[agent][item] * m.var_by_name('assign_{}_{}'.format(item, agent)) for item in range(items) for agent in range(agents))) m.optimize()
def solve(self): """Try to solve the problem and identify possible matches.""" self._check_linear_dependency() A_eq = self.A3D.reshape(-1, self.n_1 * self.n_2) n = self.n_1 * self.n_2 # PYTHON MIP: model = Model() x = [model.add_var(var_type=BINARY) for i in range(n)] model.objective = minimize(xsum(x[i] for i in range(n))) for i, row in enumerate(A_eq): model += xsum(int(row[j]) * x[j] for j in range(n)) == int(self.b[i]) model.emphasis = 2 model.verbose = 0 model.optimize(max_seconds=2) self.X_binary = np.asarray([x[i].x for i in range(n) ]).reshape(self.n_1, self.n_2)
def get_lineups(self, slate, ptcol, lineups, salcap=50000): positions = slate['positions'] pool= pd.concat(slate['players'].values(),ignore_index='True').drop(columns='position')\ .drop_duplicates().reset_index(drop=True) #Establish positions eligibility data structure elig = [[ 1 if plyr['name'] in list(slate['players'][pos]['name']) else 0 for i, pos in enumerate(positions) ] for skip, plyr in pool.iterrows()] pts = list(pool[ptcol]) #Set up player salary list sal = list(pool['salary']) #Set up range just for short reference I = range(len(pts)) J = range(len(positions)) #Set up results results = [] m = Model() m.verbose = False x = [[m.add_var(var_type=BINARY) for j in J] for i in I] m.objective = maximize( xsum(x[i][j] * elig[i][j] * pts[i] for i in I for j in J)) #Apply salary cap constraint m += xsum((x[i][j] * sal[i] for i in I for j in J)) <= salcap #Apply one player per position constraint for j in J: m += xsum(x[i][j] for i in I) == 1 #apply max one position per player constraint for i in I: m += xsum(x[i][j] for j in J) <= 1 for lineup in range(lineups): print(lineup) m.optimize() #Add lineup to results idx = [(i, j) for i in I for j in J if x[i][j].x >= 0.99] results.append( pd.concat([pool.iloc[i:i + 1] for i, j in idx], ignore_index=True)) results[-1]['position'] = [positions[j] for i, j in idx] #Apply constraint to ensure this player combination will not be repeated (cannot have three overlapping players for diversity) m += xsum(x[i][j] for i, skip in idx for j in J) <= len(positions) - 3 return results
def knapsack(): p = [10, 13, 18, 31, 7, 15] w = [11, 15, 20, 35, 10, 33] c, I = 47, range(len(w)) m = Model("knapsack") x = [m.add_var(var_type=BINARY) for i in I] m.objective = maximize(xsum(p[i] * x[i] for i in I)) m += xsum(w[i] * x[i] for i in I) <= c print(m.optimize())
def clique_cuts(self, S, a): s_aux = list(range(len(S))) perms = np.asarray(list(permutations(s_aux))) perms = [np.asarray(s) for s in perms] K = [[0] * len(S) for i in range(len(perms))] for i in range(len(K)): soma = 0 for j in range(len(K[i])): if j == 0: soma += self.instance.e[S[perms[i][j]]][a] else: soma += self.instance.times[S[perms[i][j - 1]]][a] for aux in range(j, len(K[i])): K[i][perms[i][aux]] = soma m = Model('clique_cuts') t = [ m.add_var(var_type=CONTINUOUS, lb=0, name='t({})'.format(i)) for i in S ] m.objective = xsum(i for i in t) for i in range(len(K)): m += xsum(K[i][j] * t[j] for j in range(len(K[i]))) >= 1, 'K({})'.format(i) m.optimize() soma = 0 for i in range(len(S)): soma += t[i].x * self.x[S[i]][a][1] # xt >= is a valid inequality. Thus, a violated cut is < 1 if (1 - soma) > 0.00001: # < 1: return xsum(t[i].x * self.x[S[i]][a][0] for i in range(len(S))) >= 1 return 0
def solve_it(input_data): lines = input_data.split('\n') firstLine = lines[0].split() item_count = int(firstLine[0]) capacity = int(firstLine[1]) values = [0] * item_count weights = [0] * item_count for i in range(1, item_count + 1): line = lines[i] parts = line.split() values[i - 1] = int(parts[0]) weights[i - 1] = int(parts[1]) m = Model("knapsack") m.setParam('OutputFlag', False) m.setParam("Threads", cpu_count()) x = m.addVars(item_count, vtype=GRB.BINARY, name="items") m.setObjective(LinExpr(values, [x[i] for i in range(item_count)]), GRB.MAXIMIZE) m.addLConstr(LinExpr(weights, [x[i] for i in range(item_count)]), GRB.LESS_EQUAL, capacity, name="capacity") m.update() m.optimize() if m.status == 2: opt = 1 else: opt = 0 #return int(m.objVal), opt, [int(var.x) for var in m.getVars()] output_data = f"{int(m.objVal)} {opt}\n" + " ".join( map(str, [int(var.x) for var in m.getVars()])) return output_data
def random_knapsack(n: int, interval): I = range(n) p = [randrange(*interval) for _ in I] w = [randrange(*interval) for _ in I] c = round(sum(interval) / 2 * n) m = Model("random-knapsack") x = [m.add_var(var_type=BINARY) for i in I] m.objective = maximize(xsum(p[i] * x[i] for i in I)) m += xsum(w[i] * x[i] for i in I) <= c start = monotonic() print(m.optimize()) print(f"DURATION: {(monotonic() - start) * 1000} ms")