示例#1
0
def minimum_spanning_tree(adjacency_list):
    """
    Get minimum spanning tree for graph represented as adjacency list
    """
    remain_vertices = adjacency_list.copy()
    edges_by_vertex = {}
    mst = UndirectedGraph()
    for vertex in remain_vertices.keys():
        edges_by_vertex[vertex] = None

    while remain_vertices:
        (vertex, adjacent_edges) = __extract_next_vertex_with_edges(
            remain_vertices, edges_by_vertex)
        if edges_by_vertex[vertex]:
            mst.add_edge(edges_by_vertex[vertex].start,
                         edges_by_vertex[vertex].end,
                         edges_by_vertex[vertex].weight)
        for edge in adjacent_edges:
            adjacent_vertex = edge.end
            is_not_visited = adjacent_vertex in remain_vertices
            is_lighter = edge.weight < __get_weight_or_inf(
                edges_by_vertex[adjacent_vertex])
            if is_not_visited and is_lighter:
                edges_by_vertex[adjacent_vertex] = edge
    return mst
示例#2
0
 def test_returns_true_for_graph_with_cycle(self):
     g = UndirectedGraph()
     g.add_edge(1, 2, 1)
     g.add_edge(4, 1, 1)
     g.add_edge(2, 3, 1)
     g.add_edge(3, 1, 1)
     self.assertFalse(is_bipartite(g))
    def test_can_add_multiple_edges_between_two_vertices(self):
        graph = UndirectedGraph()
        graph.add_edge(0, 1, 1)
        graph.add_edge(0, 1, 2)

        adjacency_list = graph.get_adjacency_list()
        self.assertEqual(2, len(adjacency_list))

        self.assertEqual(2, len(adjacency_list[0]))
        self.assertListEqual([0, 0],
                             sorted(map(lambda e: e.start, adjacency_list[0])))
        self.assertListEqual([1, 1],
                             sorted(map(lambda e: e.end, adjacency_list[0])))
        self.assertListEqual([1, 2],
                             sorted(map(lambda e: e.weight,
                                        adjacency_list[0])))

        self.assertEqual(2, len(adjacency_list[1]))
        self.assertListEqual([1, 1],
                             sorted(map(lambda e: e.start, adjacency_list[1])))
        self.assertListEqual([0, 0],
                             sorted(map(lambda e: e.end, adjacency_list[1])))
        self.assertListEqual([1, 2],
                             sorted(map(lambda e: e.weight,
                                        adjacency_list[1])))

        edges = graph.get_edges()
        self.assertEqual(4, len(edges))
        self.assertListEqual([0, 0, 1, 1], sorted(map(lambda e: e.start,
                                                      edges)))
        self.assertListEqual([0, 0, 1, 1], sorted(map(lambda e: e.end, edges)))
        self.assertListEqual([1, 1, 2, 2],
                             sorted(map(lambda e: e.weight, edges)))
示例#4
0
 def test_returns_minimum_edge_when_has_two_edges_with_different_weight(
         self):
     graph = UndirectedGraph()
     graph.add_edge(0, 1, 1)
     graph.add_edge(0, 1, 2)
     mst = minimum_spanning_tree(graph.get_adjacency_list())
     self.__compare_vertices([0, 1], mst.get_adjacency_list())
     self.__compare_edges([Edge(0, 1, 1), Edge(1, 0, 1)], mst.get_edges())
示例#5
0
 def test_returns_two_edges_for_two_edges_starting_in_same_vertex(self):
     graph = UndirectedGraph()
     graph.add_edge(0, 1, 1)
     graph.add_edge(0, 2, 2)
     mst = minimum_spanning_tree(graph.get_adjacency_list())
     self.__compare_vertices([0, 1, 2], mst.get_adjacency_list())
     self.__compare_edges(
         [Edge(0, 1, 1),
          Edge(1, 0, 1),
          Edge(0, 2, 2),
          Edge(2, 0, 2)], mst.get_edges())
示例#6
0
def fixtured_graph() -> UndirectedGraph:
    graph = UndirectedGraph()
    graph.add_edge("A", "B", weight=2)
    graph.add_edge("A", "C", weight=4)
    graph.add_edge("B", "C", weight=1)
    graph.add_edge("C", "D", weight=3)
    graph.add_edge("B", "D", weight=5)
    graph.add_edge("D", "E", weight=6)
    graph.add_edge("D", "F", weight=8)
    return graph
def count_possible_astronaut_pairs(total_astronauts, astronauts_connections):
    """
    Get number of possible astronaut pairs where both of them are 
    from different countries
    """
    graph = UndirectedGraph()
    for astronaut in range(0, total_astronauts):
        graph.add_vertex(astronaut)
    for connection in astronauts_connections:
        graph.add_edge(connection[0], connection[1], 0)
    country_by_astronaut = vertices_to_components(graph)
    count_by_country = {}
    for astronaut, country in country_by_astronaut.items():
        count_by_country[country] = count_by_country.get(country, 0) + 1
    total = 0
    pairs = 0
    for country, count in count_by_country.items():
        pairs += total * count
        total += count
    return pairs
