Esempio n. 1
0
def two_cycle(A, C, gap):
    """
    Solve high-vertex dense graphs by reduction to
    weighted matching ILP.
    """
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    m.params.timelimit = 60 * 60

    n = A.shape[0]
    vars = {}
    edges = tuplelist()

    # model as undirected graph
    for i in range(n):
        for j in range(i + 1, n):
            if A[i, j] == 1 and A[j, i] == 1:
                e = (i, j)
                edges.append(e)
                w_i = 2 if i in C else 1
                w_j = 2 if j in C else 1
                w = w_i + w_j
                var = m.addVar(vtype=GRB.BINARY, obj=w)
                vars[e] = var

    m.update()

    # 2 cycle constraint <=> undirected flow <= 1
    for i in range(n):
        lhs = LinExpr()
        lhs_vars = [
            vars[e] for e in chain(edges.select(i, _), edges.select(_, i))
        ]
        ones = [1.0] * len(lhs_vars)
        lhs.addTerms(ones, lhs_vars)

        m.addConstr(lhs <= 1)

    m.optimize()
    m.update()

    cycles = [list(e) for e in edges if vars[e].x == 1.0]
    return cycles, m.objval
Esempio n. 2
0
def two_cycle(A, C, gap):
    """
    Solve high-vertex dense graphs by reduction to
    weighted matching ILP.
    """
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    m.params.timelimit = 60 * 60

    n = A.shape[0]
    vars = {}
    edges = tuplelist()

    # model as undirected graph
    for i in range(n):
        for j in range(i+1, n):
            if A[i, j] == 1 and A[j, i] == 1:
                e = (i, j)
                edges.append(e)
                w_i = 2 if i in C else 1
                w_j = 2 if j in C else 1
                w = w_i + w_j
                var = m.addVar(vtype=GRB.BINARY, obj=w)
                vars[e] = var

    m.update()

    # 2 cycle constraint <=> undirected flow <= 1
    for i in range(n):
        lhs = LinExpr()
        lhs_vars = [vars[e] for e in chain(edges.select(i, _), edges.select(_, i))]
        ones = [1.0]*len(lhs_vars)
        lhs.addTerms(ones, lhs_vars)

        m.addConstr(lhs <= 1)

    m.optimize()
    m.update()

    cycles = [list(e) for e in edges if vars[e].x == 1.0]
    return cycles, m.objval
Esempio n. 3
0
def cycle_milp(A, C, k, gap):
    n = A.shape[0]
    t_0 = time.clock()
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap

    cycles = []
    vars = []
    cycles_grouped = [[] for i in range(n)]
    vars_grouped = [[] for i in range(n)]

    print('[%.1f] Generating variables...' % (time.clock() - t_0))

    print('i = ', end='')
    for i in range(n):
        for cycle in dfs_cycles(i, A, k):
            w = sum([2 if j in C else 1 for j in cycle])
            var = m.addVar(vtype=GRB.BINARY, obj=w)
            vars.append(var)
            cycles.append(cycle)
            cycles_grouped[i].append(cycle)
            vars_grouped[i].append(var)
            for j in cycle:
                if j > i:
                    vars_grouped[j].append(var)
                    cycles_grouped[j].append(cycle)
        if (i + 1) % 10 == 0:
            print(i + 1)

    m.update()

    print('[%.1f] Generated variables...' % (time.clock() - t_0))
    print('[%.1f] Generating constraints...' % (time.clock() - t_0))

    for i in range(n):
        vars_i = vars_grouped[i]
        lhs = LinExpr()
        ones = [1.0]*len(vars_i)
        lhs.addTerms(ones, vars_i)
        m.addConstr(lhs <= 1.0)

    print('[%.1f] Generated constraints...' % (time.clock() - t_0))
    print('[%.1f] Begin Optimizing %d vertex %d cycle model' % (time.clock() - t_0, n, len(cycles)))

    m.update()
    m.optimize()
    m.update()

    print('[%.1f] Finished Optimizing' % (time.clock() - t_0))
    print('[%.1f] Building cycles...' % (time.clock() - t_0))

    final_cycles = []

    for i in range(len(vars)):
        var = vars[i]
        if var.x == 1.0:
            cycle = cycles[i]
            final_cycles.append(cycle)

    print('[%.1f] Finished building cycles' % (time.clock() - t_0))
    return final_cycles, m.objval
