예제 #1
0
    def remove(self, vertices):
        """Remove vertices from the graph."""
        if not vertices in self.vertices:
            raise ValueError('Graph don\'t contain some of [{}]'.format(vertices))

        for v in iterate(vertices):
            for w in iterate(self(v)):
                self.disconnect(v, w)

        self._vertices -= vertices

        for v in iterate(vertices):
            del self.neighborhoods[v]
예제 #2
0
    def generate_random(nr_vertices, nr_edges=0):
        if not 0 <= nr_edges <= nr_vertices * (nr_vertices - 1) / 2:
            raise ValueError

        if not nr_edges:
            nr_edges = 0.5

        graph = Graph()
        graph.add(bits(*range(nr_vertices)))

        if nr_edges < 1:
            # Add random edges between groups
            for v in graph:
                for w in graph:
                    if v < w and random() < nr_edges:
                        graph.connect(v, w)
            return graph
        else:
            vertex_list = list(iterate(graph.vertices))
            for _ in range(nr_edges):
                while 1:
                    v, w = sample(vertex_list, 2)
                    # Don't connect vertices twice
                    if not w in graph[v]:
                        break
                graph.connect(v, w)

            return graph
예제 #3
0
 def __call__(self, vertices):
     """Return the union of neighborhoods of vertices."""
     result = 0
     for v in iterate(vertices):
         result = result | self.neighborhoods[v]
         #result |= self.neighborhoods[v]
     return result
예제 #4
0
def components(graph):
    """Return a list of the connected components of in the graph."""
    done = 0
    for v in iterate(graph.vertices):
        if contains(done, v):
            continue
        component = sum(bfs(graph, v))
        yield component
        done |= component
예제 #5
0
    def add(self, vertices):
        """Add new vertices to the graph."""
        assert isinstance(vertices, int)
        if not disjoint(self.vertices, vertices):
            raise ValueError('Graph already contain some of [{}]'.format(vertices))

        self._vertices |= vertices

        for v in iterate(vertices):
            self.neighborhoods[v] = 0
예제 #6
0
def greedy_step(G, left, right, un_left, booldim_left, un_table, bound):
    best_vertex = None
    best_booldim = Infinity
    best_un = None

    if size(right) == 1:
        return right, {0}, 1

    assert size(right) > 1

    candidates = get_neighborhood_2(G.neighborhoods, left) & right

    # Trivial cases are slow
    for v in iterate(candidates):
        if trivial_case(G.neighborhoods, left, right, v):
            new_un = increment_un(G, left, un_left, v)
            new_booldim = len(new_un)
            return v, new_un, new_booldim

    for v in iterate(candidates):
        if left | v not in un_table:
            un_table[left | v] = increment_un(G, left, un_left, v)
        new_un = un_table[left | v]
        new_booldim = len(new_un)

        # Apply pruning
        if new_booldim >= bound:
            # print('pruning')
            continue

        if new_booldim < best_booldim:
            best_vertex = v
            best_booldim = new_booldim
            best_un = new_un

    # If nothing found
    if best_vertex == None:
        best_un = increment_un(G, left, un_left, v)
        best_booldim = len(best_un)
        best_vertex = v

    assert best_vertex != None
    return best_vertex, best_un, best_booldim
예제 #7
0
def is_word_in_graph(word: str, graph, last_vertex=0, forbidden_vertices=0):
    if not word:
        return True

    letter = word[0]
    candidates = graph.letters_to_vertices[letter] | graph.letters_to_vertices['.']
    candidates = subtract(candidates, forbidden_vertices)
    if last_vertex:
        candidates &= graph.neighborhoods[last_vertex]

    return any(is_word_in_graph(word[1:], graph, v, forbidden_vertices | v) for v in iterate(candidates))
예제 #8
0
def is_word_in_graph(word: str, graph):
    if not word:
        return False

    letter = word[0]
    candidates = (graph.letters_to_vertices[letter]
                  if letter in graph.letters_to_vertices else 0)
    if not candidates:
        return False

    return any(recurse(word[1:], graph, v, v) for v in iterate(candidates))
예제 #9
0
def trivial_case(N, left, right, v):
    # No neighbors
    if contains(left, N[v]):
        return True

    # Twins
    for u in iterate(left):
        if N[v] & right == subtract(N[u], v) & right:
            return True

    return False
예제 #10
0
    def contract(self, v):
        """Contract a vertex."""
        if not v in self:
            raise ValueError

        neighbors = list(iterate(self(v)))
        self.remove(v)

        for w1 in neighbors:
            for w2 in neighbors:
                if w1 < w2 and not w1 in self[w2]:
                    self.connect(w1, w2)
예제 #11
0
def recurse(word: str, graph, last_vertex, forbidden):
    if not word:
        return True

    letter = word[0]

    if letter not in graph.letters_to_vertices:
        return False

    candidates = subtract(graph.letters_to_vertices[letter] &
                          graph.neighborhoods[last_vertex], forbidden)
    if not candidates:
        return False

    return any(recurse(word[1:], graph, v, forbidden | v) for v in iterate(candidates))
예제 #12
0
def heuristic(graph):
    subset = 0
    while is_independent(graph, subset):
        # Find valid vertex with the least new neighbors
        existing_neighbors = graph(subset)
        min_new_neighbors = Infinity
        new_vertex = None
        for v in iterate(subtract(graph.vertices, subset)):
            if not graph(v) & subset:
                new_neighbors = subtract(graph(v), existing_neighbors)
                if size(new_neighbors) < min_new_neighbors:
                    min_new_neighbors = size(new_neighbors)
                    new_vertex = v

        if new_vertex == None:
            return subset
        else:
            subset |= new_vertex
예제 #13
0
 def verify_symmetry(self):
     for v in self:
         for w in iterate(self(v)):
             assert v in self(w)
예제 #14
0
def get_neighborhood_2(N, subset):
    result = get_neighborhood(N, subset)
    for v in iterate(result):
        result |= N[v]
    return result
예제 #15
0
 def edges(self):
     """Iterate over each pair of connected vertices exactly once."""
     for v in self:
         for w in iterate(self(v)):
             if w < v:
                 yield v, w
예제 #16
0
def is_independent(graph, subset):
    for v in iterate(subset):
        for w in iterate(subset):
            if v > w and graph(v) & w:
                return False
    return True
예제 #17
0
def get_neighborhood(N, subset):
    result = 0
    for v in iterate(subset):
        result |= N[v]
    return result
예제 #18
0
 def __iter__(self):
     """Iterate over all vertices."""
     return iterate(self.vertices)
예제 #19
0
 def __repr__(self):
     return 'vertices: {}'.format(list(iterate(self.vertices)))