Beispiel #1
0
def topological_sort(graph: DirectedGraph) -> List:
    """
    Called Kahns algorithm
    Sorts the vertices of a graph in a topological order
    or raises an exception when the graph is cyclical
    :param graph: The graph to be sorted toplogically
    """

    graph = copy.deepcopy(graph)

    sorted_nodes = []
    nodes = Queue()

    # Add the nodes without incoming edges to the starting nodes
    for vertex in graph.get_vertices():
        if not graph.has_incoming_edge(vertex):
            nodes.enqueue(vertex)

    # Keep removing nodes and edges while nodes with no incoming edges exist
    while not nodes.is_empty():
        node = nodes.dequeue()
        sorted_nodes.append(node)

        for edge in graph.get_edges(node)[:]:
            graph.delete_edge(edge.a, edge.b)
            if not graph.has_incoming_edge(edge.b):
                nodes.enqueue(edge.b)

    if len(list(graph.get_all_edges())):
        raise RuntimeError('Graph is cyclical')

    return sorted_nodes
Beispiel #2
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 #3
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()