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 = 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_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