Reputation: 518
I am trying to get the user to enter a graph manually as opposed to using it 'pre-existing' in the code, for use in my Dijkstra's Algorithm.
I have done this but would like some feedback on its implementation and user friendliness. In addition is there a more efficient way of entering a graph into a nested dictionary ? If so how ?.
Key points about code
Many Thanks. Edit: repeat requirement no longer needed.
{'A': {'C': 1, 'B': 5}, 'D': {}, 'B': {'D': 2}, 'C': {'D': 9}}
^ Desired output for nodes also current output.
nodes = {}
def add_node():
entered_graph = False
while not entered_graph:
source_node = input("Enter a source node: ")
num_neighbours = int(input("Enter how many neighbours this node has"
"including previously entered nodes: "))
nodes[source_node] = {}
for neighbour in range(num_neighbours):
neighbour = input("Enter neighbor node: ")
distance = int(input("Enter distance from source node to this neighbor node: "))
nodes[source_node][neighbour] = distance
end_loop = input("Enter y to finish graph entry: ")
end_loop = end_loop.lower()
if end_loop == "y":
entered_graph = True
add_node()
print(nodes)
Upvotes: 1
Views: 1290
Reputation: 11075
Khanacademy has a pretty good page on different ways to represent graphs.
For an undirected graph (a => b and b => a) I would personally look at using an edge list. It can be sorted to improve lookup efficiency, and it is more memory efficient than other methods such as an adjacency table
Upvotes: 0
Reputation: 60984
You really only want users to enter every edge once, then you can just store it twice.
edges = {}
while True:
edge = input('Enter an edge as Node names separated by a space followed by a number ("exit" to exit): ')
if edge == 'exit':
break
node1, node2, weight = edge.split()
weight = float(weight)
if node1 not in edges:
edges[node1] = {}
if node2 not in edges:
edges[node2] = {}
edges[node1][node2] = weight
edges[node2][node1] = weight
User enters each edge once as "A B 3.5"
Upvotes: 1