Esempio 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)
Esempio n. 2
0
    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
Esempio n. 3
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()
Esempio n. 4
0
    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
Esempio n. 5
0
 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
Esempio n. 6
0
 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
Esempio n. 7
0
 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
Esempio n. 8
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