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)
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
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
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)