Beispiel #1
0
    def setUp(self):
        self.undirected = UndirectedGraph()

        self.undirected.add_edge(1, 2, 2)
        self.undirected.add_edge(1, 3, 6)
        self.undirected.add_edge(2, 4, 1)
        self.undirected.add_edge(3, 5, 4)
Beispiel #2
0
    def setUp(self):
        g = UndirectedGraph()

        g.add_edge(1, 2, 2)
        g.add_edge(1, 3, 6)
        g.add_edge(2, 3, 3)
        g.add_edge(2, 4, 9)
        g.add_edge(3, 4, 1)
        g.add_edge(3, 5, 4)
        g.add_edge(4, 5, 6)

        self.graph = g
    def setUp(self):
        g = UndirectedGraph()

        g.add_edge(1, 2, 2)
        g.add_edge(1, 3, 6)
        g.add_edge(2, 3, 3)
        g.add_edge(2, 4, 9)
        g.add_edge(3, 4, 1)
        g.add_edge(3, 5, 4)
        g.add_edge(4, 5, 6)

        self.graph = g
def prim(graph: UndirectedGraph) -> UndirectedGraph:
    """
    Prim's algorithm is a greedy algorithm that finds a minimum spanning tree for a weighted undirected graph.
    This means it finds a subset of the edges that forms a tree that includes every vertex
    O(E + V log V)
    """
    current_vertex = graph.get_vertices()[0]

    new_graph = UndirectedGraph()

    heap = FibonacciHeap(map(lambda x: (x, current_vertex), graph.get_outgoing_edges(current_vertex)))

    vertices = {current_vertex}

    while not heap.is_empty():

        edge, current_vertex = heap.pop()

        next_vertex = edge.a if edge.a != current_vertex else edge.b

        if next_vertex in vertices:
            continue

        # Add edge to the minimum spanning tree
        vertices.add(next_vertex)
        new_graph.add_edge(current_vertex, next_vertex, edge.weight)

        # Add all edges from this new point to the heap
        [heap.insert((edge, next_vertex)) for edge in graph.get_outgoing_edges(next_vertex)]

    return new_graph
Beispiel #5
0
def contains_cycle(graph: UndirectedGraph) -> bool:
    """
    Simple breadth first cycle detection for Undirected graphs
    """
    graph = copy.deepcopy(graph)  # type: Graph

    visited_nodes = set()

    queue = Queue()
    queue.enqueue(graph.get_vertices()[0])

    while not queue.is_empty():
        vertex = queue.dequeue()

        for neighbour in graph.get_successive_vertices(vertex):
            if neighbour in visited_nodes:
                return True
            visited_nodes.add(neighbour)
            queue.enqueue(neighbour)
            graph.delete_edge(vertex, neighbour)

    return False
Beispiel #6
0
def contains_cycle(graph: UndirectedGraph) -> bool:
    """
    Simple breadth first cycle detection for Undirected graphs
    """
    graph = copy.deepcopy(graph) # type: Graph

    visited_nodes = set()

    queue = Queue()
    queue.enqueue(graph.get_vertices()[0])

    while not queue.is_empty():
        vertex = queue.dequeue()

        for neighbour in graph.get_successive_vertices(vertex):
            if neighbour in visited_nodes:
                return True
            visited_nodes.add(neighbour)
            queue.enqueue(neighbour)
            graph.delete_edge(vertex, neighbour)

    return False
Beispiel #7
0
    def setUp(self):
        self.undirected = UndirectedGraph()
        self.undirected.add_edge(1, 2, 2)
        self.undirected.add_edge(1, 3, 6)
        self.undirected.add_edge(2, 3, 3)
        self.undirected.add_edge(2, 4, 1)
        self.undirected.add_edge(3, 4, 1)
        self.undirected.add_edge(3, 5, 4)
        self.undirected.add_edge(4, 5, 6)

        self.directed = DirectedGraph()
        self.directed.add_edge(1, 2, 2)
        self.directed.add_edge(1, 3, 6)
        self.directed.add_edge(2, 3, 3)
        self.directed.add_edge(2, 4, 1)
        self.directed.add_edge(3, 4, 1)
        self.directed.add_edge(3, 5, 4)
        self.directed.add_edge(4, 5, 6)
