How to Check Undirected Graph Connectivity Using BFS in Python

In this tutorial, we will learn how to program “How to Check Undirected Graph Connectivity Using BFS in Python.” The main objective is to understand how to implement undirected graph connectivity using BFS. This tutorial will guide you step by step through the process of implementing graph connectivity using BFS. By the end of this tutorial, you will have a solid understanding of graph connectivity, helping you strengthen your problem-solving abilities and improve your overall coding skills in data structure implementation.

This topic is straightforward and easy to understand. By simply following the instructions provided, you will be able to complete it with ease. The program will guide you step by step through the process of implementing linear search. So, let’s dive into the coding process and start implementing the solution to gain a deeper understanding of search algorithms in Python.

Getting Started:

First you will have to download & install the Python IDLE's, here's the link for the Integrated Development And Learning Environment for Python https://www.python.org/downloads/.

Creating Main Function

This is the main function of the application. The following code will display a simple GUI in terminal console that will display program. To do this, simply copy and paste these blocks of code into the IDLE text editor.
  1. class Graph:
  2.     def __init__(self):
  3.         self.vertices = {}
  4.  
  5.     def add_vertex(self, key):
  6.         vertex = Vertex(key)
  7.         self.vertices[key] = vertex
  8.  
  9.     def get_vertex(self, key):
  10.         return self.vertices[key]
  11.  
  12.     def __contains__(self, key):
  13.         return key in self.vertices
  14.  
  15.     def add_edge(self, src_key, dest_key, weight=1):
  16.         self.vertices[src_key].add_neighbour(self.vertices[dest_key], weight)
  17.  
  18.     def does_edge_exist(self, src_key, dest_key):
  19.         return self.vertices[src_key].does_it_point_to(self.vertices[dest_key])
  20.  
  21.     def add_undirected_edge(self, v1_key, v2_key, weight=1):
  22.         self.add_edge(v1_key, v2_key, weight)
  23.         self.add_edge(v2_key, v1_key, weight)
  24.  
  25.     def does_undirected_edge_exist(self, v1_key, v2_key):
  26.         return (self.does_edge_exist(v1_key, v2_key) and
  27.                 self.does_edge_exist(v2_key, v1_key))
  28.  
  29.     def __iter__(self):
  30.         return iter(self.vertices.values())
  31.  
  32.  
  33. class Vertex:
  34.     def __init__(self, key):
  35.         self.key = key
  36.         self.points_to = {}
  37.  
  38.     def get_key(self):
  39.         return self.key
  40.  
  41.     def add_neighbour(self, dest, weight):
  42.         self.points_to[dest] = weight
  43.  
  44.     def get_neighbours(self):
  45.         return self.points_to.keys()
  46.  
  47.     def get_weight(self, dest):
  48.         return self.points_to[dest]
  49.  
  50.     def does_it_point_to(self, dest):
  51.         return dest in self.points_to
  52.  
  53.  
  54. class Queue:
  55.     def __init__(self):
  56.         self.items = []
  57.  
  58.     def is_empty(self):
  59.         return self.items == []
  60.  
  61.     def enqueue(self, data):
  62.         self.items.append(data)
  63.  
  64.     def dequeue(self):
  65.         return self.items.pop(0)
  66.  
  67.  
  68. def label_all_reachable(vertex, component, label):
  69.     visited = set()
  70.     q = Queue()
  71.  
  72.     q.enqueue(vertex)
  73.     visited.add(vertex)
  74.  
  75.     while not q.is_empty():
  76.         current = q.dequeue()
  77.         component[current] = label
  78.  
  79.         for dest in current.get_neighbours():
  80.             if dest not in visited:
  81.                 visited.add(dest)
  82.                 q.enqueue(dest)
  83.  
  84.  
  85. # MAIN PROGRAM
  86. while True:
  87.  
  88.     print("\n================= Check Undirected Graph Connectivity =================\n")
  89.  
  90.     g = Graph()
  91.  
  92.     print("Undirected Graph")
  93.     print("Menu")
  94.     print("add vertex <key>")
  95.     print("add edge <src> <dest>")
  96.     print("components")
  97.     print("display")
  98.     print("quit")
  99.  
  100.     while True:
  101.  
  102.         do = input("\nWhat would you like to do? ").split()
  103.  
  104.         if len(do) == 0:
  105.             continue
  106.  
  107.         operation = do[0]
  108.  
  109.         if operation == "add":
  110.             suboperation = do[1]
  111.  
  112.             if suboperation == "vertex":
  113.                 key = int(do[2])
  114.  
  115.                 if key not in g:
  116.                     g.add_vertex(key)
  117.                 else:
  118.                     print("Vertex already exists.")
  119.  
  120.             elif suboperation == "edge":
  121.                 src = int(do[2])
  122.                 dest = int(do[3])
  123.  
  124.                 if src not in g:
  125.                     print("Vertex {} does not exist.".format(src))
  126.                 elif dest not in g:
  127.                     print("Vertex {} does not exist.".format(dest))
  128.                 else:
  129.                     if not g.does_undirected_edge_exist(src, dest):
  130.                         g.add_undirected_edge(src, dest)
  131.                     else:
  132.                         print("Edge already exists.")
  133.  
  134.         elif operation == "components":
  135.  
  136.             component = dict.fromkeys(g, None)
  137.             label = 1
  138.  
  139.             for v in g:
  140.                 if component[v] is None:
  141.                     label_all_reachable(v, component, label)
  142.                     label += 1
  143.  
  144.             max_label = label
  145.  
  146.             for label in range(1, max_label):
  147.                 component_vertices = [v.get_key() for v in component
  148.                                       if component[v] == label]
  149.  
  150.                 print("Component {}:".format(label), component_vertices)
  151.  
  152.         elif operation == "display":
  153.  
  154.             print("Vertices:", end=" ")
  155.             for v in g:
  156.                 print(v.get_key(), end=" ")
  157.             print()
  158.  
  159.             print("Edges:")
  160.             for v in g:
  161.                 for dest in v.get_neighbours():
  162.                     w = v.get_weight(dest)
  163.                     print("(src={}, dest={}, weight={})".format(
  164.                         v.get_key(), dest.get_key(), w))
  165.  
  166.         elif operation == "quit":
  167.             break
  168.  
  169.         else:
  170.             print("Invalid command.")
  171.  
  172.     # Try Again Option
  173.     opt = input("\nDo you want to try again? (yes/no): ").strip().lower()
  174.  
  175.     if opt == "no":
  176.         print("Exiting program...")
  177.         break
  178.     elif opt != "yes":
  179.         print("Invalid choice. Exiting program...")
  180.         break

This program demonstrates how to check the connectivity of an undirected graph using Python. It defines a `Graph` class to manage vertices and edges, and a `Vertex` class to represent each node along with its neighboring vertices and edge weights. The graph supports operations such as adding vertices, creating undirected edges between vertices, checking whether an edge already exists, and displaying the graph structure. To determine connectivity, the program uses a Breadth-First Search (BFS) approach implemented in the `label_all_reachable` function, which explores all vertices reachable from a starting vertex and assigns them the same component label. By repeating this process for all unvisited vertices, the program identifies and prints the different connected components of the graph. A simple queue structure is used to manage the BFS traversal. Through a menu-driven interface, users can interactively build the graph, display its vertices and edges, and check its connected components until they choose to exit the program.

Output:

There you have it we successfully created How to Check Undirected Graph Connectivity Using BFS in Python. I hope that this simple tutorial help you to what you are looking for. For more updates and tutorials just kindly visit this site. Enjoy Coding!

More Tutorials for Python Language

Python Tutorials