def reduction_from_kcol_to_3col(G, k):
    # add the main gadget

    T = lambda *x: "dummy(" + ",".join(map(str, x)) + ')'
    V = lambda v, c: str(v) + '(' + str(c) + ')'
    if k == 3: return G
    H = Graph()
    # Create the color blue
    H.add_named_vertex('c1')
    H.add_named_vertex('c2')
    H.add_named_vertex('c3')
    H.add_edge('c1', 'c2')
    H.add_edge('c1', 'c3')
    H.add_edge('c2', 'c3')

    # add vertices
    for v in G:
        H.add_named_vertex(V(v, 0))
        H.add_edge(V(v, 0), 'c1')
        H.add_edge(V(v, 0), 'c3')

        H.add_named_vertex(V(v, k))
        H.add_edge(V(v, k), 'c2')
        H.add_edge(V(v, k), 'c3')

        for i in range(1, k):
            H.add_named_vertex(V(v, i))
            H.add_edge('c3', V(v, i))

    for u, v in G.edges:
        for i in range(1, k + 1):
            H.add_named_vertex(T(u, v, u, i))
            H.add_edge(V(u, i - 1), T(u, v, u, i))
            H.add_edge(V(u, i), T(u, v, u, i))

            H.add_named_vertex(T(u, v, v, i))
            H.add_edge(V(v, i - 1), T(u, v, v, i))
            H.add_edge(V(v, i), T(u, v, v, i))
            H.add_edge(T(u, v, u, i), T(u, v, v, i))

    H.set_vertex_index()

    return H
Exemple #2
0
def load_from_edge_list_named(strFileName, G = None):
    with open(strFileName, 'r') as f:
        lines = f.readlines()

    if G is None: G = Graph()

    for line in lines:
        if len(line) == 0 or line == '\n': continue
        fields = line.split()
        if not len(fields): continue
        if fields[0] == 'e':
            u, v = nvertex(fields[1]), nvertex(fields[2])
            if u not in V(G):
                G.add_named_vertex(u)
            if v not in V(G):
                G.add_named_vertex(v)
            G.add_edge(u, v)


    G.set_vertex_index()
    return G
def reduce_3sat_to_3col(instance, G = None):
    """reduces a 3sat instance to a graph 3-coloring instance
       receives a graph G
        
      for each clause (a,b,c)
      gadget:
      (-a)----(a)---(g1)
                     | \
                     | (g3)---(g4)    (X)             
                     | /       | \   / |
      (-b)----(b)---(g2)       |  (T)  |
                               | /   \ |
      (-c)----(c)-------------(g5)    (F)
      
      X is adjacent to all variables
    """
    G = Graph() if G is None else G

    # add common gadget
    G.add_named_vertex('T')
    G.add_named_vertex('F')
    G.add_named_vertex('X')
    G.add_edge('T', 'F')
    G.add_edge('F', 'X')
    G.add_edge('X', 'T')


    # add gadget for variables
    variables = sorted(set([abs(v) for clause in instance for v in clause]))

    for v in variables:
        G.add_named_vertex(v)
        G.add_named_vertex(-v)
        G.add_edge('X', v)
        G.add_edge('X', -v)
        G.add_edge(v, -v)

    G.set_vertex_index(max(variables) + 1)
    # add the clause gadgets
    for a, b, c in instance:
        g1, g2, g3, g4, g5 = [G.add_vertex() for _i in range(5)]

        # triangle 1,2,3
        G.add_edge(g1, g2)  # 1
        G.add_edge(g2, g3)  # 2
        G.add_edge(g3, g1)  # 3

        # bridge betwen triangle 1,2,3T  and 4,5,T
        G.add_edge(g3, g4)  # 4

        # triangle 3,4,5
        G.add_edge(g4, g5)  # 5
        G.add_edge(g5, 'T')  # 6
        G.add_edge('T', g4)  # 7

        # edges for clause a,b,c
        G.add_edge(a, g1)  # 8
        G.add_edge(b, g2)  # 9
        G.add_edge(c, g5)  # 10

    return G