示例#8
0
def count_number_of_road_forks(field):
    """
    Returns number of times you are able to move in more
    than one direction by a given forest

    :param field: Array of strings that represent forest
    :return: number of road forks
    """
    graph = UndirectedGraph()
    start = None
    end = None
    height = len(field)
    width = len(field[0])
    for i, row in enumerate(field):
        for j, symbol in enumerate(row):
            if symbol == 'X':
                continue

            index = __linear_index(i, j, width)
            if symbol == 'M':
                start = index
            if symbol == '*':
                end = index

            if __can_go_to(i - 1, j, height, width):
                if field[i - 1][j] != 'X':
                    neighbor_index = __linear_index(i - 1, j, width)
                    graph.add_edge(neighbor_index, index, 1)

            if __can_go_to(i, j - 1, height, width):
                if field[i][j - 1] != 'X':
                    neighbor_index = __linear_index(i, j - 1, width)
                    graph.add_edge(neighbor_index, index, 1)

    path = dijkstra_path(graph, start, end)
    fork_count = 1 if len(graph.get_edges(start)) > 1 else 0
    for vertex in path[1:-1]:
        if len(graph.get_edges(vertex)) - 1 > 1:
            fork_count += 1
    return fork_count
    def test_adding_single_edge_produces_two_directed_edges(self):
        graph = UndirectedGraph()
        graph.add_edge(0, 1, 1)

        adjacency_list = graph.get_adjacency_list()
        self.assertEqual(2, len(adjacency_list))

        self.assertEqual(1, len(adjacency_list[0]))
        self.assertEqual(0, adjacency_list[0][0].start)
        self.assertEqual(1, adjacency_list[0][0].end)
        self.assertEqual(1, adjacency_list[0][0].weight)

        self.assertEqual(1, len(adjacency_list[1]))
        self.assertEqual(1, adjacency_list[1][0].start)
        self.assertEqual(0, adjacency_list[1][0].end)
        self.assertEqual(1, adjacency_list[1][0].weight)

        edges = graph.get_edges()
        self.assertEqual(2, len(edges))
        self.assertListEqual([0, 1], sorted(map(lambda e: e.start, edges)))
        self.assertListEqual([0, 1], sorted(map(lambda e: e.end, edges)))
        self.assertListEqual([1, 1], sorted(map(lambda e: e.weight, edges)))
示例#10
0
 def test_returns_true_for_graph_with_multiple_connected_componenets(self):
     g = UndirectedGraph()
     g.add_edge(5, 2, 1)
     g.add_edge(4, 2, 1)
     g.add_edge(3, 4, 1)
     g.add_edge(1, 4, 1)
     g.add_edge(6, 7, 1)
     self.assertTrue(is_bipartite(g))
示例#11
0
 def test_returns_mst_for_graph_with_loops(self):
     graph = UndirectedGraph()
     graph.add_edge('A', 'B', 3)
     graph.add_edge('A', 'C', 4)
     graph.add_edge('D', 'B', 6)
     graph.add_edge('E', 'B', 2)
     graph.add_edge('B', 'C', 5)
     graph.add_edge('C', 'E', 7)
     mst = minimum_spanning_tree(graph.get_adjacency_list())
     self.__compare_vertices(['A', 'B', 'C', 'D', 'E'],
                             mst.get_adjacency_list())
     self.__compare_edges([
         Edge('A', 'B', 3),
         Edge('B', 'A', 3),
         Edge('B', 'E', 2),
         Edge('E', 'B', 2),
         Edge('A', 'C', 4),
         Edge('C', 'A', 4),
         Edge('B', 'D', 6),
         Edge('D', 'B', 6)
     ], mst.get_edges())
示例#12
0
 def test_does_not_change_tree(self):
     graph = UndirectedGraph()
     graph.add_edge(0, 1, 1)
     graph.add_edge(0, 6, 1)
     graph.add_edge(2, 3, 2)
     graph.add_edge(2, 4, 3)
     graph.add_edge(4, 5, 4)
     mst = minimum_spanning_tree(graph.get_adjacency_list())
     self.__compare_vertices([0, 1, 2, 3, 4, 5, 6],
                             mst.get_adjacency_list())
     self.__compare_edges([
         Edge(0, 1, 1),
         Edge(1, 0, 1),
         Edge(0, 6, 1),
         Edge(6, 0, 1),
         Edge(2, 3, 2),
         Edge(3, 2, 2),
         Edge(2, 4, 3),
         Edge(4, 2, 3),
         Edge(4, 5, 4),
         Edge(5, 4, 4)
     ], mst.get_edges())
示例#13
0
 def test_returns_true_for_graph_as_list(self):
     g = UndirectedGraph()
     g.add_edge(1, 2, 1)
     g.add_edge(2, 3, 1)
     self.assertTrue(is_bipartite(g))
示例#14
0
 def test_returns_single_edge_for_single_edge_in_graph(self):
     graph = UndirectedGraph()
     graph.add_edge(0, 1, 1)
     mst = minimum_spanning_tree(graph.get_adjacency_list())
     self.__compare_vertices([0, 1], mst.get_adjacency_list())
     self.__compare_edges([Edge(0, 1, 1), Edge(1, 0, 1)], mst.get_edges())