Esempio n. 4
0
def constantino(A, C, k, gap):
    """
    Polynomial-sized CCMcP Edge-Extended Model
    See Constantino et al. (2013)
    """
    t_0 = time.clock()
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    # m.params.timelimit = 60 * 60
    # m.params.nodefilestart = 1.0
    # m.params.nodefiledir = './.nodefiledir'
    # m.params.presparsify = 0
    # m.params.presolve = 0

    n = A.shape[0]
    vars = {}
    edges = tuplelist()

    print('[%.1f] Generating variables...' % (time.clock() - t_0))

    # Variables
    for l in range(n):
        for i in range(l, n):
            for j in range(l, n):
                if A[i, j] == 1:
                    e = (l, i, j)
                    edges.append(e)
                    w = 2 if j in C else 1
                    var = m.addVar(vtype=GRB.BINARY, obj=w)
                    vars[e] = var

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    m.update()

    print('[%.1f] Generated variables' % (time.clock() - t_0))
    print('[%.1f] Adding flow constraints...' % (time.clock() - t_0))

    # Constraint (2): Flow in = Flow out
    for l in range(n):
        for i in range(l, n):
            # Flow in
            lhs_vars = [vars[e] for e in edges.select(l, _, i)]
            ones = [1.0]*len(lhs_vars)
            lhs = LinExpr()
            lhs.addTerms(ones, lhs_vars)

            # Flow out
            rhs_vars = [vars[e] for e in edges.select(l, i, _)]
            ones = [1.0]*len(rhs_vars)
            rhs = LinExpr()
            rhs.addTerms(ones, rhs_vars)

            # Flow in = Flow out
            m.addConstr(lhs == rhs)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added flow constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle vertex constraints...' % (time.clock() - t_0))

    # Constraint (3): Use a vertex only once per cycle
    for i in range(n):
        c_vars = [vars[e] for e in edges.select(_, i, _)]
        ones = [1.0]*len(c_vars)
        expr = LinExpr()
        expr.addTerms(ones, c_vars)
        m.addConstr(expr <= 1.0)

        if i % 100 == 0 and i != 0:
            print('[%.1f] V_i = %d' % (time.clock() - t_0, i))

    print('[%.1f] Added cycle vertex constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle cardinality constraints...' % (time.clock() - t_0))

    # Constraint (4): Limit cardinality of cycles to k
    for l in range(n):
        c_vars = [vars[e] for e in edges.select(l, _, _)]
        ones = [1.0]*len(c_vars)
        expr = LinExpr()
        expr.addTerms(ones, c_vars)
        m.addConstr(expr <= k)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added cycle cardinality constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle index constraints...' % (time.clock() - t_0))

    # Constraint (5): Cycle index is smallest vertex-index
    for l in range(n):
        rhs_vars = [vars[e] for e in edges.select(l, l, _)]
        ones = [1.0]*len(rhs_vars)
        rhs = LinExpr()
        rhs.addTerms(ones, rhs_vars)

        for i in range(l+1, n):
            lhs_vars = [vars[e] for e in edges.select(l, i, _)]
            if len(lhs_vars) > 0:
                ones = [1.0]*len(lhs_vars)
                lhs = LinExpr()
                lhs.addTerms(ones, lhs_vars)

                m.addConstr(lhs <= rhs)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added cycle index constraints...' % (time.clock() - t_0))
    print('[%.1f] Begin Optimizing %d vertex model' % (time.clock() - t_0, n))

    m.optimize()
    m.update()

    print('[%.1f] Finished Optimizing' % (time.clock() - t_0))
    print('[%.1f] Building cycles...' % (time.clock() - t_0))

    cycles = []
    for l in range(n):
        c_edges = [(e[1], e[2]) for e in edges.select(l, _, _) if vars[e].x == 1.0]
        cycles.extend(cycles_from_edges(c_edges))

    print('[%.1f] Finished building cycles' % (time.clock() - t_0))

    return cycles, m.objval
