def generate_constrs(self, model: Model): G = nx.DiGraph() r = [(v, v.x) for v in model.vars if v.name.startswith("x(")] U = [v.name.split("(")[1].split(",")[0] for v, f in r] V = [v.name.split(")")[0].split(",")[1] for v, f in r] N = list(set(U + V)) cp = CutPool() for i in range(len(U)): G.add_edge(U[i], V[i], capacity=r[i][1]) for (u, v) in product(N, N): if u == v: continue val, (S, NS) = nx.minimum_cut(G, u, v) if val <= 0.99: arcsInS = [(v, f) for i, (v, f) in enumerate(r) if U[i] in S and V[i] in S] if sum(f for v, f in arcsInS) >= (len(S) - 1) + 1e-4: cut = xsum(1.0 * v for v, fm in arcsInS) <= len(S) - 1 cp.add(cut) if len(cp.cuts) > 256: for cut in cp.cuts: model.add_cut(cut) return for cut in cp.cuts: model.add_cut(cut)
def generate_constrs(self, model: Model): xf, V_, cp, G = model.translate( self.x), self.V, CutPool(), nx.DiGraph() # valid edges for (u, v) in self.graph.edges(): try: edge = xf[u][v] G.add_edge(u, v, capacity=xf[u][v].x) except: pass for (u, v) in self.F: try: val, (S, NS) = nx.minimum_cut(G, u, v) if val <= 0.99: aInS = [(xf[i][j], xf[i][j].x) for (i, j) in product(V_, V_) if i != j and xf[i][j] and i in S and j in S] if sum(f for v, f in aInS) >= (len(S) - 1) + 1e-4: cut = xsum(1.0 * v for v, fm in aInS) <= len(S) - 1 cp.add(cut) if len(cp.cuts) > 256: for cut in cp.cuts: model += cut return except nx.NetworkXError: pass for cut in cp.cuts: model += cut
def generate_constrs(self, model: Model): xf = model.translate(self.x) yf = model.translate(self.y) V_ = range(self.instance.n) cp = CutPool() for a in range(self.instance.m): edges = [[] for i in range(self.instance.n)] for (u, v) in [ (k, l) for (k, l) in product(V_, range(self.instance.n + 1)) if k != l and abs(yf[k][l][a].x) > 1e-8 ]: print(yf[u][v][a].name, yf[u][v][a].x) edges[u].append(v) # print(edges) # input() cycles = [] for i in range(self.instance.n): c = self.cycles(edges[i], i, edges, [i], []) if c: for cycle in c: cycles.append(cycle) # print('cycles', cycles, 'a ', a) # input() for c in cycles: soma = 0 rhs = len(c) - 1 for i in range(rhs): u = c[i] v = c[i + 1] soma += yf[u][v][a].x if soma > rhs - 1 + 1e-8: cut = xsum(self.y[c[i]][c[i + 1]][a] for i in range(rhs)) <= rhs - 1 # print(cut) # input() cp.add(cut) for cut in cp.cuts: model += cut print('Total cuts: {}'.format(len(cp.cuts))) input()
def generate_constrs(self, model: Model): x_, N, cp = model.translate(self._x), range(len(self._x)), CutPool() outa = [[j for j in N if x_[i][j].x >= 0.99] for i in N] for node in N: S = set(subtour(N, outa, node)) if S: AS = [(i, j) for (i, j) in product(S, S) if i != j] cut = xsum(x_[i][j] for (i, j) in AS) <= len(S) - 1 cp.add(cut) for cut in cp.cuts: model += cut
def generate_constrs(self, model: Model): xf, V_, cp = model.translate(self.x), self.V, CutPool() for (u, v) in [(k, l) for (k, l) in product(V_, V_) if k != l and xf[k][l]]: G.add_edge(u, v, capacity=xf[u][v].x) for (u, v) in F: val, (S, NS) = nx.minimum_cut(G, u, v) if val <= 0.99: aInS = [(xf[i][j], xf[i][j].x) for (i, j) in product(V_, V_) if i != j and xf[i][j] and i in S and j in S] if sum(f for v, f in aInS) >= (len(S)-1)+1e-4: cut = xsum(1.0*v for v, fm in aInS) <= len(S)-1 cp.add(cut) if len(cp.cuts) > 256: for cut in cp.cuts: model += cut return for cut in cp.cuts: model += cut
def generate_constrs(self, m_: Model): xf, cp, Gl = m_.translate(self.x), CutPool(), nx.DiGraph() Ar = [(i, j) for (i, j) in Arcs if xf[i][j] and xf[i][j].x >= 1e-4] for (u, v) in Ar: Gl.add_edge(u, v, capacity=xf[u][v].x) for (u, v) in F: val, (S, NS) = nx.minimum_cut(Gl, u, v) if val <= 0.99: aInS = [(xf[i][j], xf[i][j].x) for (i, j) in Ar if i in S and j in S] if sum(f for v, f in aInS) >= (len(S) - 1) + 1e-4: cut = xsum(1.0 * v for v, fm in aInS) <= len(S) - 1 cp.add(cut) if len(cp.cuts) > 32: for cut in cp.cuts: m_ += cut return for cut in cp.cuts: m_ += cut
def generate_constrs(self, model: Model, depth: int = 0, npass: int = 0): xf, V_, cp, G = model.translate( self.x), self.V, CutPool(), nx.DiGraph() for (u, v) in [(k, l) for (k, l) in product(V_, V_) if k != l and xf[k][l]]: G.add_edge(u, v, capacity=xf[u][v].x) for (u, v) in F: val, (S, NS) = nx.minimum_cut(G, u, v) if val <= 0.99: aInS = [(xf[i][j], xf[i][j].x) for (i, j) in product(V_, V_) if i != j and xf[i][j] and i in S and j in S] if sum(f for v, f in aInS) >= (len(S) + sum( [1 if demand[i] > Q else 0 for i in S]) - 1) + 1e-4 + xsum( [x[g][l] for g in NS for l in S if (g != l)]): cut = xsum(1.0 * v for v, fm in aInS) <= len(S) - 1 + sum([ 1 if demand[i] > Q else 0 for i in S ]) + xsum([x[g][l] for g in NS for l in S if (g != l)]) cp.add(cut) if len(cp.cuts) > 256: for cut in cp.cuts: model += cut return for cut in cp.cuts: model += cut
def generate_cuts(self, model: Model): self.x = [[(0, 0) for i in range(self.instance.m)] for j in range(self.instance.n)] self.y = [[[(0, 0) for i in range(self.instance.m)] for k in range(self.instance.n)] for j in range(self.instance.n)] # recreate the set of vars used in the model. if position 1 have value = 0 and not a var object # the variable isn't used in the model for v in model.vars: if v.name.startswith('C'): self.c = (v, v.x) if v.name.startswith('x('): j = int(v.name.split('(')[1].split(',')[0]) i = int(v.name.split(')')[0].split(',')[1]) self.x[j][i] = (v, v.x) if v.name.startswith('y('): j = int(v.name.split('(')[1].split(',')[0]) k = int(v.name.split('(')[1].split(',')[1]) i = int(v.name.split(')')[0].split(',')[2]) self.y[j][k][i] = (v, v.x) # print('{} = {}'.format(self.c[0].name, self.c[1])) # for j in range(self.instance.n): # for i in range(self.instance.m): # if isinstance(self.x[j][i][0], int) == False: # print('{} = {}'.format(self.x[j][i][0].name, self.x[j][i][1])) # for j in range(self.instance.n): # for k in range(self.instance.n): # for i in range(self.instance.m): # if isinstance(self.y[j][k][i][0], int) == False: # print('{} = {}'.format(self.y[j][k][i][0].name, self.y[j][k][i][1])) # # input() cp = CutPool() for a in range(self.instance.m): # all possible combinations with 2 jobs. order doesnt' matter # comb = combinations(list(range(0, self.instance.n)), 2) # for jobs in list(comb): # result = self.two_jobs_cuts(jobs[0], jobs[1], a) # if isinstance(result, int) == False: # # print(result) # cp.add(result) # all possible combinations with 3 josb. the order matters # perm = permutations(list(range(0, self.instance.n)), 3) # for jobs in list(perm): # result = self.triangle_cuts(jobs[0], jobs[1], jobs[2], a) # if isinstance(result, int) == False: # # print(result) # cp.add(result) result = self.basic_cuts_best(a) if isinstance(result, int) == False: # print(result) cp.add(result) result = self.triangle_cuts_best(a) if isinstance(result, int) == False: # print(result) cp.add(result) result = self.two_jobs_cuts_best(a) if isinstance(result, int) == False: # print(result) cp.add(result) for k in range(self.instance.n): result = self.basic_cuts_plus_epsilon_best(a, k) if isinstance(result, int) == False: # print(result) cp.add(result) result = self.half_cuts_best(a, k) if isinstance(result, int) == False: # print(result) cp.add(result) for l in range(self.instance.n): result = self.late_job_cuts_best(a, k, l) if isinstance(result, int) == False: # print(result) cp.add(result) # i = 0 for cut in cp.cuts: # i = i + 1 model.add_cut(cut) # print('Number of cuts: {}'.format(i)) return