Construct a Graph from size of components for each node


Introduction

Graph theory is a fundamental field in computer science, allowing us to study and visualize relationships between objects or entities. One important aspect of analyzing graphs understands the sizes of components or connected subgraphs within the network. In this article, we will explore how to construct a graph from component size for each node using C++ code. In graph theory, a component refers to any connected subgraph where there exists some path between any two vertices within that subgraph. It helps depict clusters or groups of interconnected nodes within the entire graph structure.

A Graph from size of components for each node

Before constructing our component size distribution chart, let's briefly understand adjacency lists - one popular way of representing graphs in programming languages like C++. An adjacency list represents connections between nodes by storing neighbor information for each vertex.

To create an adjacency list representation

  • Define a struct called Graph which contains properties such as 'value' and 'neighbors'.

  • Create an array (or vector) of Node structs; its index denotes the node label or identifier.

  • For each edge connecting two vertices A and B, add both A and B as neighbors under their corresponding positions in the array or vector.

Finding Connected Components

Now that we have our graph represented using an adjacency list structure, we can proceed with finding connected components for each node recursively through depth-first search (DFS).

  • Initialize all nodes as unvisited.

  • Traverse through every unvisited node.

    • When traversing from one node to another via DFS exploration, check if they are already visited.

    • If not visited yet, mark them as visited and continue DFS exploration on their neighbors until no more unvisited neighbors remain.

    • Increment your count variable when visiting newly discovered nodes during DFS traversal.

  • Store these counts of connected components for each individual starting node.

C++ code to construct a graph from size of components for each node

Algorithm

  • Step 1 − The required header files are included.

  • Step 2 − Create a class Graph with an ID and a vector of neighbors.

  • Step 3 − Create a function outputgraph() that takes in a vector of pairs components and an integer n.

  • Step 4 − Create an unordered map mp to store the components.

  • Step 5 − Loop through the components and add them to the map.

  • Step 6 − Check if the input is valid by checking if the number of nodes in each component is divisible by the size of the component.

  • Step 7 − In the given code there may be two possibilities for not running the code.

  • Step 8 − The first case is when the input itself is wrong and the other case is when the edges cannot be formed from the input pairs.

  • Step 9 − With the help of the input given for the component size and the pairs, the edges of the graph can be constructed.

Example

//Including the required header files
#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;

class Graph {
   public:
      // unique identifier for each node
      // stores neighbor IDs
      int id;
      vector<int> neighbors;
    
      Graph() { }
    
      void addNeighbor(int neighborID) {
         neighbors.push_back(neighborID);
      }
};
//Defining the function with three parameters
//The parameters are the input pairs, their address of it, and the size
void outputgraph(vector<pair<int, int>> &components, int n) {
   unordered_map<int, vector<int>> mp;
   for (int m = 0; m < n; m++)//O(n) {
      mp[components[m].second].push_back(components[m].first);
   }

   bool noEdgesExist = true;
   for (auto a : mp)//O(n) {
      int component_size, num_nodes;
      component_size = a.first;
      num_nodes = a.second.size();
      if (component_size != 1)
         noEdgesExist = false;
      if (num_nodes % component_size != 0) {
         cout << "Valid Graph cannot be constructed\n";
         return;
      }
   }
   //If the edges could not be constructed using the given pairs this statement gets executed
   if (noEdgesExist){
      cout << "Edges cannot be constructed for this possible graph\n";
      return;
   }

   vector<pair<int, int>> edges;

   for (auto a : mp){
      vector<int> nodes = a.second;
      int component_size = a.first;

      // divide the nodes into groups of size= component_size
      int numGroups = nodes.size() / component_size;
      for (int m = 0; m < numGroups; m++){
         int start = m * component_size;
         for (int y = start + 1; y < start + component_size; y++){
            edges.push_back({nodes[y], nodes[y - 1]});
         }
      }
   }
   //for loop will iterate through the pairs
   for (int m = 0; m < edges.size(); m++){
      cout << edges[m].first << ", "
         << edges[m].second;
      if (m != edges.size() - 1){
         cout << ", ";
      }
   }

}
//main function to test the implemented functions

int main() {
//component size is initialized as 2
   int n = 2;
   vector<pair<int, int>> components{{1,2}, {2,2}, {3,1}, {4,1}, {5,1}, {6,1}};
  
   outputgraph(components, n);

   return 0;
}

Output

2,1

Conclusion

The Code runs and gives the edges pair based on the input pair and the component size using the class method along with the Boolean functionalities. With the thorough description in this article and the implementation examples in C++ that were provided, we are now prepared to take on comparable problems involving constructing a graph.

Updated on: 25-Aug-2023

83 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements