Example #1
0
    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
Example #2
0
 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
Example #3
0
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()
Example #4
0
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
Example #5
0
def test_size_empty():

    graph = Graph()

    expected = 0

    actual = graph.size()

    assert actual == expected
Example #6
0
def test_add_node():

    graph = Graph()

    expected = "spam"  # a vertex's value that comes back

    actual = graph.add_node("spam").value

    assert actual == expected
Example #7
0
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
Example #8
0
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)
Example #9
0
def test_size():

    graph = Graph()

    graph.add_node("spam")

    expected = 1

    actual = graph.size()

    assert actual == expected
Example #10
0
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()
Example #12
0
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
Example #13
0
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
Example #14
0
    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')
Example #15
0
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
Example #16
0
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
Example #17
0
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
Example #18
0
    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)
Example #19
0
    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)
Example #20
0
    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())
Example #23
0
 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
Example #24
0
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']
Example #25
0
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
Example #26
0
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
Example #27
0
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
Example #28
0
    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')
Example #29
0
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
Example #30
0
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
Example #31
0
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
Example #32
0
    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')
Example #33
0
    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
Example #34
0
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
    ]