Beispiel #8
0
class TestCyclical(unittest.TestCase):
    def setUp(self):
        self.undirected = UndirectedGraph()

        self.undirected.add_edge(1, 2, 2)
        self.undirected.add_edge(1, 3, 6)
        self.undirected.add_edge(2, 4, 1)
        self.undirected.add_edge(3, 5, 4)

    def test_topological_sort(self):
        assert not contains_cycle(self.undirected)
        self.undirected.add_edge(4, 5, 6)
        assert contains_cycle(self.undirected)
def kruskal(graph: UndirectedGraph) -> UndirectedGraph:
    """
    Kruskal's algorithm is a minimum-spanning-tree algorithm which finds an edge of the least possible weight
    that connects any two trees in the forest. It is a greedy algorithm in graph theory as it finds a minimum
    spanning tree for a connected weighted undirected graph adding increasing cost arcs at each step.
    Time complexity: O(E log V)
    """
    spanning_tree = UndirectedGraph()

    union_find = UnionFind(max(graph.get_vertices()) + 1)

    heap = FibonacciHeap(graph.get_all_edges())

    while not heap.is_empty():

        edge = heap.pop()

        # Only add the edge if it will not create a cycle
        if union_find.find(edge.a) != union_find.find(edge.b):
            spanning_tree.add_edge(edge.a, edge.b, edge.weight)
            union_find.union(edge.a, edge.b)

    return spanning_tree
Beispiel #10
0
class TestGraph(unittest.TestCase):

    def setUp(self):
        self.undirected = UndirectedGraph()
        self.undirected.add_edge(1, 2, 2)
        self.undirected.add_edge(1, 3, 6)
        self.undirected.add_edge(2, 3, 3)
        self.undirected.add_edge(2, 4, 1)
        self.undirected.add_edge(3, 4, 1)
        self.undirected.add_edge(3, 5, 4)
        self.undirected.add_edge(4, 5, 6)

        self.directed = DirectedGraph()
        self.directed.add_edge(1, 2, 2)
        self.directed.add_edge(1, 3, 6)
        self.directed.add_edge(2, 3, 3)
        self.directed.add_edge(2, 4, 1)
        self.directed.add_edge(3, 4, 1)
        self.directed.add_edge(3, 5, 4)
        self.directed.add_edge(4, 5, 6)

    def test_get_edges(self):
        assert self.undirected.get_all_edges() == self.directed.get_all_edges()
        assert self.undirected.get_vertices() == self.directed.get_vertices()

    def test_directed_graph(self):

        assert len(self.directed.get_successive_vertices(4)) == 1

        assert len(self.undirected.get_successive_vertices(4)) == 3

        assert self.undirected.edge_exists(4, 3)
        assert not self.directed.edge_exists(4, 3)

        self.directed.delete_edge(4, 3)
        self.undirected.delete_edge(4, 3)

        assert len(self.directed.get_all_edges()) == len(self.undirected.get_all_edges()) + 1

    def test_undirected_graph(self):
        g = UndirectedGraph()
Beispiel #11
0
 def test_undirected_graph(self):
     g = UndirectedGraph()
Beispiel #12
0
class TestGraph(unittest.TestCase):
    def setUp(self):
        self.undirected = UndirectedGraph()
        self.undirected.add_edge(1, 2, 2)
        self.undirected.add_edge(1, 3, 6)
        self.undirected.add_edge(2, 3, 3)
        self.undirected.add_edge(2, 4, 1)
        self.undirected.add_edge(3, 4, 1)
        self.undirected.add_edge(3, 5, 4)
        self.undirected.add_edge(4, 5, 6)

        self.directed = DirectedGraph()
        self.directed.add_edge(1, 2, 2)
        self.directed.add_edge(1, 3, 6)
        self.directed.add_edge(2, 3, 3)
        self.directed.add_edge(2, 4, 1)
        self.directed.add_edge(3, 4, 1)
        self.directed.add_edge(3, 5, 4)
        self.directed.add_edge(4, 5, 6)

    def test_get_edges(self):
        assert self.undirected.get_all_edges() == self.directed.get_all_edges()
        assert self.undirected.get_vertices() == self.directed.get_vertices()

    def test_directed_graph(self):

        assert len(self.directed.get_successive_vertices(4)) == 1

        assert len(self.undirected.get_successive_vertices(4)) == 3

        assert self.undirected.edge_exists(4, 3)
        assert not self.directed.edge_exists(4, 3)

        self.directed.delete_edge(4, 3)
        self.undirected.delete_edge(4, 3)

        assert len(self.directed.get_all_edges()) == len(
            self.undirected.get_all_edges()) + 1

    def test_undirected_graph(self):
        g = UndirectedGraph()