Example #1
0
    def __init__(self, grid_dict):
        """The grid is a 2d array of numbers."""
        self.grid_dict = grid_dict
        self.grid_matrix = dict_to_matrix(grid_dict)

        for row in self.grid_matrix:
            if len(row) != self.grid_width:
                raise ValueError('Input grid is not a valid matrix.')
            for val in row:
                if val < 0:
                    raise ValueError('Input grid has negative numbers.')

        # Detect fields by BFS
        todo = [cell for cell in grid_dict]
        fields = {}  # Mapping from field number to group of cells

        while todo:
            front = [todo.pop()]
            field = front[:]
            current_number = grid_dict[field[0]]
            if current_number in fields:
                raise ValueError(
                    'Not all cells with the same number are in the same field'
                )

            while front:
                current_cell = front.pop()
                for neighbor_cell in neighbor_cells(grid_dict, current_cell):
                    if neighbor_cell in todo and grid_dict[neighbor_cell] == current_number:
                        front.append(neighbor_cell)
                        field.append(neighbor_cell)
                        todo.remove(neighbor_cell)
            fields[current_number] = field
        self.fields = fields

        # Detect and create vertices
        vertex_numbers = fields.keys()
        vertices = bits(*vertex_numbers)

        # Detect and create neighborhoods
        neighborhoods = {}
        for number, cells in fields.items():
            neighbors = 0
            for cell in cells:
                for neighbor_cell in neighbor_cells(grid_dict, cell):
                    neighbors |= bit(grid_dict[neighbor_cell])
            neighborhoods[bit(number)] = neighbors

        Graph.__init__(self, vertices, neighborhoods)
Example #2
0
 def adjacency_matrix(self):
     length = domain(self.vertices) + 1
     result = []
     for i in range(length):
         v = bit(i)
         if v in self:
             result.append(tuple(tolist(self(v), length)))
         else:
             result.append(tuple([0] * length))
     return result
Example #3
0
    def load(filename):
        graph = Graph()
        with open(filename, 'r') as f:
            while 1:
                line = f.readline()
                #print('Parsing `{}`'.format(line[:-1]))
                if line == '':
                    break
                if line == '\n':
                    continue

                if line[0] == 'n':
                    v = bit(int(line[1:]))
                    graph.add(v)
                elif line[0] == 'e':
                    edge = line[1:].split()
                    v, w = bit(int(edge[0])), bit(int(edge[1]))
                    if v not in graph:
                        graph.add(v)
                    if w not in graph:
                        graph.add(w)
                    graph.connect(v, w)
        print('Graph loaded')
        return graph
Example #4
0
    def split(self, v, w):
        """Split edge between two vertices."""
        if not v in self:
            raise ValueError
        if not w in self:
            raise ValueError

        if w == v:
            raise ValueError('{} and {} are the same vertex.'.format(v, w))

        if contains(self(v), w):
            raise ValueError('{} and {} are not connected.'.format(v, w))

        # Only support undirected edges
        assert contains(self(w), v)

        new = bit(size(self.vertices))
        self.add(new)
        self.disconnect(v, w)
        self.connect(v, new)
        self.connect(w, new)