def test_get_all_vertices(self): graph = Graph() self.assertSequenceEqual([], graph.get_all_vertices()) graph.add_vertex(1) graph.add_vertex(2) graph.add_vertex(3) graph.add_edge(4, 5) self.assertSetEqual(set([1, 2, 3, 4, 5]), set(graph.get_all_vertices()))
def test_add_edge(self): graph = Graph() graph.add_vertex(5) graph.add_vertex(1) graph.add_vertex(2) graph.add_edge(5, 1) graph.add_edge(5, 2) graph.add_edge(3, 4) self.assertSequenceEqual([1, 2], graph.adjacency_list[5]) self.assertSequenceEqual([5], graph.adjacency_list[1]) self.assertSequenceEqual([5], graph.adjacency_list[2]) self.assertSequenceEqual([3], graph.adjacency_list[4]) self.assertSequenceEqual([4], graph.adjacency_list[3])
def kruskal(graph): total_cost = 0 min_cost_tree = Graph() connected_components = UnionFind(graph.get_all_vertices()) edges_queue = graph.get_all_edges() heapq.heapify(edges_queue) while edges_queue: cost, edge = heapq.heappop(edges_queue) if is_valid_edge(edge, min_cost_tree, connected_components): total_cost += cost min_cost_tree.add_edge(edge[0], edge[1], cost) connected_components.union(edge[0], edge[1]) return total_cost, min_cost_tree
def test_get_vertex_environment(self): graph = Graph() graph.add_edge(1, 2) graph.add_edge(1, 3) graph.add_edge(2, 4) self.assertSequenceEqual([2, 3], graph.get_vertex_environment(1)) self.assertSequenceEqual([1, 4], graph.get_vertex_environment(2)) self.assertEqual([], graph.get_vertex_environment(100))
def prim(graph): total_cost = 0 min_cost_tree = Graph() start_vertex = graph.get_start_vertex() vertices_queue = [(0, (start_vertex, start_vertex))] while vertices_queue: cost, (vertex, orig_vertex) = heapq.heappop(vertices_queue) if vertex not in min_cost_tree: total_cost += cost min_cost_tree.add_edge(vertex, orig_vertex) for adjacent_vertex in graph.get_vertex_environment(vertex): if adjacent_vertex not in min_cost_tree: heapq.heappush(vertices_queue, (graph.get_edge_cost( (vertex, adjacent_vertex)), (adjacent_vertex, vertex))) return total_cost, min_cost_tree
def test_is_connected(self): graph = Graph() graph.add_edge(1, 2) graph.add_edge(2, 3) graph.add_edge(2, 4) graph.add_edge(3, 4) self.assertTrue(utils.is_graph_connected(graph)) graph.add_edge(5, 6) self.assertFalse(utils.is_graph_connected(graph))
def test_add_vertex(self): graph = Graph() graph.add_vertex(5) graph.add_vertex(1) graph.add_vertex(2) self.assertSequenceEqual([], graph.adjacency_list[5]) self.assertSequenceEqual([], graph.adjacency_list[1]) self.assertSequenceEqual([], graph.adjacency_list[2]) with self.assertRaises(Exception): graph.add_vertex(5)
def test_is_adjacent_vertices(self): graph = Graph() graph.add_edge(1, 2) graph.add_edge(3, 4) self.assertTrue(graph.is_adjacent_vertices(1, 2)) self.assertTrue(graph.is_adjacent_vertices(3, 4)) self.assertFalse(graph.is_adjacent_vertices(1, 4)) self.assertFalse(graph.is_adjacent_vertices(5, 10))
def tsp(graph: Graph): if len(graph) <= 3: return list(graph.get_all_vertices()) best_cycle = list(graph.get_all_vertices()) best_cycle_weight = graph.cycle_weight(best_cycle) i = 1 improvement = True while improvement and i < len(graph): improvement = False current_cycle = best_cycle[:] for j in range(i + 2, len(graph) + i - 1): current_cycle[i], current_cycle[j % len(graph)] = current_cycle[ j % len(graph)], current_cycle[i] if (new_length := graph.cycle_weight(current_cycle)) < best_cycle_weight: best_cycle = current_cycle[:] best_cycle_weight = new_length improvement = True current_cycle[j % len(graph)], current_cycle[i] = current_cycle[ i], current_cycle[j % len(graph)] i += 1
def non_backtracking_test(N, q, c_avg, delta_min, delta_max, step, nb_instances): f = open('non_backtr_results.txt', 'w') f.write('Overlap obtained by the non-backtracking spectral algorithm on graphs with {} groups and average degree {}.'.format(q, c_avg)) f.write('\nEvery group has the same number of nodes, and each result shown is for an independent random SBM graph with {} nodes.'.format(N)) nb_vector = np.array([N//q for _ in range(q)]) for delta in np.arange(delta_min, delta_max, step): sum_ovlp = 0 edge_matrix = construct_edge_matrix(q, c_avg, delta) f.write('\n\nResults for c_in = {:.3f}, c_out = {:.3f}:'.format(edge_matrix[0][0], edge_matrix[0][1])) for i in range(1, nb_instances + 1): g = Graph(np.copy(nb_vector), np.copy(edge_matrix)/N) ovlp = non_backtr_cluster(g.nb_nodes, g.nb_groups, g.adj_list, g.group, g.group_prop) sum_ovlp += ovlp f.write('\n\tOverlap from test {}:'.format(i)) f.write(' {:.3f}'.format(ovlp)) f.write('\n\t\tAverage overlap: {:.3f}'.format(sum_ovlp/nb_instances)) f.close()
def test_is_acyclic_graph(self): graph = Graph() self.assertTrue(utils.is_acyclic_graph(graph)) graph.add_edge(1, 2) graph.add_edge(2, 3) graph.add_edge(1, 3) self.assertFalse(utils.is_acyclic_graph(graph)) graph.remove_edge(1, 3) self.assertTrue(utils.is_acyclic_graph(graph)) graph.add_edge(2, 4) graph.add_edge(3, 4) self.assertFalse(utils.is_acyclic_graph(graph)) graph.remove_edge(3, 4) self.assertTrue(utils.is_acyclic_graph(graph)) graph.add_edge(3, 5) graph.add_edge(3, 7) graph.add_edge(5, 7) self.assertFalse(utils.is_acyclic_graph(graph))
def test_euler_cycle(self): graph = Graph() self.assertIsNone(utils.find_euler_cycle(graph)) graph.add_edge(1, 2) graph.add_edge(1, 3) self.assertIsNone(utils.find_euler_cycle(graph)) graph.add_edge(2, 3) self.assertSequenceEqual([1, 2, 3, 1], utils.find_euler_cycle(graph)) graph.add_edge(2, 4) graph.add_edge(2, 6) graph.add_edge(3, 6) graph.add_edge(3, 5) graph.add_edge(5, 6) graph.add_edge(5, 4) graph.add_edge(4, 6) graph.add_edge(4, 7) graph.add_edge(5, 7) self.assertSequenceEqual([1, 2, 4, 6, 5, 7, 4, 5, 3, 6, 2, 3, 1], utils.find_euler_cycle(graph, 1))
def test_kruskal(self): graph = Graph() total_cost, _ = utils.kruskal(graph) self.assertEqual(0, total_cost) graph.add_edge('A', 'D', 5) graph.add_edge('A', 'B', 7) graph.add_edge('D', 'B', 9) graph.add_edge('D', 'E', 15) graph.add_edge('B', 'E', 7) graph.add_edge('B', 'C', 8) graph.add_edge('C', 'E', 5) graph.add_edge('D', 'F', 6) graph.add_edge('E', 'G', 9) graph.add_edge('F', 'G', 11) graph.add_edge('F', 'E', 8) total_cost, result_graph = utils.kruskal(graph) self.assertEqual(39, total_cost) self.assertEqual(7, len(result_graph.get_all_vertices())) self.assertTrue(utils.is_graph_connected(result_graph)) self.assertTrue(utils.is_acyclic_graph(result_graph))
# recursively search for parent # if the parent of the two vertexes are not the same, union them and add to the spanningtree minimumSpanningTree = set() for edge in edges: weight, vertice1, vertice2 = edge if find(vertice1) != find(vertice2): union(vertice1, vertice2) minimumSpanningTree.add(edge) return minimumSpanningTree if __name__ == '__main__': # Prim G = Graph() G.addEdge("A", "B", 7) G.addEdge("A", "D", 5) G.addEdge("B", "C", 8) G.addEdge("B", "D", 9) G.addEdge("B", "E", 7) G.addEdge("C", "E", 5) G.addEdge("D", "E", 15) G.addEdge("D", "F", 6) G.addEdge("E", "F", 8) G.addEdge("E", "G", 9) G.addEdge("F", "G", 11) print('Graph data:') for v in G: for w in v.getConnections():
def test_remove_edge(self): graph = Graph() graph.add_edge(1, 2) graph.add_edge(1, 3) graph.add_edge(1, 4) graph.add_edge(2, 4) graph.add_edge(3, 4) graph.remove_edge(1, 2) self.assertSequenceEqual([3, 4], graph.adjacency_list[1]) self.assertSequenceEqual([4], graph.adjacency_list[2]) graph.remove_edge(2, 4) self.assertSequenceEqual([], graph.adjacency_list[2]) self.assertSequenceEqual([1, 3], graph.adjacency_list[4]) with self.assertRaises(Exception): graph.remove_edge(5, 10) graph.remove_edge(1, 2)
def test_tsp(self): graph = Graph() graph.add_edges([(1, 2, 5), (1, 3, 2), (1, 4, 1), (1, 5, 7), (2, 3, 4), (2, 4, 3), (2, 5, 2), (3, 4, 3), (3, 5, 6), (4, 5, 4)]) self.assertEqual([1, 4, 5, 2, 3], utils.tsp(graph))
def test_gis(self): graph = Graph() graph.add_edges([(1, 2), (1, 7), (2, 3), (7, 6), (6, 3), (3, 4), (6, 4), (6, 5), (5, 4)]) vertices_colors, used_colors = utils.gis(graph) self.assertDictEqual({1: 0, 5: 0, 3: 0, 2: 1, 4: 1, 7: 1, 6: 2}, vertices_colors) self.assertEqual(used_colors, 3)
def test_is_bipartite(self): graph = Graph() self.assertTrue(utils.is_bipartite(graph)) graph.add_vertices([1, 2, 3]) self.assertTrue(utils.is_bipartite(graph)) graph.add_edge(1, 2) graph.add_edge(3, 4) graph.add_edge(1, 4) graph.add_edge(2, 3) graph.add_edge(4, 5) graph.add_edge(5, 6) self.assertTrue(utils.is_bipartite(graph)[0]) graph.add_edge(1, 5) self.assertFalse(utils.is_bipartite(graph)[0]) graph = Graph() graph.add_edges([(1, 5), (2, 5), (2, 6), (6, 7), (7, 3), (7, 4)]) self.assertTrue(utils.is_bipartite(graph)[0]) graph = Graph() graph.add_edges([(1, 4), (2, 4), (1, 2), (2, 5), (5, 3)]) self.assertFalse(utils.is_bipartite(graph)[0])
def test_dsatur(self): graph = Graph() graph.add_edges([(1, 2), (1, 7), (2, 3), (7, 6), (6, 3), (3, 4), (6, 4), (6, 5), (5, 4)]) vertices_colors, used_colors = utils.dsatur(graph) self.assertDictEqual({6: 0, 3: 1, 4: 2, 5: 1, 2: 0, 1: 1, 7: 2}, vertices_colors) self.assertEqual(used_colors, 3)