Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
    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()
Ejemplo n.º 3
0
    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