def test_neighbour_vertices(): mat = np.array([[1, 1, 1, 0, 0], [1, 0, 0, 1, 0], [0, 1, 1, 0, 0], [0, 0, 0, 1, 2]]) assert [(1, 0), (2, 1), (2, 2)] == list(graph.neighbours(mat, 0)) assert [(0, 0), (3, 3)] == list(graph.neighbours(mat, 1)) assert [(0, 1), (0, 2)] == list(graph.neighbours(mat, 2)) assert [(1, 3), (3, 4)] == list(graph.neighbours(mat, 3))
def sample_pixel(i, j, image, labels, eps, beta): """Sample pixel from conditional probability distribution. Arguments: i {int} -- row coordinate of pixel j {int} -- column coordinate of pixel image {numpy.ndarray} -- image labels {list} -- list of all labels ([0, 1] for black and white images) eps {float} -- noise parameter beta {float} -- edge cost parameter Returns: int -- sampled pixel """ probs = [] neighbour_pxls = neighbours(image, i, j) for label in labels: pixel = Pixel(i, j, label) pxl_cost = pixel_cost(pixel, image[i, j], eps) neighbours_costs = [] for neighbour in neighbour_pxls: neighbours_costs += [edge_cost(pixel, neighbour, beta)] probs.append(np.exp(-pxl_cost - np.sum(neighbours_costs))) probs = probs / np.sum(probs) sampled_pixel = np.random.choice(labels, p=probs) return sampled_pixel
def dijkstra(graph: Graph, start: tuple) -> Tuple[dict, dict]: distance = {} ancestor = {} visited = {} # Initialize structures for vertex in Graph.vertices: v_id = vertex[0] distance[v_id] = float("inf") ancestor[v_id] = None visited[v_id] = False start_v_id = start[0] distance[start_v_id] = 0 while False in visited.values(): non_visited_distance = { k: distance[k] for k, v in visited.items() if v == False } u = min(non_visited_distance, key=non_visited_distance.get) visited[u] = True for vertex in neighbours(u): v = vertex[0] if visited[v] == False: if distance[v] > distance[u] + weight(u, v): distance[v] = distance[u] + weight(u, v) ancestor[v] = u return distance, ancestor
def prim(graph: Graph): not_visited = [v[0] for v in graph.vertices] r = not_visited[0] not_visited.remove(r) # we choose the first vertex Q = [] # priority queue A = [] # mininum spanning tree weight_sum = 0 # combined value of the tree's edges while not_visited: for neighbour in neighbours(r): heapq.heappush(Q, (weight(neighbour[0], r), (neighbour[0], r))) while Q: e_weight, u = heapq.heappop(Q) # return edge with smallest weight if u[0] in not_visited: next_r = u[0] break if u[1] in not_visited: next_r = u[1] break weight_sum += e_weight A.append(u) r = next_r not_visited.remove(r) return weight_sum, A
def hierholzer(graph:Graph): edges = [edge[0] for edge in graph.edges] # The graphs we're working with are undirected # So an edge (v, u) is the same as an edge (u, v) # This bit check which of the "repeated" edges are # not present and adds them to the list for v in graph.vertices: for n in neighbours(v[0]): if (v[0], n[0]) not in edges: edges.append((v[0], n[0])) if (n[0], v[0]) not in edges: edges.append((n[0], v[0])) # Initially, all edges are marked unvisited e_visited = {edge: False for edge in edges} # We begin the algorithm from the first vertex vertex = graph.vertices[0] (r, cycle) = eulerian_subcycle(graph, vertex[0], e_visited) if not r: return (False, None) elif not all(e_visited): return (False, None) else: return (True, cycle)
def bfs(n_vertices: int) -> Tuple[dict, dict]: visited = {} distance = {} ancestor = {} # Initialize structures for vertex in Graph.vertices: label = vertex[0] visited[label] = False distance[label] = float("inf") ancestor[label] = None # Add starting node start = Graph.vertices[0] start_label = start[0] visited[start_label] = True distance[start_label] = 0 # Exploration loop queue = [start] while queue: current_node = queue.pop() cnode_label = current_node[0] for neighbour in neighbours(cnode_label): n_label = neighbour[0] if not visited[n_label]: visited[n_label] = True distance[n_label] = distance[cnode_label] + 1 ancestor[n_label] = n_label queue.append(neighbour) return distance, ancestor
def dfs(current: int, visited: dict, sorted_vertices: list): visited[current] = True for neighbour in neighbours(current): if not visited[neighbour]: dfs(neighbour, visited, sorted_vertices) sorted_vertices.insert(0, current)
def graph_coloring(graph): # Reversed sort by number of neighbours vertices = sorted(graph.vertices, key=lambda x: len(neighbours(x)), reverse=True) colors = [] color_map = {} for v in vertices: color_tmp = [True for i in vertices] for n in neighbours(v[0]): if n in color_map: color = color_map[n] color_tmp[color] = False for color, available in enumerate(color_tmp): if available: color_map[v] = color if color not in color_map: colors.append(color) break return color_map
def test_neighbours(self): """ FUNCTION: neighbours, in graph.py. """ """Use the function to determine the neighbours of each node""" neighbours = [] for i in range(0, self.n): neighbours.append(graph.neighbours(self.dag, i)) """ Assert that the function returns the expected neighbours for each node. """ assert neighbours[0] == [1, 2] assert neighbours[1] == [3, 0] assert neighbours[2] == [3, 0] assert neighbours[3] == [1, 2]
def eulerian_subcycle(graph, v, e_visited): cycle = [v] t = v while True: v_isolated = True for u in neighbours(v): edge = (v, u[0]) if e_visited[edge] == False and e_visited[u[0], v] == False: e_visited[edge] = True e_visited[u[0], v] = True v = u[0] cycle.append(v) v_isolated = False break if v_isolated: return (False, None) if v == t: break for x in cycle: for w in neighbours(x): if e_visited[(x, w[0])] == False: (r, aux_cycle) = eulerian_subcycle(graph, x, e_visited) if r == False: return (False, None) else: # append subcycles cycle = cycle[:cycle.index(x)] + aux_cycle + cycle[(cycle.index(x) +1):] return (True, cycle)
def create_graph(labeling, alpha, L, S): graph = maxflow.Graph[float]() height, width = labeling.shape nodeids = graph.add_grid_nodes(labeling.shape) for i in range(height): for j in range(width): current_pxl = Pixel(i, j, labeling[i, j]) current_label = current_pxl.label neighbours_list = neighbours(labeling, i, j) for neighbour in neighbours_list: weight = edge_cost(current_pxl, neighbour, S, L) graph.add_edge(nodeids[i, j], nodeids[neighbour.i, neighbour.j], weight, weight) pxl_weight_0 = pixel_cost(current_pxl, current_label) pxl_weight_1 = pixel_cost(current_pxl, alpha) graph.add_tedge(nodeids[i, j], pxl_weight_0, pxl_weight_1) return graph, nodeids
def dfs_visit(self, u, adj_mat, directed): """ Performs a depth first serach visit on a node in a graph. Parameters ---------- -'u': Int The index of the node to visit. -'adj_mat': Numpy ndarray Adjacency matrix. If adj_mat[i, j] = 1, there exists a directed edge from node i to node j. -'directed': Int Equals 1 if it is a directed graph, 0 otherwise. """ self.pre.append(u) self.color[0, u] = self.gray self.time_stamp = self.time_stamp + 1 self.d[0, u] = self.time_stamp if directed == 1: ns = graph.children(adj_mat, u) else: ns = graph.neighbours(adj_mat, u) ns = np.unique(ns) ns = np.setdiff1d(np.array(ns), np.array([self.pred[0, u]])) ns = ns.tolist() for v in ns: if self.color[0, v] == self.white: self.pred[0, v] = u self.dfs_visit(v, adj_mat, directed) elif self.color[0, v] == self.gray: self.cycle = 1 self.color[0, u] = self.black self.post.append(u) self.time_stamp = self.time_stamp + 1 self.f[0, u] = self.time_stamp