def __init__(self, truck_id, package_limit, speed, start_of_day, hub_location): """ Create Truck Object :param truck_id: id of the truck :int :param package_limit: maximum number of packages truck can hold :int :param speed: speed of truck in miles per hour :int :param start_of_day: time of start of day :str :param hub_location: location of hub :Location :return: Truck Object Worst Case Runtime Complexity: O(1) Best Case Runtime Complexity: O(1) """ self._id = truck_id self._package_limit = package_limit self._speed = (speed / 60) / 60 # truck speed in miles per second self._locations = Graph() self._packages = [] self._start_of_day = start_of_day self._locations.add_vertex(hub_location.name, hub_location) self._route = Queue() self._departure_time = None # departure time in seconds since start self._distance_traveled = 0.0 self._current_location = None self._next_location = None self._route_done = False
def setUp(self) -> None: node1 = GraphNode(data=1) node2 = GraphNode(data=2) node3 = GraphNode(data=3) node4 = GraphNode(data=4) node5 = GraphNode(data=5) node6 = GraphNode(data=6) node7 = GraphNode(data=7) node8 = GraphNode(data=8) node9 = GraphNode(data=9) node10 = GraphNode(data=10) node11 = GraphNode(data=11) node12 = GraphNode(data=12) node13 = GraphNode(data=13) node14 = GraphNode(data=14) node15 = GraphNode(data=15) node1.add_child(node5) node2.add_children([node5, node9, node10]) node3.add_children([node2, node13, node4]) node4.add_children([node5, node6, node8]) node5.add_children([node3]) node6.add_child(node7) node9.add_child(node10) node10.add_child(node11) node11.add_child(node12) node13.add_child(node14) node14.add_child(node15) my_graph = Graph() my_graph.add_nodes([ node1, node2, node3, node4, node5, node6, node7, node8, node9, node10, node11, node12, node13, node14, node15 ]) self.my_graph = my_graph
def show_graph(g: Graph): """ Displays the graph g. :param g: the graph to display """ vertices = g.vertices() edges = g.edges() dg = nx.DiGraph() dg.add_nodes_from(vertices, label=vertices) dg.add_weighted_edges_from([ (edge._origin, edge._destination, edge.element()) for edge in edges ]) plt.plot() layout = nx.circular_layout(dg) nx.draw(dg, layout, with_labels=True, connectionstyle='arc3, rad = 0.15') labels = nx.get_edge_attributes(dg, "weight") for key, weight in labels.items(): labels[key] = round(labels[key], 2) nx.draw_networkx_edge_labels(dg, pos=layout, font_color='b', edge_labels=labels, label_pos=0.25, font_size=8) plt.show()
def test_has_node(): _graph = Graph() _node1 = Node(4) _node2 = Node(5) _graph.add_node(_node1) assert _graph.had_node(_node1) == True assert _graph.had_node(_node2) == False
def test_size_empty(): graph = Graph() expected = 0 actual = graph.size() assert actual == expected
def test_add_node(): graph = Graph() expected = "spam" # a vertex's value that comes back actual = graph.add_node("spam").value assert actual == expected
def knight_graph(board_size): kt_graph = Graph() for row in range(board_size): for col in range(board_size): node_id = pos_to_node_id(row, col, board_size) new_positions = gen_legal_moves(row, col, board_size) for e in new_positions: n_id = pos_to_node_id(e[0], e[1], board_size) kt_graph.add_edge(node_id, n_id) return kt_graph
def test_add_edge_interloper_end(): graph = Graph() end = Vertex("end") start = graph.add_node("start") with pytest.raises(KeyError): graph.add_edge(start, end)
def test_size(): graph = Graph() graph.add_node("spam") expected = 1 actual = graph.size() assert actual == expected
def create_graph3(): graph = Graph() nodes = [1, 2, 3, 4, 5] edges = [ (1, 3, 1), (1, 2, 2), (3, 6, 3), (2, 4, 2), (4, 5, 1) ] for n in nodes: graph.add_node(n) for e in edges: graph.add_edge(e[0], e[1], e[2]) return graph
def steiner_tree(graph): leaf_nodes = graph.find_non_terminal_leaves() # Get a copy of the graph edges # we are going to delete edges from this dictionary (by setting their value to an empty list) new_edges = graph.edges.copy() # Same with the nodes new_nodes = graph.nodes.copy() # For all non-terminal leaves in the MST for leaf in leaf_nodes: node_num = leaf[0] edge_num = list(leaf[1].values())[0] leaf_edge = graph.edges[edge_num] # Second node connected to the edge second_node = leaf_edge[0] if leaf_edge[ 1] == node_num else leaf_edge[1] # Setting the value of the chosen edge and node to [] (as if we have deleted it) new_edges[edge_num] = [] new_nodes[node_num] = [] # Update the second node's degree and edges dictionary graph.nodes[second_node][0] -= 1 graph.nodes[second_node][1].pop(node_num) # Checking if the remaining node is a leaf and not a terminal while graph.nodes[second_node][2] == 0 and graph.nodes[ second_node][0] == 1: node_num = second_node node_edges = graph.nodes[second_node][1] edge_num = list(node_edges.values())[0] leaf_edge = graph.edges[edge_num] second_node = leaf_edge[0] if leaf_edge[ 1] == node_num else leaf_edge[1] new_edges[edge_num] = [] new_nodes[node_num] = [] graph.nodes[second_node][0] -= 1 graph.nodes[second_node][1].pop(node_num) # Making new dictionaries of the updated nodes and edges to make a graph from them new_graph_nodes = {k: v[2] for k, v in new_nodes.items() if v != []} edge_number = 1 new_graph_edges = {} for k, v in new_edges.items(): if v: new_graph_edges[edge_number] = v edge_number += 1 steiner_tree = Graph(len(new_graph_nodes), len(new_graph_edges), new_graph_nodes, new_graph_edges) return steiner_tree, steiner_tree.graph_weight()
def create_graph(): graph = Graph() nodes = [1, 2, 3, 4, 5] edges = [ (1, 2, 1), (2, 3, 2), (3, 4, 3), (4, 5, 6) ] for n in nodes: graph.add_node(n) for e in edges: # node1, node2, weight graph.add_edge(e[0], e[1], e[2]) return graph
def cyclical_graph(): graph = Graph() nodes = [1, 2, 3, 4, 5, 6, 7] edges = [ (1, 2, 3), (2, 3, 3), (3, 5, 2), (5, 4, 2), (5, 6, 1), (4, 2, 1), (4, 7, 1) ] for n in nodes: graph.add_node(n) for e in edges: graph.add_edge(e[0], e[1], e[2]) return graph
def test_remove_node(self): print('Test: test_remove_node') g = Graph() print('Test: remove a non-existent node') self.assertRaises(ValueError, g.remove_node, 0) print('Test: general case') n = g.add_node() self.assertEqual(len(g._nodes), 1) g.remove_node(n.key) self.assertEqual(len(g._nodes), 0) print('Success: test_remove_node')
def generate_sample_graph(is_directed=False): ''' Will return a graph obj as such, either undirected or directed based on the optional arg: undirected [A] -> {'B', 'C'} [B] -> {'A', 'D', 'E'} [C] -> {'A', 'F'} [D] -> {'B'} [E] -> {'B', 'F'} [F] -> {'E', 'C'} directed [A] -> {'C', 'B'} [B] -> {'E', 'D'} [C] -> {'F'} [E] -> {'F'} ''' graph = Graph(is_directed) graph.add_edge('A', 'B') graph.add_edge('A', 'C') graph.add_edge('B', 'D') graph.add_edge('B', 'E') graph.add_edge('C', 'F') graph.add_edge('E', 'F') return graph
def test_get_nodes(): graph = Graph() banana = graph.add_node("banana") apple = graph.add_node("apple") loner = Vertex("loner") expected = 2 actual = len(graph.get_nodes()) assert actual == expected
def create_spaghetti(): graph = Graph() nodes = [1, 2, 3, 4, 5, 6, 7, 8, 9] edges = [ (1, 2, 3), (1, 3, 2), (1, 4, 5), (2, 9, 5), (2, 5, 3), (2, 6, 6), (3, 5, 5), (3, 7, 2), (4, 6, 6), (4, 8, 2), (9, 5, 4), (6, 9, 4), (7, 8, 5) ] for n in nodes: graph.add_node(n) for e in edges: graph.add_edge(e[0], e[1], e[2]) return graph
def test_graph_cracov_easy_path_len(self): stops_common = [ "Czerwone Maki", "Chmieleniec", "Kampus UJ", "Ruczaj", "Norymberska", "Grota", "Lipinskiego" ] nodes = {} for name in stops_common: nodes[name] = Node(name) def conn_nod(a, b, len): connect_both(nodes[a], nodes[b], len) def ass_path_len(a, b, i): self.assert_path_len( graph, a, b, i, "between {0} and {1} should be {2}".format(a, b, i)) nodes_list = [node for node in nodes.values()] conn_nod(stops_common[0], stops_common[1], 5) conn_nod(stops_common[1], stops_common[2], 5) conn_nod(stops_common[2], stops_common[3], 5) conn_nod(stops_common[3], stops_common[4], 5) conn_nod(stops_common[4], stops_common[5], 5) conn_nod(stops_common[5], stops_common[6], 5) graph = Graph(nodes_list) q = 0 for i in range(0, len(stops_common)): for q in range(0, len(stops_common)): self.assert_path_len(graph, stops_common[i], stops_common[q], abs(i - q) * 5)
def test_get_edges(self): """ A - 1 - B - 2 - C - 1 - D | | 1 5 | | E - 1 - F """ nodes = {} for letter in "ABCDEF": nodes[letter] = Node(letter) def conn_nod(a, b, len): connect_both(nodes[a], nodes[b], len) conn_nod("A", "B", 1) conn_nod("A", "E", 1) conn_nod("E", "F", 1) conn_nod("F", "B", 5) conn_nod("B", "C", 2) conn_nod("D", "C", 1) graph = Graph([nodes[key] for key in nodes]) self.assertEqual(graph["A", "B"], 1) self.assertEqual(graph["A", "E"], 1) self.assertEqual(graph["E", "F"], 1) self.assertEqual(graph["F", "B"], 5) self.assertEqual(graph["B", "C"], 2) self.assertEqual(graph["D", "C"], 1)
def test_graph_cracov_easy_path_next(self): stops_common = [ "Czerwone Maki", "Chmieleniec", "Kampus UJ", "Ruczaj", "Norymberska", "Grota", "Lipinskiego" ] nodes = {} for name in stops_common: nodes[name] = Node(name) def conn_nod(a, b, len): connect_both(nodes[a], nodes[b], len) nodes_list = [node for node in nodes.values()] for i in range(0, len(stops_common) - 1): conn_nod(stops_common[i], stops_common[i + 1], 5) graph = Graph(nodes_list) for stop in stops_common[1:]: self.assert_path_next_move(graph, "Czerwone Maki", stop, "Chmieleniec") for stop in stops_common[2:]: self.assert_path_next_move(graph, "Chmieleniec", stop, "Kampus UJ") for stop in stops_common[3:]: self.assert_path_next_move(graph, "Kampus UJ", stop, "Ruczaj") for stop in stops_common[:2]: self.assert_path_next_move(graph, "Kampus UJ", stop, "Chmieleniec") for stop in stops_common[4:]: self.assert_path_next_move(graph, "Ruczaj", stop, "Norymberska")
def test_file_data_to_graph(): comment, graph, terminals = FileHandler.read_stp_file( "/home/amir/Desktop/dev/steiner-tree-ds/steiner-tree-ds-project/inputs/bip42p.stp" ) graph_nodes = {k: 0 for k in range(1, graph['Nodes'] + 1)} terminal_nodes = [ terminals[k] for k in range(1, terminals['Terminals'] + 1) ] for terminal in terminal_nodes: graph_nodes[terminal] = 1 graph = Graph(graph['Nodes'], graph['Edges'], graph_nodes, {k: graph[k] for k in range(1, graph['Edges'] + 1)}) print(graph.nodes) print(graph.edges) print(graph.sort_edges())
def test_graph(): terminals = [1, 4] nodes = [1, 2, 3, 4] graph_nodes = {k: 0 for k in nodes} for terminal in terminals: graph_nodes[terminal] = 1 edges = {1: [1, 3, 2], 2: [3, 2, 4], 3: [1, 4, 1], 4: [2, 4, 5]} graph = Graph(4, 4, graph_nodes, { 1: [1, 3, 2], 2: [3, 2, 4], 3: [1, 4, 1], 4: [2, 4, 5] }) print(graph.nodes) print(graph.edges) print(graph.sort_edges())
def test_bfs(self): """ Tests that add_node properly adds nodes to adjecency list """ # Uses graph in this article: # http://bit.ly/2ONjp55 graph = Graph({ 'A': set(['B', 'C']), 'B': set(['A', 'D', 'E']), 'C': set(['A', 'F']), 'D': set(['B']), 'E': set(['B', 'F']), 'F': set(['C', 'E']) }) # self.assertSetEqual(['A', 'B', 'C', '']) path = graph.bfs('A') self.assertListEqual(['A', 'B', 'C', 'E', 'D', 'F'], path) pass
def test_neighbours(): _graph = Graph() _node1 = Node(4) _node2 = Node(5) _node3 = Node(6) _node4 = Node(7) _graph.add_edges(_node1, _node2, 1) _graph.add_edges(_node3, _node4, 1) _graph.add_edges(_node2, _node4, 1) _graph.add_edges(_node1, _node2, 2) _graph.add_edges(_node3, _node4, 2) _graph.add_edges(_node2, _node4, 2) assert _graph.neighbours(_node2) == ['n0', 'n3']
def find_negative_cycle( graph: Graph, source: str) -> Tuple[bool, Optional[List[Graph.Edge]]]: """ Finds a negative cycle starting at source in graph. :param graph: the graph where source is :param source: the starting node of the cycle to find :return: found: True if a negative cycle exists, False otherwise cycle: the list of edges representing the cycle. It is None if found is False. """ # Step 1: Find all neighbors outgoing from source neighbors = { edge.opposite(source): edge for edge in graph.incident_edges(source, outgoing=True) } # Step 2: Find minimum edge weight in the graph minimum_edge_weight = min(edge.element() for edge in graph.edges()) # Step 3: Make all edges positive for edge in graph.edges(): edge._element += abs(minimum_edge_weight) # Step 4: Call compute_shortest_path from each vertex in neighbors to source paths = { vertex: compute_shortest_path(graph, vertex, source) for vertex in neighbors } # Step 5: Restore all edges weights for edge in graph.edges(): edge._element -= abs(minimum_edge_weight) # Step 6: Close cycles for vertex, path in paths.items(): if len(path) == 0: continue path_weight = sum(edge.element() for edge in path) first_edge = neighbors[vertex] first_weight = first_edge.element() cycle_weight = first_weight + path_weight cycle = [first_edge] + path if cycle_weight < 0: return True, cycle return False, None
def build_graph(w_list): d = {} g = Graph() for word in w_list: for i in range(len(word)): bucket = word[:i] + '_' + word[i + 1:] if bucket in d: d[bucket].append(word) else: d[bucket] = [word] for bucket in d.keys(): for word1 in d[bucket]: for word2 in d[bucket]: if word1 != word2: g.add_edge(word1, word2) return g
def generate_graph(voro, width, height): line_list = sort_lines(voro, width, height) g = Graph.Graph() for line in line_list: g.add_vertex(line[0]) g.add_vertex(line[1]) g.add_edge(line[0], line[1], line_tools.calc_length(line)) return g
def test_add_edge(self): print('Test: test_add_edge') g = Graph() print('Test: Invalid input') self.assertRaises(ValueError, g.add_edge, None, None) print('Test: general case') n, n1 = g.add_node(), g.add_node() g.add_edge(n, n1) self.assertIn([n1, 0], n.neighbors) n2 = g.add_node() g.add_edge(n1, n2, 5) self.assertIn([n2, 5], n1.neighbors) print('Success: test_add_edge')
def test_add_edge(): g = Graph() apple = g.add_node("apple") banana = g.add_node("banana") g.add_edge(apple, banana, 5) neighbors = g.get_neighbors(apple) assert len(neighbors) == 1 assert neighbors[0].vertex.value == "banana" assert neighbors[0].weight == 5
def create_graph(currencies: Set[Currency]) -> Graph: """ Creates a directed graph representing currencies. :param currencies: the currencies to insert in the graph :return: the graph representing currencies """ g = Graph(directed=True) for currency in currencies: if currency._code not in g.vertices(): g.insert_vertex(currency._code) for c in currencies: code = c._code try: change = currency.get_change(code) if code not in g.vertices(): g.insert_vertex(code) g.insert_edge(currency._code, code, round(change, 2)) except KeyError: continue return g
def test_adjacent(): _graph = Graph() _node1 = Node(4) _node2 = Node(5) _node3 = Node(6) _node4 = Node(7) _graph.add_edges(_node1, _node2, 1) _graph.add_edges(_node3, _node4, 1) _graph.add_edges(_node2, _node4, 1) assert _graph.adjacent(_node1, _node2) == True assert _graph.adjacent(_node3, _node4) == True assert _graph.adjacent(_node2, _node4) == True assert _graph.adjacent(_node1, _node4) == False
def test_add_node(self): print('Test: test_add_node') print('Test: keys are numbers') g = Graph() g.add_node() self.assertEqual(len(g._nodes), 1) self.assertEqual(g._counter, 1) print('Test: keys are chars') g = Graph(letters=True) g.add_node() self.assertEqual(len(g._nodes), 1) self.assertEqual(g._counter, 98) print('Test: keys are chars (not enough keys)') for i in range(98, 123): g.add_node() self.assertRaises(NotEnoughKeys, g.add_node) print('Success: test_add_node')
def __init__(self, start_time, delayed_flight_time, table_size): """ Create a Simulation Object :param start_time: start time of simulation :param delayed_flight_time: time delayed packages arrive on flight :param table_size: size of the hashtable Worst Case Runtime Complexity: O(1) Best Case Runtime Complexity: O(1) """ self._start_time = start_time self._clock = Clock(0, start_time) self._packages = HashTable(table_size) self._active_trucks = [] self._trucks = Queue() self.simulation_over = False self._delayed_flight_time = Clock.seconds_since_start(delayed_flight_time, start_time) self._delayed_packages_departed = False self._total_miles = 0.0 self.locations = Graph() self.wrong_address_fixed = False
def shortest_reach(n, edges, s): graph = Graph(False) for vertex in range(1, n + 1): graph.add_vertex(vertex) for begin, end, weight in edges: graph.add_edge(begin, end, weight) shortest_paths = graph.dijkstra_shortest_path(s) return [ value.distance if value.distance != inf else -1 for key, value in sorted(shortest_paths.items()) if key != s ]