def callback(cb: CallbackModel, where: Where): if where == Where.PathMIPCuts: epsilon = 1e-4 relax = cb.x # Enumerate cuts for |S| = 2 for i in range(n)[1:-1]: for j in range(n)[1:-1]: # not depot nodes in S if i == 0 or j == n - 1 or i == j: continue rhs = math.ceil((d[i] + d[j]) / Q) lhs = 0 lhsIdxs = [] for e, edge in enumerate(E): # inside S if (i, j) == edge or (j, i) == edge: continue # if either end of edge is in S if i == edge[0] or i == edge[1] or j == edge[0] or j == edge[1]: lhs += relax[e] lhsIdxs += [e] if lhs < rhs - epsilon: cb.addCut(xsum(g.vars[e] for e in lhsIdxs) >= rhs)
path = [] index = E.index((0, i)) path.append(index) cost += c[index] index = E.index((i, n - 1)) path.append(index) cost += c[index] cb.addPath(cost, path) m.setCallback(callback) # set partition constriants for i in range(n)[1:-1]: m += xsum(x * 1 for x in g.vars if i == x.source) == 1 # packing set for i in range(n)[1:-1]: m.addPackingSet([x for x in g.vars if i == x.source]) status = m.optimize() # print(f"ObjectiveValue {round(m.objectiveValue, 1)}") # get the variable values # for var in m.vars: # if var.x > 0: # print(f"{var.name} = {round(var.x, 1)}")
# sum_(j) x_ji - sum_(j) x_ij = 0 , forall i for i in range(n)[1:-1]: expr = LinExpr() [expr.addTerm(1, x) for x, e in zip(xsk, E) if e[1] == i] [expr.addTerm(-1, x) for x, e in zip(xsk, E) if e[0] == i] m.addConstr(expr == 0) # sum_(j,n-1) x_j,n-1 = 1 expr = LinExpr() [expr.addTerm(1, x) for x, e in zip(xsk, E) if e[1] == n - 1] m.addConstr(expr + xFeasiblity == 1) # capacity constraint # sum_(ij) d_i * x_ij <= Q m.addConstr(xsum(x * d[e[0]] for x, e in zip(xsk, E)) <= Q) # time stamp per vertex qt = [ m.addVar(lb=0, ub=max(b), obj=0, type="C", name=f"q_t_{i}_{k}") for i in range(n) ] # time winwos # q_ik + t_ij - q_jk <= (1 - x_ijk)M , forall (i,j) for j, e in enumerate(E): bigM = b[e[0]] + t[j] m.addConstr(qt[e[0]] * 1 - qt[e[1]] * 1 + xsk[j] * bigM <= bigM - t[j]) # a_i sum_(j) x_ijk <= q_ik for i in range(n)[1:-1]: expr = LinExpr()
# keep track of voyageEdges for constraints later tmp = list([eid["index"] for eid in voyageEdgeIds]) for j, e in enumerate(es): for h, eid in enumerate(tmp): if g.edges[e]["index"] == eid: voyageEdgeVarsIds[eid][i] = j tmp.remove(eid) break # graph vars vars = [gs[i].vars for i in range(k)] # sum_( i,j \in delta+(o^k)) x_ijk = 1 , forall k for i in range(k): source = gs[i].source m.addConstr(xsum((1, x) for x in vars[i] if source == x.source) == 1) for j, ks in enumerate(voyageEdgeVarsIds): expr = LinExpr() for i, h in ks.items(): x = vars[i][h] expr.addTerm(builder.demand["FFEPerWeek"][i], x) m.addConstr(expr <= builder.capacity[j]) status = m.optimize() # print(f"ObjectiveValue {round(m.objectiveValue, 5)}") # get the variable values # for var in m.vars: # if var.x > 0: # print(f"{var.name} = {round(var.x, 5)}")
# 0-1 Knapsack problem from flowty import Model, xsum from or_datasets import pisinger bunch = pisinger.fetch_knapsack("small", instance="knapPI_1_50_1000_1") name, n, c, p, w, z, x = bunch["instance"] m = Model() m.setParam("Algorithm", "MIP") for i in range(n): m.addVar(lb=0, ub=1, obj=-p[i], type="B") m.addConstr(xsum(w[i] * v for i, v in enumerate(m.vars)) <= c) status = m.optimize() # print(f"ObjectiveValue {round(m.objectiveValue)} == {-z}") # get the variable values # for var in m.vars: # if var.x > 0: # print(f"{var.name} = {round(var.x, 1)}")
index = E.index((i, n - 1)) xEdges[index] = 1 cost += c[index] cb.addSolution(cost, xEdges) # Verify solution if where == Where.PathMIPSolution: x = cb.x # candidate solution # check is solution is infeasible and skip it if so isInfeasible = False if isInfeasible: cb.skip() m.setCallback(callback) # set partitioning constraints for i in range(n)[1:-1]: m.addConstr(xsum(1 * x for x in g.vars if i == x.source) == 1) m.addPackingSet([x for x in g.vars if i == x.source]) status = m.optimize() # print(f"ObjectiveValue {round(m.objectiveValue, 1)}") # get the variable values # for var in m.vars: # if var.x > 0: # print(f"{var.name} = {round(var.x, 1)}")