networkx
LibraryA graph is a collection of nodes (also called vertices) and edges that connect these nodes. Nodes represent objects, and edges represent the relationships between these objects. For example, in a social network, users can be represented as nodes, and friendships can be represented as edges.
Dijkstra’s algorithm is used to find the shortest path between a source node and all other nodes in a weighted graph with non - negative edge weights.
import heapq
def dijkstra(graph, start):
distances = {node: float('inf') for node in graph}
distances[start] = 0
priority_queue = [(0, start)]
while priority_queue:
current_distance, current_node = heapq.heappop(priority_queue)
if current_distance > distances[current_node]:
continue
for neighbor, weight in graph[current_node].items():
distance = current_distance + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(priority_queue, (distance, neighbor))
return distances
graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'C': 2, 'D': 5},
'C': {'A': 4, 'B': 2, 'D': 1},
'D': {'B': 5, 'C': 1}
}
start_node = 'A'
result = dijkstra(graph, start_node)
print(result)
The A* algorithm is a popular path - finding algorithm that combines the features of Dijkstra’s algorithm and greedy best - first search. It uses a heuristic function to estimate the cost from a node to the goal node.
import heapq
def heuristic(a, b):
# A simple heuristic function (Manhattan distance in a grid)
return abs(a[0] - b[0]) + abs(a[1] - b[1])
def a_star(graph, start, goal):
open_list = []
heapq.heappush(open_list, (0, start))
came_from = {}
g_score = {node: float('inf') for node in graph}
g_score[start] = 0
f_score = {node: float('inf') for node in graph}
f_score[start] = heuristic(start, goal)
while open_list:
_, current = heapq.heappop(open_list)
if current == goal:
path = []
while current in came_from:
path.append(current)
current = came_from[current]
path.append(start)
path.reverse()
return path
for neighbor in graph[current]:
tentative_g_score = g_score[current] + 1
if tentative_g_score < g_score[neighbor]:
came_from[neighbor] = current
g_score[neighbor] = tentative_g_score
f_score[neighbor] = tentative_g_score + heuristic(neighbor, goal)
heapq.heappush(open_list, (f_score[neighbor], neighbor))
return None
graph = {
(0, 0): [(0, 1), (1, 0)],
(0, 1): [(0, 0), (0, 2), (1, 1)],
(0, 2): [(0, 1), (1, 2)],
(1, 0): [(0, 0), (1, 1)],
(1, 1): [(0, 1), (1, 0), (1, 2)],
(1, 2): [(0, 2), (1, 1)]
}
start = (0, 0)
goal = (1, 2)
path = a_star(graph, start, goal)
print(path)
Kruskal’s algorithm is used to find the minimum spanning tree (MST) of a weighted undirected graph.
def find(parent, i):
if parent[i] == i:
return i
return find(parent, parent[i])
def union(parent, rank, x, y):
xroot = find(parent, x)
yroot = find(parent, y)
if rank[xroot] < rank[yroot]:
parent[xroot] = yroot
elif rank[xroot] > rank[yroot]:
parent[yroot] = xroot
else:
parent[yroot] = xroot
rank[xroot] += 1
def kruskal(edges, num_vertices):
result = []
edges = sorted(edges, key=lambda item: item[2])
parent = []
rank = []
for node in range(num_vertices):
parent.append(node)
rank.append(0)
e = 0
i = 0
while e < num_vertices - 1:
u, v, w = edges[i]
i = i + 1
x = find(parent, u)
y = find(parent, v)
if x != y:
e = e + 1
result.append([u, v, w])
union(parent, rank, x, y)
return result
edges = [
[0, 1, 10],
[0, 2, 6],
[0, 3, 5],
[1, 3, 15],
[2, 3, 4]
]
num_vertices = 4
mst = kruskal(edges, num_vertices)
print(mst)
networkx
Librarynetworkx
is a powerful Python library for working with graphs. It provides easy - to - use functions for creating, analyzing, and visualizing graphs.
import networkx as nx
import matplotlib.pyplot as plt
# Create a directed graph
G = nx.DiGraph()
# Add nodes
G.add_nodes_from([1, 2, 3, 4])
# Add edges
G.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 1)])
# Draw the graph
nx.draw(G, with_labels=True)
plt.show()
# Find the shortest path using Dijkstra's algorithm
shortest_path = nx.dijkstra_path(G, 1, 3)
print(shortest_path)
Implementing algorithms from scratch helps in understanding the underlying concepts better. The code examples above for Dijkstra’s, A*, and Kruskal’s algorithms are all implemented from scratch.
Visualizing graphs can help in understanding the structure and relationships between nodes. We can use libraries like matplotlib
and networkx
for graph visualization.
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph()
G.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 1)])
nx.draw(G, with_labels=True)
plt.show()
current_distance
and priority_queue
.find
and union
operations.Advanced graph algorithms are essential for solving a wide range of complex problems. Python, with its simplicity and the availability of libraries like networkx
, makes it easy to implement and understand these algorithms. By learning the fundamental concepts, using the right usage methods, following common practices, and adhering to best practices, you can efficiently use advanced graph algorithms in your projects.