Esempio n. 5
0
def lazy_cycle_constraint(A, C, k, gap):
    """
    Lazily generate cycle constraints as potential feasible solutions
    are generated.
    """
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    m.params.timelimit = 5 * 60 * 60
    m.params.lazyconstraints = 1

    n = A.shape[0]
    edges = tuplelist()
    vars = {}

    for i in range(n):
        for j in range(n):
            if A[i, j] == 1:
                e = (i, j)
                edges.append(e)
                w = 2 if j in C else 1
                var = m.addVar(vtype=GRB.BINARY, obj=w)
                vars[e] = var

    m.update()

    # flow constraints
    for i in range(n):
        out_vars = [vars[e] for e in edges.select(i, _)]
        out_ones = [1.0]*len(out_vars)
        out_expr = LinExpr()
        out_expr.addTerms(out_ones, out_vars)

        in_vars = [vars[e] for e in edges.select(_, i)]
        in_ones = [1.0]*len(in_vars)
        in_expr = LinExpr()
        in_expr.addTerms(in_ones, in_vars)

        m.addConstr(in_expr <= 1)
        m.addConstr(out_expr == in_expr)

    m.update()

    ith_cycle = 0

    def callback(model, where):
        if where == GRB.Callback.MIPSOL:
            sols = model.cbGetSolution([vars[e] for e in edges])
            c_edges = [edges[i] for i in range(len(edges)) if sols[i] > 0.5]
            cycles = cycles_from_edges(c_edges)
            for cycle in cycles:
                len_cycle = len(cycle)
                if len_cycle > k:
                    cycle_vars = [vars[(cycle[i], cycle[(i+1) % len_cycle])] for i in range(len_cycle)]
                    ones = [1.0]*len(cycle_vars)
                    expr = LinExpr()
                    expr.addTerms(ones, cycle_vars)
                    model.cbLazy(expr <= len_cycle - 1)

    m.optimize(callback)
    m.update()

    c_edges = [e for e in edges if vars[e].x == 1.0]
    cycles = cycles_from_edges(c_edges)

    return cycles, m.objval
Esempio n. 6
0
def cycle_milp(A, C, k, gap):
    n = A.shape[0]
    t_0 = time.clock()
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap

    cycles = []
    vars = []
    cycles_grouped = [[] for i in range(n)]
    vars_grouped = [[] for i in range(n)]

    print('[%.1f] Generating variables...' % (time.clock() - t_0))

    print('i = ', end='')
    for i in range(n):
        for cycle in dfs_cycles(i, A, k):
            w = sum([2 if j in C else 1 for j in cycle])
            var = m.addVar(vtype=GRB.BINARY, obj=w)
            vars.append(var)
            cycles.append(cycle)
            cycles_grouped[i].append(cycle)
            vars_grouped[i].append(var)
            for j in cycle:
                if j > i:
                    vars_grouped[j].append(var)
                    cycles_grouped[j].append(cycle)
        if (i + 1) % 10 == 0:
            print(i + 1)

    m.update()

    print('[%.1f] Generated variables...' % (time.clock() - t_0))
    print('[%.1f] Generating constraints...' % (time.clock() - t_0))

    for i in range(n):
        vars_i = vars_grouped[i]
        lhs = LinExpr()
        ones = [1.0] * len(vars_i)
        lhs.addTerms(ones, vars_i)
        m.addConstr(lhs <= 1.0)

    print('[%.1f] Generated constraints...' % (time.clock() - t_0))
    print('[%.1f] Begin Optimizing %d vertex %d cycle model' %
          (time.clock() - t_0, n, len(cycles)))

    m.update()
    m.optimize()
    m.update()

    print('[%.1f] Finished Optimizing' % (time.clock() - t_0))
    print('[%.1f] Building cycles...' % (time.clock() - t_0))

    final_cycles = []

    for i in range(len(vars)):
        var = vars[i]
        if var.x == 1.0:
            cycle = cycles[i]
            final_cycles.append(cycle)

    print('[%.1f] Finished building cycles' % (time.clock() - t_0))
    return final_cycles, m.objval
