def setUp(self): self.graph = UndirectedSimpleGraph(range(5)) self.graph.add_edge_between(self.graph.get_vertex(0), self.graph.get_vertex(1), self._Weight(-1)) self.graph.add_edge_between(self.graph.get_vertex(0), self.graph.get_vertex(2), self._Weight(4)) self.graph.add_edge_between(self.graph.get_vertex(1), self.graph.get_vertex(2), self._Weight(9)) self.graph.add_edge_between(self.graph.get_vertex(1), self.graph.get_vertex(3), self._Weight(7)) self.graph.add_edge_between(self.graph.get_vertex(1), self.graph.get_vertex(4), self._Weight(12)) self.graph.add_edge_between(self.graph.get_vertex(2), self.graph.get_vertex(4), self._Weight(6)) self.graph.add_edge_between(self.graph.get_vertex(3), self.graph.get_vertex(4), self._Weight(3))
class UndirectedSimpleGraphTest(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.test_object = None def setUp(self): self.test_object = UndirectedSimpleGraph(range(10)) def test__properties_setitem_getitem__when_setting_property__then_property( self): # given vertex = Vertex(2) edge = self.test_object.add_edge_between(Vertex(0), Vertex(1)) vertex_property = "x" edge_property = "y" # when self.test_object.properties[vertex] = vertex_property self.test_object.properties[edge] = edge_property result_vertex = self.test_object.properties[vertex] result_edge = self.test_object.properties[edge] # then assert_that(result_vertex).is_equal_to(vertex_property) assert_that(result_edge).is_equal_to(edge_property) def test__properties_getitem__when_no_property__then_none(self): # given vertex = Vertex(4) edge = self.test_object.add_edge_between(Vertex(6), Vertex(7)) # when result_vertex = self.test_object.properties[vertex] result_edge = self.test_object.properties[edge] # then assert_that(result_vertex).is_none() assert_that(result_edge).is_none() def test__properties_getitem__when_not_existing__then_value_error(self): # when def function(item): return self.test_object.properties[item] # then assert_that(function).raises(ValueError).when_called_with(Vertex(14)) assert_that(function).raises(ValueError).when_called_with( Edge(Vertex(2), Vertex(8))) assert_that(function).raises(ValueError).when_called_with( Edge(Vertex(0), Vertex(-1))) def test__properties_delitem__then_none(self): # given vertex = Vertex(4) edge = self.test_object.add_edge_between(Vertex(6), Vertex(7)) self.test_object.properties[vertex] = "x" self.test_object.properties[edge] = "y" # when del self.test_object.properties[vertex] del self.test_object.properties[edge] # then assert_that(self.test_object.properties[vertex]).is_none() assert_that(self.test_object.properties[edge]).is_none() def test__vertices_count__then_number_of_vertices(self): # when result = self.test_object.vertices_count # then assert_that(result).is_equal_to(10) def test__edges_count__then_number_of_edges(self): # given self.test_object.add_edge_between(Vertex(7), Vertex(7)) self.test_object.add_edge_between(Vertex(1), Vertex(5)) self.test_object.add_edge_between(Vertex(2), Vertex(4)) self.test_object.add_edge_between(Vertex(8), Vertex(0)) self.test_object.add_edge_between(Vertex(6), Vertex(3)) self.test_object.add_edge_between(Vertex(9), Vertex(3)) # when result = self.test_object.edges_count # then assert_that(result).is_equal_to(6) def test__vertices__then_all_vertices(self): # when result = self.test_object.vertices # then assert_that(sorted(result)).is_equal_to([ Vertex(0), Vertex(1), Vertex(2), Vertex(3), Vertex(4), Vertex(5), Vertex(6), Vertex(7), Vertex(8), Vertex(9) ]) def test__edges__then_all_edges(self): # given self.test_object.add_edge_between(Vertex(7), Vertex(7)) self.test_object.add_edge_between(Vertex(1), Vertex(5)) self.test_object.add_edge_between(Vertex(2), Vertex(4)) self.test_object.add_edge_between(Vertex(8), Vertex(0)) self.test_object.add_edge_between(Vertex(6), Vertex(3)) self.test_object.add_edge_between(Vertex(9), Vertex(3)) # when result = self.test_object.edges # then assert_that(sorted(result)).is_equal_to([ Edge(Vertex(1), Vertex(5)), Edge(Vertex(2), Vertex(4)), Edge(Vertex(6), Vertex(3)), Edge(Vertex(7), Vertex(7)), Edge(Vertex(8), Vertex(0)), Edge(Vertex(9), Vertex(3)) ]) def test__get_vertex__when_exists__then_vertex(self): # given vertex_id = 6 # when result = self.test_object.get_vertex(vertex_id) # then assert_that(result.id).is_equal_to(vertex_id) def test__get_vertex__when_not_exists__then_key_error(self): # when def function(id_): return self.test_object.get_vertex(id_) # then assert_that(function).raises(KeyError).when_called_with(14) def test__get_edge__when_in_direction__then_edge(self): # given source = Vertex(5) destination = Vertex(9) self.test_object.add_edge_between(source, destination) # when result = self.test_object.get_edge(source, destination) # then assert_that(result.source).is_equal_to(source) assert_that(result.destination).is_equal_to(destination) def test__get_edge__when_reversed_direction__then_edge(self): # given source = Vertex(9) destination = Vertex(5) self.test_object.add_edge_between(source, destination) # when result = self.test_object.get_edge(destination, source) # then assert_that(result.source).is_equal_to(source) assert_that(result.destination).is_equal_to(destination) def test__get_edge__when_not_exists__then_key_error(self): # when def function(source, destination): return self.test_object.get_edge(source, destination) # then assert_that(function).raises(KeyError).when_called_with(1, 2) def test__adjacent_edges__then_outgoing_edges(self): # given self.test_object.add_edge_between(Vertex(1), Vertex(1)) self.test_object.add_edge_between(Vertex(1), Vertex(3)) self.test_object.add_edge_between(Vertex(1), Vertex(4)) self.test_object.add_edge_between(Vertex(1), Vertex(7)) self.test_object.add_edge_between(Vertex(1), Vertex(9)) self.test_object.add_edge_between(Vertex(2), Vertex(1)) self.test_object.add_edge_between(Vertex(6), Vertex(1)) # when result = self.test_object.adjacent_edges(Vertex(1)) # then assert_that(sorted(result)).is_equal_to([ Edge(Vertex(1), Vertex(1)), Edge(Vertex(1), Vertex(3)), Edge(Vertex(1), Vertex(4)), Edge(Vertex(1), Vertex(7)), Edge(Vertex(1), Vertex(9)), Edge(Vertex(2), Vertex(1)), Edge(Vertex(6), Vertex(1)) ]) def test__neighbours__then_destination_vertices_of_outgoing_edges(self): # given self.test_object.add_edge_between(Vertex(1), Vertex(1)) self.test_object.add_edge_between(Vertex(1), Vertex(3)) self.test_object.add_edge_between(Vertex(1), Vertex(4)) self.test_object.add_edge_between(Vertex(1), Vertex(7)) self.test_object.add_edge_between(Vertex(1), Vertex(9)) self.test_object.add_edge_between(Vertex(2), Vertex(1)) self.test_object.add_edge_between(Vertex(6), Vertex(1)) # when result = self.test_object.neighbours(Vertex(1)) # then assert_that(sorted(result)).is_equal_to([ Vertex(1), Vertex(2), Vertex(3), Vertex(4), Vertex(6), Vertex(7), Vertex(9) ]) def test__output_degree__then_number_of_outgoing_edges(self): # given self.test_object.add_edge_between(Vertex(1), Vertex(1)) self.test_object.add_edge_between(Vertex(1), Vertex(3)) self.test_object.add_edge_between(Vertex(1), Vertex(4)) self.test_object.add_edge_between(Vertex(1), Vertex(7)) self.test_object.add_edge_between(Vertex(1), Vertex(9)) self.test_object.add_edge_between(Vertex(2), Vertex(1)) self.test_object.add_edge_between(Vertex(6), Vertex(1)) # when result = self.test_object.output_degree(Vertex(1)) # then assert_that(result).is_equal_to(7) def test__input_degree__then_number_of_incoming_edges(self): # given self.test_object.add_edge_between(Vertex(1), Vertex(1)) self.test_object.add_edge_between(Vertex(3), Vertex(1)) self.test_object.add_edge_between(Vertex(4), Vertex(1)) self.test_object.add_edge_between(Vertex(7), Vertex(1)) self.test_object.add_edge_between(Vertex(9), Vertex(1)) self.test_object.add_edge_between(Vertex(1), Vertex(2)) self.test_object.add_edge_between(Vertex(1), Vertex(6)) # when result = self.test_object.input_degree(Vertex(1)) # then assert_that(result).is_equal_to(7) def test__add_vertex__when_new_vertex__then_created_vertex(self): # given new_vertex_id = 13 vertex_property = "qwerty" # when result = self.test_object.add_vertex(new_vertex_id, vertex_property) # then assert_that(result.id).is_equal_to(new_vertex_id) assert_that(self.test_object.vertices_count).is_equal_to(11) assert_that(list(self.test_object.neighbours(result))).is_empty() assert_that( self.test_object.properties[result]).is_equal_to(vertex_property) def test__add_vertex__when_existing_vertex__then_value_error(self): # given vertex = Vertex(6) vertex_property = "qwerty" self.test_object.properties[vertex] = vertex_property # when def function(vertex_): self.test_object.add_vertex(vertex_, "abcdefg") # then assert_that(function).raises(ValueError).when_called_with(vertex) assert_that(self.test_object.vertices_count).is_equal_to(10) assert_that( self.test_object.properties[vertex]).is_equal_to(vertex_property) def test__add_edge_between__when_new_edge__then_created_edge(self): # given vertex1 = Vertex(1) vertex2 = Vertex(5) edge_property = "asdfgh" # when result = self.test_object.add_edge_between(vertex1, vertex2, edge_property) self.test_object.add_edge_between(vertex1, vertex1) # then assert_that(result.source).is_equal_to(vertex1) assert_that(result.destination).is_equal_to(vertex2) assert_that( self.test_object.properties[result]).is_equal_to(edge_property) assert_that(sorted(self.test_object.neighbours(vertex1))).is_equal_to( [vertex1, vertex2]) assert_that(list(self.test_object.neighbours(vertex2))).is_equal_to( [vertex1]) def test__add_edge_between__when_duplicated_edge__then_value_error(self): # given source = Vertex(3) destination = Vertex(7) _ = self.test_object.add_edge_between(source, destination) # when def function(source_, destination_): return self.test_object.add_edge_between(source_, destination_) # then assert_that(function).raises(ValueError).when_called_with( source, destination) def test__as_directed__then_directed_graph(self): # given vertex = Vertex(5) vertex_property = "123456" edge_property = "zxcvb" edge = self.test_object.add_edge_between(Vertex(1), Vertex(5)) self.test_object.add_edge_between(Vertex(7), Vertex(7)) self.test_object.add_edge_between(Vertex(2), Vertex(4)) self.test_object.add_edge_between(Vertex(8), Vertex(0)) self.test_object.add_edge_between(Vertex(6), Vertex(3)) self.test_object.add_edge_between(Vertex(9), Vertex(3)) self.test_object.properties[vertex] = vertex_property self.test_object.properties[edge] = edge_property # when result = self.test_object.as_directed() # then assert_that(result).is_instance_of(DirectedGraph) assert_that(sorted(result.vertices)).is_equal_to( sorted(self.test_object.vertices)) assert_that(sorted(result.edges)).is_equal_to([ Edge(Vertex(0), Vertex(8)), Edge(Vertex(1), Vertex(5)), Edge(Vertex(2), Vertex(4)), Edge(Vertex(3), Vertex(6)), Edge(Vertex(3), Vertex(9)), Edge(Vertex(4), Vertex(2)), Edge(Vertex(5), Vertex(1)), Edge(Vertex(6), Vertex(3)), Edge(Vertex(7), Vertex(7)), Edge(Vertex(8), Vertex(0)), Edge(Vertex(9), Vertex(3)) ]) assert_that(result.properties[vertex]).is_equal_to(vertex_property) assert_that(result.properties[Vertex(9)]).is_none() assert_that(result.properties[result.get_edge( 1, 5)]).is_equal_to(edge_property) assert_that(result.properties[result.get_edge( 5, 1)]).is_equal_to(edge_property) assert_that(result.properties[result.get_edge(8, 0)]).is_none()
def setUp(self): self.test_object = UndirectedSimpleGraph(range(10))
def test__find_vertex_cut__when_no_separators(): # given graph = UndirectedSimpleGraph(range(6)) graph.add_edge_between(graph.get_vertex(0), graph.get_vertex(1)) graph.add_edge_between(graph.get_vertex(0), graph.get_vertex(2)) graph.add_edge_between(graph.get_vertex(1), graph.get_vertex(2)) graph.add_edge_between(graph.get_vertex(1), graph.get_vertex(3)) graph.add_edge_between(graph.get_vertex(1), graph.get_vertex(4)) graph.add_edge_between(graph.get_vertex(2), graph.get_vertex(3)) graph.add_edge_between(graph.get_vertex(3), graph.get_vertex(5)) graph.add_edge_between(graph.get_vertex(4), graph.get_vertex(5)) # when result = find_vertex_cut(graph) # then assert_that(list(result)).is_empty()
def test__find_vertex_cut__when_present_separators(): # given graph = UndirectedSimpleGraph(range(12)) graph.add_edge_between(graph.get_vertex(0), graph.get_vertex(1)) graph.add_edge_between(graph.get_vertex(0), graph.get_vertex(2)) graph.add_edge_between(graph.get_vertex(0), graph.get_vertex(7)) graph.add_edge_between(graph.get_vertex(1), graph.get_vertex(2)) graph.add_edge_between(graph.get_vertex(1), graph.get_vertex(3)) graph.add_edge_between(graph.get_vertex(1), graph.get_vertex(4)) graph.add_edge_between(graph.get_vertex(3), graph.get_vertex(5)) graph.add_edge_between(graph.get_vertex(4), graph.get_vertex(5)) graph.add_edge_between(graph.get_vertex(5), graph.get_vertex(6)) graph.add_edge_between(graph.get_vertex(7), graph.get_vertex(8)) graph.add_edge_between(graph.get_vertex(7), graph.get_vertex(9)) graph.add_edge_between(graph.get_vertex(7), graph.get_vertex(11)) graph.add_edge_between(graph.get_vertex(8), graph.get_vertex(9)) graph.add_edge_between(graph.get_vertex(9), graph.get_vertex(10)) graph.add_edge_between(graph.get_vertex(9), graph.get_vertex(11)) graph.add_edge_between(graph.get_vertex(10), graph.get_vertex(11)) # when result = find_vertex_cut(graph) # then assert_that(sorted(result)).is_equal_to([ graph.get_vertex(0), graph.get_vertex(1), graph.get_vertex(5), graph.get_vertex(7) ])
def setUp(self): self._directed_graph = DirectedSimpleGraph(range(10)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(0), self._directed_graph.get_vertex(1), self._Weight(4)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(1), self._directed_graph.get_vertex(4), self._Weight(7)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(1), self._directed_graph.get_vertex(7), self._Weight(12)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(2), self._directed_graph.get_vertex(4), self._Weight(6)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(2), self._directed_graph.get_vertex(6), self._Weight(8)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(3), self._directed_graph.get_vertex(0), self._Weight(3)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(3), self._directed_graph.get_vertex(7), self._Weight(5)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(4), self._directed_graph.get_vertex(5), self._Weight(1)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(4), self._directed_graph.get_vertex(3), self._Weight(10)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(5), self._directed_graph.get_vertex(6), self._Weight(4)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(5), self._directed_graph.get_vertex(8), self._Weight(2)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(6), self._directed_graph.get_vertex(5), self._Weight(7)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(7), self._directed_graph.get_vertex(5), self._Weight(2)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(7), self._directed_graph.get_vertex(8), self._Weight(6)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(8), self._directed_graph.get_vertex(9), self._Weight(10)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(9), self._directed_graph.get_vertex(6), self._Weight(3)) self._undirected_graph = UndirectedSimpleGraph(range(10)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(0), self._undirected_graph.get_vertex(1), self._Weight(4)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(1), self._undirected_graph.get_vertex(4), self._Weight(7)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(1), self._undirected_graph.get_vertex(7), self._Weight(12)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(2), self._undirected_graph.get_vertex(6), self._Weight(8)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(3), self._undirected_graph.get_vertex(0), self._Weight(3)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(3), self._undirected_graph.get_vertex(7), self._Weight(5)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(4), self._undirected_graph.get_vertex(5), self._Weight(1)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(4), self._undirected_graph.get_vertex(3), self._Weight(10)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(5), self._undirected_graph.get_vertex(8), self._Weight(2)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(7), self._undirected_graph.get_vertex(5), self._Weight(2)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(7), self._undirected_graph.get_vertex(8), self._Weight(6)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(9), self._undirected_graph.get_vertex(6), self._Weight(3))
class PathsTest(unittest.TestCase): INF = Paths.INFINITY def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._directed_graph = None self._undirected_graph = None def setUp(self): self._directed_graph = DirectedSimpleGraph(range(10)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(0), self._directed_graph.get_vertex(1), self._Weight(4)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(1), self._directed_graph.get_vertex(4), self._Weight(7)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(1), self._directed_graph.get_vertex(7), self._Weight(12)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(2), self._directed_graph.get_vertex(4), self._Weight(6)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(2), self._directed_graph.get_vertex(6), self._Weight(8)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(3), self._directed_graph.get_vertex(0), self._Weight(3)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(3), self._directed_graph.get_vertex(7), self._Weight(5)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(4), self._directed_graph.get_vertex(5), self._Weight(1)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(4), self._directed_graph.get_vertex(3), self._Weight(10)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(5), self._directed_graph.get_vertex(6), self._Weight(4)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(5), self._directed_graph.get_vertex(8), self._Weight(2)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(6), self._directed_graph.get_vertex(5), self._Weight(7)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(7), self._directed_graph.get_vertex(5), self._Weight(2)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(7), self._directed_graph.get_vertex(8), self._Weight(6)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(8), self._directed_graph.get_vertex(9), self._Weight(10)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(9), self._directed_graph.get_vertex(6), self._Weight(3)) self._undirected_graph = UndirectedSimpleGraph(range(10)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(0), self._undirected_graph.get_vertex(1), self._Weight(4)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(1), self._undirected_graph.get_vertex(4), self._Weight(7)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(1), self._undirected_graph.get_vertex(7), self._Weight(12)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(2), self._undirected_graph.get_vertex(6), self._Weight(8)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(3), self._undirected_graph.get_vertex(0), self._Weight(3)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(3), self._undirected_graph.get_vertex(7), self._Weight(5)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(4), self._undirected_graph.get_vertex(5), self._Weight(1)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(4), self._undirected_graph.get_vertex(3), self._Weight(10)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(5), self._undirected_graph.get_vertex(8), self._Weight(2)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(7), self._undirected_graph.get_vertex(5), self._Weight(2)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(7), self._undirected_graph.get_vertex(8), self._Weight(6)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(9), self._undirected_graph.get_vertex(6), self._Weight(3)) # region bellman_ford def test__bellman_ford__when_directed_graph__then_shortest_paths_lengths( self): # given distances = [20, 0, self.INF, 17, 7, 8, 12, 12, 10, 20] expected = _from_list(self._directed_graph, distances) # when result = bellman_ford(self._directed_graph, self._directed_graph.get_vertex(1)) # then assert_that(result).is_equal_to(expected) def test__bellman_ford__when_negative_edge__then_edge_included(self): # given distances = [8, 0, self.INF, 5, 7, 8, 12, 10, 10, 20] expected = _from_list(self._directed_graph, distances) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(8), self._directed_graph.get_vertex(3), self._Weight(-5)) # when result = bellman_ford(self._directed_graph, self._directed_graph.get_vertex(1)) # then assert_that(result).is_equal_to(expected) def test__bellman_ford__when_undirected_graph__then_shortest_paths_lengths( self): # given distances = [4, 0, self.INF, 7, 7, 8, self.INF, 10, 10, self.INF] expected = _from_list(self._undirected_graph, distances) # when result = bellman_ford(self._undirected_graph.as_directed(), self._undirected_graph.get_vertex(1)) # then assert_that(result).is_equal_to(expected) def test__bellman_ford__when_negative_cycle__then_value_error(self): # given self._directed_graph.add_edge_between( self._directed_graph.get_vertex(8), self._directed_graph.get_vertex(3), self._Weight(-20)) # when def function(graph): return bellman_ford(graph, graph.get_vertex(1)) # then assert_that(function).raises(ValueError).when_called_with( self._directed_graph) # endregion # region dijkstra def test__dijkstra__when_directed_graph__then_shortest_paths_lengths(self): # given distances = [20, 0, self.INF, 17, 7, 8, 12, 12, 10, 20] expected = _from_list(self._directed_graph, distances) # when result = dijkstra(self._directed_graph, self._directed_graph.get_vertex(1)) # then assert_that(result).is_equal_to(expected) def test__dijkstra__when_undirected_graph__then_shortest_paths_lengths( self): # given distances = [4, 0, self.INF, 7, 7, 8, self.INF, 10, 10, self.INF] expected = _from_list(self._undirected_graph, distances) # when result = dijkstra(self._undirected_graph, self._undirected_graph.get_vertex(1)) # then assert_that(result).contains_only(*expected) assert_that(result).contains_entry(*({ k: v } for k, v in expected.items())) def test__dijkstra__when_negative_edge__then_value_error(self): # given self._directed_graph.add_edge_between( self._directed_graph.get_vertex(2), self._directed_graph.get_vertex(1), self._Weight(-2)) # when def function(graph): dijkstra(graph, graph.get_vertex(1)) # then assert_that(function).raises(ValueError).when_called_with( self._directed_graph) # endregion # region floyd_warshall def test__floyd_warshall__when_directed_graph__then_shortest_paths_lengths( self): # given distances = [[0, 4, self.INF, 21, 11, 12, 16, 16, 14, 24], [20, 0, self.INF, 17, 7, 8, 12, 12, 10, 20], [19, 23, 0, 16, 6, 7, 8, 21, 9, 19], [3, 7, self.INF, 0, 14, 7, 11, 5, 9, 19], [13, 17, self.INF, 10, 0, 1, 5, 15, 3, 13], [ self.INF, self.INF, self.INF, self.INF, self.INF, 0, 4, self.INF, 2, 12 ], [ self.INF, self.INF, self.INF, self.INF, self.INF, 7, 0, self.INF, 9, 19 ], [ self.INF, self.INF, self.INF, self.INF, self.INF, 2, 6, 0, 4, 14 ], [ self.INF, self.INF, self.INF, self.INF, self.INF, 20, 13, self.INF, 0, 10 ], [ self.INF, self.INF, self.INF, self.INF, self.INF, 10, 3, self.INF, 12, 0 ]] expected = _from_matrix(self._directed_graph, distances) # when result = floyd_warshall(self._directed_graph) # then assert_that(result).is_equal_to(expected) def test__floyd_warshall__when_negative_edge__then_edge_included(self): # given distances = [[0, 4, self.INF, 9, 11, 12, 16, 14, 14, 24], [8, 0, self.INF, 5, 7, 8, 12, 10, 10, 20], [7, 11, 0, 4, 6, 7, 8, 9, 9, 19], [3, 7, self.INF, 0, 14, 7, 11, 5, 9, 19], [1, 5, self.INF, -2, 0, 1, 5, 3, 3, 13], [0, 4, self.INF, -3, 11, 0, 4, 2, 2, 12], [7, 11, self.INF, 4, 18, 7, 0, 9, 9, 19], [2, 6, self.INF, -1, 13, 2, 6, 0, 4, 14], [-2, 2, self.INF, -5, 9, 2, 6, 0, 0, 10], [10, 14, self.INF, 7, 21, 10, 3, 12, 12, 0]] expected = _from_matrix(self._directed_graph, distances) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(8), self._directed_graph.get_vertex(3), self._Weight(-5)) # when result = floyd_warshall(self._directed_graph) # then assert_that(result).is_equal_to(expected) def test__floyd_warshall__when_undirected_graph__then_shortest_paths_lengths( self): # given distances = \ [[0, 4, self.INF, 3, 11, 10, self.INF, 8, 12, self.INF], [4, 0, self.INF, 7, 7, 8, self.INF, 10, 10, self.INF], [self.INF, self.INF, 0, self.INF, self.INF, self.INF, 8, self.INF, self.INF, 11], [3, 7, self.INF, 0, 8, 7, self.INF, 5, 9, self.INF], [11, 7, self.INF, 8, 0, 1, self.INF, 3, 3, self.INF], [10, 8, self.INF, 7, 1, 0, self.INF, 2, 2, self.INF], [self.INF, self.INF, 8, self.INF, self.INF, self.INF, 0, self.INF, self.INF, 3], [8, 10, self.INF, 5, 3, 2, self.INF, 0, 4, self.INF], [12, 10, self.INF, 9, 3, 2, self.INF, 4, 0, self.INF], [self.INF, self.INF, 11, self.INF, self.INF, self.INF, 3, self.INF, self.INF, 0]] expected = _from_matrix(self._undirected_graph, distances) # when result = floyd_warshall(self._undirected_graph.as_directed()) # then assert_that(result).is_equal_to(expected) # endregion class _Weight: def __init__(self, weight): self.weight = weight
class SearchingTest(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._directed_graph = None self._undirected_graph = None def setUp(self): self._directed_graph = DirectedSimpleGraph(range(10)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(0), self._directed_graph.get_vertex(1)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(1), self._directed_graph.get_vertex(3)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(1), self._directed_graph.get_vertex(7)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(3), self._directed_graph.get_vertex(4)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(4), self._directed_graph.get_vertex(0)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(5), self._directed_graph.get_vertex(4)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(5), self._directed_graph.get_vertex(8)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(6), self._directed_graph.get_vertex(2)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(6), self._directed_graph.get_vertex(9)) self._directed_graph.add_edge_between( self._directed_graph.get_vertex(8), self._directed_graph.get_vertex(5)) self._undirected_graph = UndirectedSimpleGraph(range(10)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(0), self._undirected_graph.get_vertex(1)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(0), self._undirected_graph.get_vertex(4)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(1), self._undirected_graph.get_vertex(3)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(1), self._undirected_graph.get_vertex(7)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(2), self._undirected_graph.get_vertex(6)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(3), self._undirected_graph.get_vertex(4)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(4), self._undirected_graph.get_vertex(5)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(5), self._undirected_graph.get_vertex(8)) self._undirected_graph.add_edge_between( self._undirected_graph.get_vertex(6), self._undirected_graph.get_vertex(9)) # region bfs def test__bfs__when_undirected_graph_and_single_root__then_visited_visited( self): # when result = bfs(self._undirected_graph, EmptyStrategy(), [self._undirected_graph.get_vertex(0)]) # then assert_that(sorted(result)).is_equal_to([ self._undirected_graph.get_vertex(0), self._undirected_graph.get_vertex(1), self._undirected_graph.get_vertex(3), self._undirected_graph.get_vertex(4), self._undirected_graph.get_vertex(5), self._undirected_graph.get_vertex(7), self._undirected_graph.get_vertex(8) ]) def test__bfs__when_undirected_graph_and_many_roots__then_all_visited( self): # given strategy = self._TestingStrategy() # when result = bfs(self._undirected_graph, strategy, [ self._undirected_graph.get_vertex(0), self._undirected_graph.get_vertex(6) ]) # then assert_that(sorted(result)).is_equal_to( sorted(self._undirected_graph.vertices)) assert_that(sorted(strategy.entries)).is_equal_to( sorted(self._undirected_graph.vertices)) assert_that(sorted(strategy.exits)).is_equal_to( sorted(self._undirected_graph.vertices)) def test__bfs__when_undirected_graph_and_no_roots__then_empty(self): # when result = bfs(self._undirected_graph, EmptyStrategy(), []) # then assert_that(list(result)).is_empty() def test__bfs__when_directed_graph_and_single_root__then_visited_visited( self): # when result = bfs(self._directed_graph, EmptyStrategy(), [self._directed_graph.get_vertex(1)]) # then assert_that(sorted(result)).is_equal_to([ self._directed_graph.get_vertex(0), self._directed_graph.get_vertex(1), self._directed_graph.get_vertex(3), self._directed_graph.get_vertex(4), self._directed_graph.get_vertex(7) ]) def test__bfs__when_directed_graph_and_many_roots__then_all_visited(self): # given strategy = self._TestingStrategy() # when result = bfs(self._directed_graph, strategy, [ self._directed_graph.get_vertex(8), self._directed_graph.get_vertex(6) ]) # then assert_that(sorted(result)).is_equal_to( sorted(self._directed_graph.vertices)) assert_that(sorted(strategy.entries)).is_equal_to( sorted(self._undirected_graph.vertices)) assert_that(sorted(strategy.exits)).is_equal_to( sorted(self._undirected_graph.vertices)) # endregion # region dfs_iterative def test__dfs_iterative__when_undirected_graph_and_single_root__then_visited_visited( self): # when result = dfs_iterative(self._undirected_graph, EmptyStrategy(), [self._undirected_graph.get_vertex(0)]) # then assert_that(sorted(result)).is_equal_to([ self._undirected_graph.get_vertex(0), self._undirected_graph.get_vertex(1), self._undirected_graph.get_vertex(3), self._undirected_graph.get_vertex(4), self._undirected_graph.get_vertex(5), self._undirected_graph.get_vertex(7), self._undirected_graph.get_vertex(8) ]) def test__dfs_iterative__when_undirected_graph_and_many_roots__then_all_visited( self): # given strategy = self._TestingStrategy() # when result = dfs_iterative(self._undirected_graph, strategy, [ self._undirected_graph.get_vertex(0), self._undirected_graph.get_vertex(6) ]) # then assert_that(sorted(result)).is_equal_to( sorted(self._undirected_graph.vertices)) assert_that(sorted(strategy.entries)).is_equal_to( sorted(self._undirected_graph.vertices)) assert_that(sorted(strategy.exits)).is_equal_to( sorted(self._undirected_graph.vertices)) def test__dfs_iterative__when_undirected_graph_and_no_roots__then_empty( self): # when result = dfs_iterative(self._undirected_graph, EmptyStrategy(), []) # then assert_that(list(result)).is_empty() def test__dfs_iterative__when_directed_graph_and_single_root__then_visited_visited( self): # when result = dfs_iterative(self._directed_graph, EmptyStrategy(), [self._directed_graph.get_vertex(1)]) # then assert_that(sorted(result)).is_equal_to([ self._directed_graph.get_vertex(0), self._directed_graph.get_vertex(1), self._directed_graph.get_vertex(3), self._directed_graph.get_vertex(4), self._directed_graph.get_vertex(7) ]) def test__dfs_iterative__when_directed_graph_and_many_roots__then_all_visited( self): # given strategy = self._TestingStrategy() # when result = dfs_iterative(self._directed_graph, strategy, [ self._directed_graph.get_vertex(8), self._directed_graph.get_vertex(6) ]) # then assert_that(sorted(result)).is_equal_to( sorted(self._directed_graph.vertices)) assert_that(sorted(strategy.entries)).is_equal_to( sorted(self._undirected_graph.vertices)) assert_that(sorted(strategy.exits)).is_equal_to( sorted(self._undirected_graph.vertices)) # endregion # region dfs_recursive def test__dfs_recursive__when_undirected_graph_and_single_root__then_visited_visited( self): # when result = dfs_recursive(self._undirected_graph, EmptyStrategy(), [self._undirected_graph.get_vertex(0)]) # then assert_that(sorted(result)).is_equal_to([ self._undirected_graph.get_vertex(0), self._undirected_graph.get_vertex(1), self._undirected_graph.get_vertex(3), self._undirected_graph.get_vertex(4), self._undirected_graph.get_vertex(5), self._undirected_graph.get_vertex(7), self._undirected_graph.get_vertex(8) ]) def test__dfs_recursive__when_undirected_graph_and_many_roots__then_all_visited( self): # given strategy = self._TestingStrategy() # when result = dfs_recursive(self._undirected_graph, strategy, [ self._undirected_graph.get_vertex(0), self._undirected_graph.get_vertex(6) ]) # then assert_that(sorted(result)).is_equal_to( sorted(self._undirected_graph.vertices)) assert_that(sorted(strategy.entries)).is_equal_to( sorted(self._undirected_graph.vertices)) assert_that(sorted(strategy.exits)).is_equal_to( sorted(self._undirected_graph.vertices)) def test__dfs_recursive__when_undirected_graph_and_no_roots__then_empty( self): # when result = dfs_recursive(self._undirected_graph, EmptyStrategy(), []) # then assert_that(list(result)).is_empty() def test__dfs_recursive__when_directed_graph_and_single_root__then_visited_visited( self): # when result = dfs_recursive(self._directed_graph, EmptyStrategy(), [self._directed_graph.get_vertex(1)]) # then assert_that(sorted(result)).is_equal_to([ self._directed_graph.get_vertex(0), self._directed_graph.get_vertex(1), self._directed_graph.get_vertex(3), self._directed_graph.get_vertex(4), self._directed_graph.get_vertex(7) ]) def test__dfs_recursive__when_directed_graph_and_many_roots__then_all_visited( self): # given strategy = self._TestingStrategy() # when result = dfs_recursive(self._directed_graph, strategy, [ self._directed_graph.get_vertex(8), self._directed_graph.get_vertex(6) ]) # then assert_that(sorted(result)).is_equal_to( sorted(self._directed_graph.vertices)) assert_that(sorted(strategy.entries)).is_equal_to( sorted(self._undirected_graph.vertices)) assert_that(sorted(strategy.exits)).is_equal_to( sorted(self._undirected_graph.vertices)) # endregion class _TestingStrategy(DFSStrategy): def __init__(self): self.entries = [] self.exits = [] def for_root(self, root): pass def on_entry(self, vertex): self.entries.append(vertex) def on_next_vertex(self, vertex, neighbour): pass def on_exit(self, vertex): self.exits.append(vertex) def on_edge_to_visited(self, vertex, neighbour): pass
class MinimalSpanningTreeTest(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.graph = None def setUp(self): self.graph = UndirectedSimpleGraph(range(5)) self.graph.add_edge_between(self.graph.get_vertex(0), self.graph.get_vertex(1), self._Weight(-1)) self.graph.add_edge_between(self.graph.get_vertex(0), self.graph.get_vertex(2), self._Weight(4)) self.graph.add_edge_between(self.graph.get_vertex(1), self.graph.get_vertex(2), self._Weight(9)) self.graph.add_edge_between(self.graph.get_vertex(1), self.graph.get_vertex(3), self._Weight(7)) self.graph.add_edge_between(self.graph.get_vertex(1), self.graph.get_vertex(4), self._Weight(12)) self.graph.add_edge_between(self.graph.get_vertex(2), self.graph.get_vertex(4), self._Weight(6)) self.graph.add_edge_between(self.graph.get_vertex(3), self.graph.get_vertex(4), self._Weight(3)) def test__kruskal__then_mst(self): # when result = kruskal(self.graph) # then assert_that(sorted(result.vertices)).is_equal_to(sorted(self.graph.vertices)) assert_that(sorted(result.edges)).is_equal_to([self.graph.get_edge(0, 1), self.graph.get_edge(0, 2), self.graph.get_edge(2, 4), self.graph.get_edge(3, 4)]) assert_that(sum(result.properties[edge].weight for edge in result.edges)).is_equal_to(12) def test__prim__then_mst(self): # when result = prim(self.graph, self.graph.get_vertex(0)) # then assert_that(sorted(result.vertices)).is_equal_to(sorted(self.graph.vertices)) assert_that(sorted(result.edges)).is_equal_to([self.graph.get_edge(0, 1), self.graph.get_edge(0, 2), self.graph.get_edge(2, 4), self.graph.get_edge(3, 4)]) assert_that(sum(result.properties[edge].weight for edge in result.edges)).is_equal_to(12) def test__prim__when_different_sources__then_same_mst(self): # when result1 = prim(self.graph, self.graph.get_vertex(1)) result4 = prim(self.graph, self.graph.get_vertex(4)) # then assert_that(result1.edges_count).is_equal_to(result4.edges_count) assert_that(sorted(result1.edges)).is_equal_to(sorted(result4.edges)) class _Weight: def __init__(self, weight): self.weight = weight