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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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)
Beispiel #6
0
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
Beispiel #7
0
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)
Beispiel #8
0
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
Beispiel #9
0
 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]
Beispiel #10
0
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 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 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
Beispiel #13
0
    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
Beispiel #14
0
    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