Esempio n. 7
0
def constantino(A, C, k, gap):
    """
    Polynomial-sized CCMcP Edge-Extended Model
    See Constantino et al. (2013)
    """
    t_0 = time.clock()
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    # m.params.timelimit = 60 * 60
    # m.params.nodefilestart = 1.0
    # m.params.nodefiledir = './.nodefiledir'
    # m.params.presparsify = 0
    # m.params.presolve = 0

    n = A.shape[0]
    vars = {}
    edges = tuplelist()

    print('[%.1f] Generating variables...' % (time.clock() - t_0))

    # Variables
    for l in range(n):
        for i in range(l, n):
            for j in range(l, n):
                if A[i, j] == 1:
                    e = (l, i, j)
                    edges.append(e)
                    w = 2 if j in C else 1
                    var = m.addVar(vtype=GRB.BINARY, obj=w)
                    vars[e] = var

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    m.update()

    print('[%.1f] Generated variables' % (time.clock() - t_0))
    print('[%.1f] Adding flow constraints...' % (time.clock() - t_0))

    # Constraint (2): Flow in = Flow out
    for l in range(n):
        for i in range(l, n):
            # Flow in
            lhs_vars = [vars[e] for e in edges.select(l, _, i)]
            ones = [1.0] * len(lhs_vars)
            lhs = LinExpr()
            lhs.addTerms(ones, lhs_vars)

            # Flow out
            rhs_vars = [vars[e] for e in edges.select(l, i, _)]
            ones = [1.0] * len(rhs_vars)
            rhs = LinExpr()
            rhs.addTerms(ones, rhs_vars)

            # Flow in = Flow out
            m.addConstr(lhs == rhs)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added flow constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle vertex constraints...' % (time.clock() - t_0))

    # Constraint (3): Use a vertex only once per cycle
    for i in range(n):
        c_vars = [vars[e] for e in edges.select(_, i, _)]
        ones = [1.0] * len(c_vars)
        expr = LinExpr()
        expr.addTerms(ones, c_vars)
        m.addConstr(expr <= 1.0)

        if i % 100 == 0 and i != 0:
            print('[%.1f] V_i = %d' % (time.clock() - t_0, i))

    print('[%.1f] Added cycle vertex constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle cardinality constraints...' %
          (time.clock() - t_0))

    # Constraint (4): Limit cardinality of cycles to k
    for l in range(n):
        c_vars = [vars[e] for e in edges.select(l, _, _)]
        ones = [1.0] * len(c_vars)
        expr = LinExpr()
        expr.addTerms(ones, c_vars)
        m.addConstr(expr <= k)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added cycle cardinality constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle index constraints...' % (time.clock() - t_0))

    # Constraint (5): Cycle index is smallest vertex-index
    for l in range(n):
        rhs_vars = [vars[e] for e in edges.select(l, l, _)]
        ones = [1.0] * len(rhs_vars)
        rhs = LinExpr()
        rhs.addTerms(ones, rhs_vars)

        for i in range(l + 1, n):
            lhs_vars = [vars[e] for e in edges.select(l, i, _)]
            if len(lhs_vars) > 0:
                ones = [1.0] * len(lhs_vars)
                lhs = LinExpr()
                lhs.addTerms(ones, lhs_vars)

                m.addConstr(lhs <= rhs)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added cycle index constraints...' % (time.clock() - t_0))
    print('[%.1f] Begin Optimizing %d vertex model' % (time.clock() - t_0, n))

    m.optimize()
    m.update()

    print('[%.1f] Finished Optimizing' % (time.clock() - t_0))
    print('[%.1f] Building cycles...' % (time.clock() - t_0))

    cycles = []
    for l in range(n):
        c_edges = [(e[1], e[2]) for e in edges.select(l, _, _)
                   if vars[e].x == 1.0]
        cycles.extend(cycles_from_edges(c_edges))

    print('[%.1f] Finished building cycles' % (time.clock() - t_0))

    return cycles, m.objval
Esempio n. 8
0
def lazy_cycle_constraint(A, C, k, gap):
    """
    Lazily generate cycle constraints as potential feasible solutions
    are generated.
    """
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    m.params.timelimit = 5 * 60 * 60
    m.params.lazyconstraints = 1

    n = A.shape[0]
    edges = tuplelist()
    vars = {}

    for i in range(n):
        for j in range(n):
            if A[i, j] == 1:
                e = (i, j)
                edges.append(e)
                w = 2 if j in C else 1
                var = m.addVar(vtype=GRB.BINARY, obj=w)
                vars[e] = var

    m.update()

    # flow constraints
    for i in range(n):
        out_vars = [vars[e] for e in edges.select(i, _)]
        out_ones = [1.0] * len(out_vars)
        out_expr = LinExpr()
        out_expr.addTerms(out_ones, out_vars)

        in_vars = [vars[e] for e in edges.select(_, i)]
        in_ones = [1.0] * len(in_vars)
        in_expr = LinExpr()
        in_expr.addTerms(in_ones, in_vars)

        m.addConstr(in_expr <= 1)
        m.addConstr(out_expr == in_expr)

    m.update()

    ith_cycle = 0

    def callback(model, where):
        if where == GRB.Callback.MIPSOL:
            sols = model.cbGetSolution([vars[e] for e in edges])
            c_edges = [edges[i] for i in range(len(edges)) if sols[i] > 0.5]
            cycles = cycles_from_edges(c_edges)
            for cycle in cycles:
                len_cycle = len(cycle)
                if len_cycle > k:
                    cycle_vars = [
                        vars[(cycle[i], cycle[(i + 1) % len_cycle])]
                        for i in range(len_cycle)
                    ]
                    ones = [1.0] * len(cycle_vars)
                    expr = LinExpr()
                    expr.addTerms(ones, cycle_vars)
                    model.cbLazy(expr <= len_cycle - 1)

    m.optimize(callback)
    m.update()

    c_edges = [e for e in edges if vars[e].x == 1.0]
    cycles = cycles_from_edges(c_edges)

    return cycles, m.objval