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