algos_and_structures/grokaem/graphs/dijkstra.py
2024-11-02 14:03:30 +03:00

130 lines
3.6 KiB
Python

# First - initializing the graph
graph = {}
# Put first element in graph
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2
# Put A element in graph
graph["a"] = {}
graph["a"]["fin"] = 1
# Put B element in graph
graph["b"] = {}
graph["b"]["fin"] = 5
graph["b"]["a"] = 3
# Put last element in graph
graph["fin"] = {}
# Now we need to declare "costs" hash table
# Costs table shows how much time needed to reach to this node from the starting node
# Settings up infinity value
infinity = float("inf")
# initializing "costs" hash-table
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity
# We also needed "parents" hash-table
parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None
# ------- Notebook graph example -------
graph_notebook = {}
graph_notebook["a"] = {}
graph_notebook["a"]["b"] = 1
graph_notebook["a"]["d"] = 10
graph_notebook["b"] = {}
graph_notebook["b"]["c"] = 2
graph_notebook["c"] = {}
graph_notebook["c"]["d"] = 3
graph_notebook["c"]["e"] = 15
graph_notebook["d"] = {}
graph_notebook["d"]["e"] = 1
graph_notebook["e"] = {}
costs_notebook = {}
costs_notebook["b"] = 1
costs_notebook["d"] = 10
costs_notebook["c"] = infinity
costs_notebook["e"] = infinity
# We also needed "parents" hash-table
parents_notebook = {}
parents_notebook["b"] = "a"
parents_notebook["d"] = "a"
parents_notebook["c"] = None
parents_notebook["e"] = None
def dijkstra_algo(graph, costs, parents):
# We need to store processed nodes list
processed = []
# First we need to define function for finding the lowest cost node to process it
def find_lowest_cost_node(costs):
lowest_cost = float("inf")
lowest_cost_node = None
for node in costs:
cost = costs[node]
if cost < lowest_cost and node not in processed:
lowest_cost = cost
lowest_cost_node = node
return lowest_cost_node
# And now we initiate the algorithm
node = find_lowest_cost_node(costs)
step = 1
while node is not None:
print(f"Step {step}")
print(f"Current data:\nParents: {parents}\nCosts: {costs}\n\n")
print(f"current lowest node: {node}. Start to inspect it")
cost = costs[node]
neighbors = graph[node]
print(f"Cost of node {node} = {cost}")
print(f"Neighbors of node {node} = {neighbors}")
for n in neighbors.keys():
print(f" Processing neighbor {n}")
new_cost = cost + neighbors[n]
print(f" New calculated cost for neighbor {n} = {new_cost}")
if costs[n] > new_cost:
print(
f" New calculated cost {new_cost} is lower than old node cost {costs[n]} so we replace it with new value and new parent {node}"
)
costs[n] = new_cost
parents[n] = node
print(
f" New costs table:\n {costs}\n New parents table:\n {parents}"
)
else:
print(
f" New calculated cost {new_cost} is greater than old node cost {costs[n]} so we do not touching costs and parents table"
)
print(f" Costs table:\n {costs}\n Parents table:\n {parents}")
print(
f"Work with node {node} is finished, so we marking it with processed label"
)
processed.append(node)
node = find_lowest_cost_node(costs)
step += 1
print("--------------------")
print(processed)
print(parents)
print(costs)
dijkstra_algo(graph_notebook, costs_notebook, parents_notebook)