openGPMP
Open Source Mathematics Package
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
gpmp::Graph Class Reference

#include <graphs.hpp>

Public Member Functions

 Graph (int v)
 Constructor for the Graph class. More...
 
void add_edge (int v, int w, int weight)
 Adds an edge between two vertices with a specified weight. More...
 
void dfs (int start)
 Performs Depth-First Search (DFS) traversal starting from a given vertex. More...
 
void dfs_rec (int v, std::vector< bool > &visited)
 Helper function for recursive Depth-First Search (DFS) traversal. More...
 
void bfs (int start)
 Performs Breadth-First Search (BFS) traversal starting from a given vertex. More...
 
void dijkstra (int start)
 Applies Dijkstra's algorithm to find the single-source shortest paths in the graph. More...
 
void bellman_ford (int start)
 Applies Bellman-Ford algorithm to find the single-source shortest paths in the graph, handling negative weights. More...
 
std::vector< std::pair< int, std::pair< int, int > > > kruskal ()
 Applies Kruskal's algorithm to find the minimum spanning tree of the graph. More...
 
void floyd_warshall ()
 Applies Floyd-Warshall algorithm to find all-pairs shortest paths in the graph. More...
 
void topo_sort ()
 Performs topological sorting on a Directed Acyclic Graph (DAG) More...
 
std::vector< std::vector< int > > connected_components ()
 Finds connected components in an undirected graph using Depth-First Search (DFS) More...
 
bool is_bipartite ()
 Determines if a given graph is bipartite using BFS (Breadth First Search) More...
 
std::vector< double > betweenness_centrality ()
 Calculates betweenness centrality for each vertex in the graph. More...
 
bool has_hamiltonian_circuit ()
 Checks if the graph contains a Hamiltonian circuit. More...
 
bool has_eulerian_path ()
 Checks if the graph contains an Eulerian path. More...
 
int eccentricity (int vertex)
 Calculates the eccentricity of a specified vertex in the graph. More...
 
int radius ()
 Calculates the radius of the graph. More...
 
std::vector< int > greedy_coloring ()
 Performs graph coloring using the greedy algorithm. More...
 
int chromatic_number ()
 Calculates the chromatic number of the graph. More...
 
std::vector< std::pair< int, int > > match_cardinality ()
 Finds a maximum cardinality matching in the graph using a greedy algorithm. More...
 
std::vector< std::pair< int, int > > match_wt ()
 Finds a maximum weight matching in the graph using a greedy algorithm. More...
 
bool is_planar ()
 Checks if the graph is planar using Kuratowski's theorem. More...
 
void planar_gen (int num_vertices, double radius)
 Generates a random planar graph using the random geometric graph model. More...
 
bool has_k5 ()
 Checks if the graph contains a subgraph that is a subdivision of K5. More...
 
bool has_k33 ()
 Checks if the graph contains a subgraph that is a subdivision of K3,3. More...
 
bool is_k33 (const std::set< int > &k_vertices)
 Checks if a set of vertices forms a subgraph that is a subdivision of K3,3. More...
 
double euclid_dist (const std::pair< double, double > &point1, const std::pair< double, double > &point2)
 Calculates the Euclidean distance between two 2D points. More...
 
std::vector< uint64_t > compress ()
 Compresses the graph using Elias Gamma encoding. More...
 
void decompress (const std::vector< uint64_t > &compressed)
 Decompresses a compressed graph using Elias Gamma encoding. More...
 

Public Attributes

int vertices
 
std::vector< std::vector< std::pair< int, int > > > adj_list
 

Private Member Functions

void topo_sort_util (int v, std::vector< bool > &visited, std::stack< int > &topo_stack)
 Helper function for topological sorting. More...
 
int find (std::vector< int > &parent, int i)
 Finds the representative element of the set that contains the given element. More...
 
void union_sets (std::vector< int > &parent, int x, int y)
 Unions two sets by rank in the disjoint set data structure. More...
 
void dfs_connected_components (int v, std::vector< bool > &visited, std::vector< int > &component)
 Performs Depth-First Search (DFS) traversal to find connected components in an undirected graph. More...
 
int choose_random_neighbor (int vertex)
 Chooses a random neighbor of a given vertex. More...
 
bool hamiltonian_circuit_util (int v, std::vector< bool > &visited, std::vector< int > &path, int count)
 Utility function for finding a Hamiltonian circuit. More...
 

Private Attributes

std::vector< bool > is_matched
 

Detailed Description

Definition at line 49 of file graphs.hpp.

Constructor & Destructor Documentation

◆ Graph()

gpmp::Graph::Graph ( int  v)
inline

Constructor for the Graph class.

Parameters
vNumber of vertices in the graph

Definition at line 58 of file graphs.hpp.

58  : vertices(v), adj_list(v) {
59  }
std::vector< std::vector< std::pair< int, int > > > adj_list
Definition: graphs.hpp:52
int vertices
Definition: graphs.hpp:51

Member Function Documentation

◆ add_edge()

void gpmp::Graph::add_edge ( int  v,
int  w,
int  weight 
)

Adds an edge between two vertices with a specified weight.

Parameters
vThe first vertex
wThe second vertex
weightThe weight of the edge

Definition at line 44 of file graphs.cpp.

44  {
45  adj_list[v].emplace_back(w, weight);
46  adj_list[w].emplace_back(v, weight); // uncomment for undirected graph
47 }

References adj_list.

Referenced by main().

◆ bellman_ford()

void gpmp::Graph::bellman_ford ( int  start)

Applies Bellman-Ford algorithm to find the single-source shortest paths in the graph, handling negative weights.

Parameters
startThe starting vertex for Bellman-Ford algorithm

Definition at line 116 of file graphs.cpp.

116  {
117  std::vector<int> dist(vertices, std::numeric_limits<int>::max());
118  dist[start] = 0;
119 
120  for (int i = 0; i < vertices - 1; ++i) {
121  for (int u = 0; u < vertices; ++u) {
122  for (const auto &neighbor : adj_list[u]) {
123  int v = neighbor.first;
124  int weight = neighbor.second;
125 
126  if (dist[u] != std::numeric_limits<int>::max() &&
127  dist[u] + weight < dist[v]) {
128  dist[v] = dist[u] + weight;
129  }
130  }
131  }
132  }
133 
134  std::cout << "Bellman-Ford Shortest Paths from vertex " << start << ":\n";
135  for (int i = 0; i < vertices; ++i)
136  std::cout << "Vertex " << i << ": " << dist[i] << "\n";
137 }
static GLfloat u

References u.

Referenced by main().

◆ betweenness_centrality()

std::vector< double > gpmp::Graph::betweenness_centrality ( )

Calculates betweenness centrality for each vertex in the graph.

Returns
Vector of doubles representing the betweenness centrality of each vertex

Definition at line 298 of file graphs.cpp.

298  {
299  std::vector<double> centrality(vertices, 0.0);
300 
301  for (int s = 0; s < vertices; ++s) {
302  std::vector<int> predecessors(vertices, -1);
303  std::vector<int> distance(vertices, -1);
304  std::vector<int> num_shortest_paths(vertices, 0);
305  std::stack<int> stack;
306  std::queue<int> bfs_queue;
307 
308  distance[s] = 0;
309  num_shortest_paths[s] = 1;
310  bfs_queue.push(s);
311 
312  while (!bfs_queue.empty()) {
313  int v = bfs_queue.front();
314  bfs_queue.pop();
315  stack.push(v);
316 
317  for (const auto &neighbor : adj_list[v]) {
318  int w = neighbor.first;
319  if (distance[w] == -1) {
320  distance[w] = distance[v] + 1;
321  bfs_queue.push(w);
322  }
323 
324  if (distance[w] == distance[v] + 1) {
325  num_shortest_paths[w] += num_shortest_paths[v];
326  predecessors[w] = v;
327  }
328  }
329  }
330 
331  std::vector<double> dependency(vertices, 0.0);
332 
333  while (!stack.empty()) {
334  int w = stack.top();
335  stack.pop();
336 
337  for (const auto &predecessor : adj_list[w]) {
338  int v = predecessor.first;
339  dependency[v] += (static_cast<double>(num_shortest_paths[v]) /
340  num_shortest_paths[w]) *
341  (1 + dependency[w]);
342  }
343 
344  if (w != s) {
345  centrality[w] += dependency[w];
346  }
347  }
348  }
349 
350  return centrality;
351 }

◆ bfs()

void gpmp::Graph::bfs ( int  start)

Performs Breadth-First Search (BFS) traversal starting from a given vertex.

Parameters
startThe starting vertex for BFS traversal

Definition at line 65 of file graphs.cpp.

65  {
66  std::vector<bool> visited(vertices, false);
67  std::queue<int> bfs_queue;
68 
69  visited[start] = true;
70  bfs_queue.push(start);
71 
72  while (!bfs_queue.empty()) {
73  int v = bfs_queue.front();
74  bfs_queue.pop();
75  std::cout << v << " ";
76 
77  for (const auto &neighbor : adj_list[v]) {
78  if (!visited[neighbor.first]) {
79  visited[neighbor.first] = true;
80  bfs_queue.push(neighbor.first);
81  }
82  }
83  }
84 }

Referenced by main().

◆ choose_random_neighbor()

int gpmp::Graph::choose_random_neighbor ( int  vertex)
private

Chooses a random neighbor of a given vertex.

Parameters
vertexThe vertex for which a random neighbor is chosen
Returns
The index of the randomly chosen neighbor in the adjacency list

◆ chromatic_number()

int gpmp::Graph::chromatic_number ( )

Calculates the chromatic number of the graph.

Returns
The chromatic number of the graph

Definition at line 467 of file graphs.cpp.

467  {
468  std::vector<int> result(vertices, -1);
469 
470  // assign the first color to the first vertex
471  result[0] = 0;
472 
473  // initialize available colors. For each vertex, remove colors used by its
474  // neighbors.
475  std::vector<bool> available(vertices, false);
476  for (const auto &neighbor : adj_list[0]) {
477  int v = neighbor.first;
478  if (result[v] != -1) {
479  available[result[v]] = true;
480  }
481  }
482 
483  // assign colors to the remaining vertices
484  for (int v = 1; v < vertices; ++v) {
485  for (int c = 0; c < vertices; ++c) {
486  if (!available[c]) {
487  result[v] = c;
488  break;
489  }
490  }
491 
492  // reset available colors for the next vertex
493  std::fill(available.begin(), available.end(), false);
494 
495  // update available colors for neighbors
496  for (const auto &neighbor : adj_list[v]) {
497  int u = neighbor.first;
498  if (result[u] != -1) {
499  available[result[u]] = true;
500  }
501  }
502  }
503 
504  // find the maximum color assigned, which represents the chromatic number
505  int chrom_num = *std::max_element(result.begin(), result.end()) + 1;
506 
507  return chrom_num;
508 }

References u.

◆ compress()

std::vector< uint64_t > gpmp::Graph::compress ( )

Compresses the graph using Elias Gamma encoding.

Returns
Vector of uint64_t representing the compressed graph

Definition at line 693 of file graphs.cpp.

693  {
694  std::vector<uint64_t> compressed;
695  compressed.push_back(vertices);
696 
697  for (int v = 0; v < vertices; ++v) {
698  // encode the number of neighbors using Elias Gamma encoding
699  std::bitset<64> binary_representation(adj_list[v].size() + 1);
700  int length = log2(adj_list[v].size() + 1) + 1;
701 
702  // store the length of the encoded number
703  compressed.push_back(length);
704 
705  // store the encoded number
706  compressed.push_back(
707  std::stoull(binary_representation.to_string(), 0, 2));
708 
709  // store the neighbors
710  for (const auto &neighbor : adj_list[v]) {
711  compressed.push_back(neighbor.first);
712  }
713  }
714 
715  return compressed;
716 }

◆ connected_components()

std::vector< std::vector< int > > gpmp::Graph::connected_components ( )

Finds connected components in an undirected graph using Depth-First Search (DFS)

Returns
Vector of vectors representing the connected components

Definition at line 254 of file graphs.cpp.

254  {
255  std::vector<std::vector<int>> components;
256  std::vector<bool> visited(vertices, false);
257 
258  for (int v = 0; v < vertices; ++v) {
259  if (!visited[v]) {
260  std::vector<int> component;
261  dfs_connected_components(v, visited, component);
262  components.push_back(component);
263  }
264  }
265 
266  return components;
267 }
void dfs_connected_components(int v, std::vector< bool > &visited, std::vector< int > &component)
Performs Depth-First Search (DFS) traversal to find connected components in an undirected graph.
Definition: graphs.cpp:353

◆ decompress()

void gpmp::Graph::decompress ( const std::vector< uint64_t > &  compressed)

Decompresses a compressed graph using Elias Gamma encoding.

Parameters
compressedVector of uint64_t representing the compressed graph

Definition at line 719 of file graphs.cpp.

719  {
720  int index = 0;
721  vertices = compressed[index++];
722 
723  adj_list.resize(vertices);
724 
725  for (int v = 0; v < vertices; ++v) {
726  int length = compressed[index++];
727  uint64_t encoded_neighbors = compressed[index++];
728  std::bitset<64> binary_representation(encoded_neighbors);
729 
730  // decode the number of neighbors
731  int num_neighbors =
732  std::stoi(binary_representation.to_string().substr(64 - length),
733  nullptr,
734  2) -
735  1;
736 
737  // decode and add neighbors
738  for (int i = 0; i < num_neighbors; ++i) {
739  adj_list[v].emplace_back(compressed[index++],
740  0); // TODO assuming unweighted graph
741  }
742  }
743 }

◆ dfs()

void gpmp::Graph::dfs ( int  start)

Performs Depth-First Search (DFS) traversal starting from a given vertex.

Parameters
startThe starting vertex for DFS traversal

Definition at line 49 of file graphs.cpp.

49  {
50  std::vector<bool> visited(vertices, false);
51  dfs_rec(start, visited);
52 }
void dfs_rec(int v, std::vector< bool > &visited)
Helper function for recursive Depth-First Search (DFS) traversal.
Definition: graphs.cpp:54

Referenced by main().

◆ dfs_connected_components()

void gpmp::Graph::dfs_connected_components ( int  v,
std::vector< bool > &  visited,
std::vector< int > &  component 
)
private

Performs Depth-First Search (DFS) traversal to find connected components in an undirected graph.

This method is a helper function used by the connected_components method

Parameters
vThe current vertex during DFS traversal
visitedA vector indicating whether each vertex has been visited
componentThe connected component being formed during the traversal

Definition at line 353 of file graphs.cpp.

355  {
356  visited[v] = true;
357  component.push_back(v);
358 
359  for (const auto &neighbor : adj_list[v]) {
360  int u = neighbor.first;
361  if (!visited[u]) {
362  dfs_connected_components(u, visited, component);
363  }
364  }
365 }

References u.

◆ dfs_rec()

void gpmp::Graph::dfs_rec ( int  v,
std::vector< bool > &  visited 
)

Helper function for recursive Depth-First Search (DFS) traversal.

Parameters
vThe current vertex
visitedA vector indicating whether each vertex has been visited

Definition at line 54 of file graphs.cpp.

54  {
55  visited[v] = true;
56  std::cout << v << " ";
57 
58  for (const auto &neighbor : adj_list[v]) {
59  if (!visited[neighbor.first]) {
60  dfs_rec(neighbor.first, visited);
61  }
62  }
63 }

◆ dijkstra()

void gpmp::Graph::dijkstra ( int  start)

Applies Dijkstra's algorithm to find the single-source shortest paths in the graph.

Parameters
startThe starting vertex for Dijkstra's algorithm

Definition at line 86 of file graphs.cpp.

86  {
87  std::priority_queue<std::pair<int, int>,
88  std::vector<std::pair<int, int>>,
89  std::greater<std::pair<int, int>>>
90  pq;
91  std::vector<int> dist(vertices, std::numeric_limits<int>::max());
92 
93  dist[start] = 0;
94  pq.push({0, start});
95 
96  while (!pq.empty()) {
97  int u = pq.top().second;
98  pq.pop();
99 
100  for (const auto &neighbor : adj_list[u]) {
101  int v = neighbor.first;
102  int weight = neighbor.second;
103 
104  if (dist[u] + weight < dist[v]) {
105  dist[v] = dist[u] + weight;
106  pq.push({dist[v], v});
107  }
108  }
109  }
110 
111  std::cout << "Dijkstra's Shortest Paths from vertex " << start << ":\n";
112  for (int i = 0; i < vertices; ++i)
113  std::cout << "Vertex " << i << ": " << dist[i] << "\n";
114 }

References u.

Referenced by main().

◆ eccentricity()

int gpmp::Graph::eccentricity ( int  vertex)

Calculates the eccentricity of a specified vertex in the graph.

Parameters
vertexThe vertex for which eccentricity is calculated
Returns
The eccentricity of the specified vertex

Definition at line 431 of file graphs.cpp.

431  {
432  std::vector<int> distance(vertices, std::numeric_limits<int>::max());
433  distance[vertex] = 0;
434 
435  std::queue<int> bfs_queue;
436  bfs_queue.push(vertex);
437 
438  while (!bfs_queue.empty()) {
439  int v = bfs_queue.front();
440  bfs_queue.pop();
441 
442  for (const auto &neighbor : adj_list[v]) {
443  int u = neighbor.first;
444  if (distance[u] == std::numeric_limits<int>::max()) {
445  distance[u] = distance[v] + 1;
446  bfs_queue.push(u);
447  }
448  }
449  }
450 
451  // the eccentricity is the maximum distance from the given vertex
452  return *std::max_element(distance.begin(), distance.end());
453 }

References u.

◆ euclid_dist()

double gpmp::Graph::euclid_dist ( const std::pair< double, double > &  point1,
const std::pair< double, double > &  point2 
)

Calculates the Euclidean distance between two 2D points.

Parameters
point1The first 2D point
point2The second 2D point
Returns
The Euclidean distance between the two points

Definition at line 686 of file graphs.cpp.

687  {
688  double dx = point1.first - point2.first;
689  double dy = point1.second - point2.second;
690  return std::sqrt(dx * dx + dy * dy);
691 }

◆ find()

int gpmp::Graph::find ( std::vector< int > &  parent,
int  i 
)
private

Finds the representative element of the set that contains the given element.

Parameters
parentThe parent vector representing disjoint sets
iThe element to find
Returns
The representative element of the set containing 'i'

Definition at line 242 of file graphs.cpp.

242  {
243  if (parent[i] == -1)
244  return i;
245  return find(parent, parent[i]);
246 }
int find(std::vector< int > &parent, int i)
Finds the representative element of the set that contains the given element.
Definition: graphs.cpp:242

◆ floyd_warshall()

void gpmp::Graph::floyd_warshall ( )

Applies Floyd-Warshall algorithm to find all-pairs shortest paths in the graph.

Definition at line 170 of file graphs.cpp.

170  {
171  std::vector<std::vector<int>> dist(
172  vertices,
173  std::vector<int>(vertices, std::numeric_limits<int>::max()));
174 
175  for (int i = 0; i < vertices; ++i) {
176  dist[i][i] = 0;
177  for (const auto &neighbor : adj_list[i]) {
178  int v = neighbor.first;
179  int weight = neighbor.second;
180  dist[i][v] = weight;
181  }
182  }
183 
184  for (int k = 0; k < vertices; ++k) {
185  for (int i = 0; i < vertices; ++i) {
186  for (int j = 0; j < vertices; ++j) {
187  if (dist[i][k] != std::numeric_limits<int>::max() &&
188  dist[k][j] != std::numeric_limits<int>::max() &&
189  dist[i][k] + dist[k][j] < dist[i][j]) {
190  dist[i][j] = dist[i][k] + dist[k][j];
191  }
192  }
193  }
194  }
195 
196  std::cout << "Floyd-Warshall Shortest Paths:\n";
197  for (int i = 0; i < vertices; ++i) {
198  for (int j = 0; j < vertices; ++j) {
199  std::cout << "From " << i << " to " << j << ": ";
200  if (dist[i][j] == std::numeric_limits<int>::max())
201  std::cout << "INF";
202  else
203  std::cout << dist[i][j];
204  std::cout << "\n";
205  }
206  }
207 }

Referenced by main().

◆ greedy_coloring()

std::vector< int > gpmp::Graph::greedy_coloring ( )

Performs graph coloring using the greedy algorithm.

Returns
Vector of integers representing the color assigned to each vertex

Definition at line 511 of file graphs.cpp.

511  {
512  std::vector<int> result(vertices, -1);
513 
514  // assign colors to vertices
515  for (int v = 0; v < vertices; ++v) {
516  std::vector<bool> available(vertices, false);
517  for (const auto &neighbor : adj_list[v]) {
518  int u = neighbor.first;
519  if (result[u] != -1) {
520  available[result[u]] = true;
521  }
522  }
523 
524  for (int c = 0; c < vertices; ++c) {
525  if (!available[c]) {
526  result[v] = c;
527  break;
528  }
529  }
530  }
531 
532  return result;
533 }

References u.

◆ hamiltonian_circuit_util()

bool gpmp::Graph::hamiltonian_circuit_util ( int  v,
std::vector< bool > &  visited,
std::vector< int > &  path,
int  count 
)
private

Utility function for finding a Hamiltonian circuit.

Parameters
vThe current vertex in the exploration
visitedVector indicating whether each vertex has been visited
pathVector representing the current path in the exploration
countThe count of vertices visited so far
Returns
True if a Hamiltonian circuit is found, false otherwise

Definition at line 395 of file graphs.cpp.

398  {
399  visited[v] = true;
400  path.push_back(v);
401 
402  if (count == vertices) {
403  // all vertices are visited; check if there is an edge from the last
404  // added vertex to the starting vertex
405  for (const auto &neighbor : adj_list[v]) {
406  if (neighbor.first == path[0]) {
407  return true; // Hamiltonian circuit found
408  }
409  }
410  } else {
411  // recursive step to try all vertices as the next one in the Hamiltonian
412  // circuit
413  for (const auto &neighbor : adj_list[v]) {
414  if (!visited[neighbor.first]) {
415  if (hamiltonian_circuit_util(neighbor.first,
416  visited,
417  path,
418  count + 1)) {
419  return true;
420  }
421  }
422  }
423  }
424 
425  // backtrack
426  visited[v] = false;
427  path.pop_back();
428  return false;
429 }
bool hamiltonian_circuit_util(int v, std::vector< bool > &visited, std::vector< int > &path, int count)
Utility function for finding a Hamiltonian circuit.
Definition: graphs.cpp:395

◆ has_eulerian_path()

bool gpmp::Graph::has_eulerian_path ( )

Checks if the graph contains an Eulerian path.

Returns
True if the graph contains an Eulerian path, false otherwise

Definition at line 381 of file graphs.cpp.

381  {
382  // A connected graph has an Eulerian path if and only if it has exactly 0 or
383  // 2 vertices with an odd degree.
384  int odd_degrees = 0;
385 
386  for (int v = 0; v < vertices; ++v) {
387  if (adj_list[v].size() % 2 != 0) {
388  ++odd_degrees;
389  }
390  }
391 
392  return odd_degrees == 0 || odd_degrees == 2;
393 }

◆ has_hamiltonian_circuit()

bool gpmp::Graph::has_hamiltonian_circuit ( )

Checks if the graph contains a Hamiltonian circuit.

Returns
True if the graph contains a Hamiltonian circuit, false otherwise

Definition at line 367 of file graphs.cpp.

367  {
368  std::vector<int> path;
369  std::vector<bool> visited(vertices, false);
370 
371  for (int v = 0; v < vertices; ++v) {
372  path.clear();
373  if (hamiltonian_circuit_util(v, visited, path, 1)) {
374  return true;
375  }
376  }
377 
378  return false;
379 }

◆ has_k33()

bool gpmp::Graph::has_k33 ( )

Checks if the graph contains a subgraph that is a subdivision of K3,3.

Returns
True if the graph contains a subgraph that is a subdivision of K3,3, false otherwise

Definition at line 654 of file graphs.cpp.

654  {
655  for (int v = 0; v < vertices; ++v) {
656  if (adj_list[v].size() >= 3) {
657  std::set<int> neighbors;
658  for (const auto &neighbor : adj_list[v]) {
659  neighbors.insert(neighbor.first);
660  }
661 
662  if (is_k33(neighbors)) {
663  return true;
664  }
665  }
666  }
667 
668  return false;
669 }
bool is_k33(const std::set< int > &k_vertices)
Checks if a set of vertices forms a subgraph that is a subdivision of K3,3.
Definition: graphs.cpp:672

◆ has_k5()

bool gpmp::Graph::has_k5 ( )

Checks if the graph contains a subgraph that is a subdivision of K5.

Returns
True if the graph contains a subgraph that is a subdivision of K5, false otherwise

Definition at line 624 of file graphs.cpp.

624  {
625  for (int v = 0; v < vertices; ++v) {
626  if (adj_list[v].size() >= 5) {
627  std::set<int> neighbors;
628  for (const auto &neighbor : adj_list[v]) {
629  neighbors.insert(neighbor.first);
630  }
631 
632  for (const auto &u : neighbors) {
633  std::set<int> common_neighbors;
634  for (const auto &neighbor : adj_list[u]) {
635  if (neighbors.find(neighbor.first) != neighbors.end()) {
636  common_neighbors.insert(neighbor.first);
637  }
638  }
639 
640  for (const auto &w : common_neighbors) {
641  if (neighbors.find(w) != neighbors.end()) {
642  return true;
643  }
644  }
645  }
646  }
647  }
648 
649  return false;
650 }

References u.

◆ is_bipartite()

bool gpmp::Graph::is_bipartite ( )

Determines if a given graph is bipartite using BFS (Breadth First Search)

Note
A bipartite graph is a graph where the vertices can be divided into two disjoint sets such that all edges connect a vertex in one set to a vertex in another set

Definition at line 269 of file graphs.cpp.

269  {
270  std::vector<int> color(vertices, -1);
271  std::queue<int> bfs_queue;
272 
273  for (int start = 0; start < vertices; ++start) {
274  if (color[start] == -1) {
275  color[start] = 0;
276  bfs_queue.push(start);
277 
278  while (!bfs_queue.empty()) {
279  int v = bfs_queue.front();
280  bfs_queue.pop();
281 
282  for (const auto &neighbor : adj_list[v]) {
283  int u = neighbor.first;
284  if (color[u] == -1) {
285  color[u] = 1 - color[v];
286  bfs_queue.push(u);
287  } else if (color[u] == color[v]) {
288  return false; // Not bipartite
289  }
290  }
291  }
292  }
293  }
294 
295  return true; // Bipartite
296 }

References u.

◆ is_k33()

bool gpmp::Graph::is_k33 ( const std::set< int > &  k_vertices)

Checks if a set of vertices forms a subgraph that is a subdivision of K3,3.

Parameters
verticesThe set of vertices to be checked
Returns
True if the set of vertices forms a subgraph that is a subdivision of K3,3, false otherwise

Definition at line 672 of file graphs.cpp.

672  {
673  if (k_vertices.size() == 6) {
674  int degree_sum = 0;
675  for (int v : k_vertices) {
676  degree_sum += adj_list[v].size();
677  }
678 
679  // Cast vertices.size() to int to avoid the comparison warning
680  return degree_sum == 2 * static_cast<int>(k_vertices.size());
681  }
682  return false;
683 }

◆ is_planar()

bool gpmp::Graph::is_planar ( )

Checks if the graph is planar using Kuratowski's theorem.

Returns
True if the graph is planar, false otherwise

Definition at line 589 of file graphs.cpp.

589  {
590  // planar graphs satisfy Kuratowski's theorem: they do not contain a
591  // subgraph that is a subdivision of K5 or K3,3.
592  return !has_k5() && !has_k33();
593 }
bool has_k5()
Checks if the graph contains a subgraph that is a subdivision of K5.
Definition: graphs.cpp:624
bool has_k33()
Checks if the graph contains a subgraph that is a subdivision of K3,3.
Definition: graphs.cpp:654

◆ kruskal()

std::vector< std::pair< int, std::pair< int, int > > > gpmp::Graph::kruskal ( )

Applies Kruskal's algorithm to find the minimum spanning tree of the graph.

Returns
Vector of edges forming the minimum spanning tree

Definition at line 139 of file graphs.cpp.

139  {
140  std::vector<std::pair<int, std::pair<int, int>>> edges;
141  for (int u = 0; u < vertices; ++u) {
142  for (const auto &neighbor : adj_list[u]) {
143  int v = neighbor.first;
144  int weight = neighbor.second;
145  edges.emplace_back(weight, std::make_pair(u, v));
146  }
147  }
148 
149  std::sort(edges.begin(), edges.end());
150 
151  std::vector<std::pair<int, std::pair<int, int>>> min_span_tree;
152  std::vector<int> parent(vertices, -1);
153 
154  for (const auto &edge : edges) {
155  int u = edge.second.first;
156  int v = edge.second.second;
157 
158  int setU = find(parent, u);
159  int setV = find(parent, v);
160 
161  if (setU != setV) {
162  min_span_tree.push_back(edge);
163  union_sets(parent, setU, setV);
164  }
165  }
166 
167  return min_span_tree;
168 }
void union_sets(std::vector< int > &parent, int x, int y)
Unions two sets by rank in the disjoint set data structure.
Definition: graphs.cpp:248

References u.

Referenced by main().

◆ match_cardinality()

std::vector< std::pair< int, int > > gpmp::Graph::match_cardinality ( )

Finds a maximum cardinality matching in the graph using a greedy algorithm.

Returns
Vector of pairs representing the edges in the maximum cardinality matching

Definition at line 535 of file graphs.cpp.

535  {
536  std::vector<std::pair<int, int>> matching;
537 
538  // iterate through each vertex and find unmatched neighbors
539  for (int v = 0; v < vertices; ++v) {
540  if (!is_matched[v]) {
541  for (const auto &neighbor : adj_list[v]) {
542  int u = neighbor.first;
543  if (!is_matched[u]) {
544  matching.push_back({v, u});
545  is_matched[v] = true;
546  is_matched[u] = true;
547  break;
548  }
549  }
550  }
551  }
552 
553  return matching;
554 }
std::vector< bool > is_matched
Definition: graphs.hpp:259

References u.

◆ match_wt()

std::vector< std::pair< int, int > > gpmp::Graph::match_wt ( )

Finds a maximum weight matching in the graph using a greedy algorithm.

Returns
Vector of pairs representing the edges in the maximum weight matching

Definition at line 557 of file graphs.cpp.

557  {
558  std::vector<std::pair<int, int>> matching;
559 
560  // sort edges in descending order based on weights
561  std::vector<std::pair<std::pair<int, int>, int>> wt_edges;
562  for (int v = 0; v < vertices; ++v) {
563  for (const auto &neighbor : adj_list[v]) {
564  int u = neighbor.first;
565  int weight = neighbor.second;
566  wt_edges.push_back({{v, u}, weight});
567  }
568  }
569 
570  std::sort(wt_edges.rbegin(),
571  wt_edges.rend(),
572  [](const auto &a, const auto &b) { return a.second < b.second; });
573 
574  // iterate through sorted edges and add to matching if both vertices are
575  // unmatched
576  for (const auto &edge : wt_edges) {
577  int v = edge.first.first;
578  int u = edge.first.second;
579  if (!is_matched[v] && !is_matched[u]) {
580  matching.push_back({v, u});
581  is_matched[v] = true;
582  is_matched[u] = true;
583  }
584  }
585 
586  return matching;
587 }

References u.

◆ planar_gen()

void gpmp::Graph::planar_gen ( int  num_vertices,
double  radius 
)

Generates a random planar graph using the random geometric graph model.

Parameters
num_verticesThe number of vertices in the generated graph
radiusThe radius parameter for the random geometric graph model

Definition at line 597 of file graphs.cpp.

597  {
598  vertices = num_vertices;
599  adj_list.resize(vertices);
600 
601  // generate random points in a 2D plane
602  std::vector<std::pair<double, double>> points;
603  for (int v = 0; v < vertices; ++v) {
604  double x = static_cast<double>(rand()) / RAND_MAX;
605  double y = static_cast<double>(rand()) / RAND_MAX;
606  points.push_back({x, y});
607  }
608 
609  // connect vertices if their Euclidean distance is less than the specified
610  // radius
611  for (int v = 0; v < vertices; ++v) {
612  for (int u = v + 1; u < vertices; ++u) {
613  double distance = euclid_dist(points[v], points[u]);
614  if (distance < radius) {
615  // TODO the weight of the generated edges should probably be
616  // determined algorithmically
617  add_edge(v, u, 0);
618  }
619  }
620  }
621 }
int radius()
Calculates the radius of the graph.
Definition: graphs.cpp:456
void add_edge(int v, int w, int weight)
Adds an edge between two vertices with a specified weight.
Definition: graphs.cpp:44
double euclid_dist(const std::pair< double, double > &point1, const std::pair< double, double > &point2)
Calculates the Euclidean distance between two 2D points.
Definition: graphs.cpp:686

References u.

◆ radius()

int gpmp::Graph::radius ( )

Calculates the radius of the graph.

Returns
The radius of the graph

Definition at line 456 of file graphs.cpp.

456  {
457  int min_ecntrc = std::numeric_limits<int>::max();
458 
459  for (int v = 0; v < vertices; ++v) {
460  int vEccentricity = eccentricity(v);
461  min_ecntrc = std::min(min_ecntrc, vEccentricity);
462  }
463 
464  return min_ecntrc;
465 }
int eccentricity(int vertex)
Calculates the eccentricity of a specified vertex in the graph.
Definition: graphs.cpp:431

◆ topo_sort()

void gpmp::Graph::topo_sort ( )

Performs topological sorting on a Directed Acyclic Graph (DAG)

Definition at line 209 of file graphs.cpp.

209  {
210  std::stack<int> topo_stack;
211  std::vector<bool> visited(vertices, false);
212 
213  for (int i = 0; i < vertices; ++i) {
214  if (!visited[i]) {
215  topo_sort_util(i, visited, topo_stack);
216  }
217  }
218 
219  std::cout << "Topological Sorting: ";
220  while (!topo_stack.empty()) {
221  std::cout << topo_stack.top() << " ";
222  topo_stack.pop();
223  }
224  std::cout << std::endl;
225 }
void topo_sort_util(int v, std::vector< bool > &visited, std::stack< int > &topo_stack)
Helper function for topological sorting.
Definition: graphs.cpp:227

Referenced by main().

◆ topo_sort_util()

void gpmp::Graph::topo_sort_util ( int  v,
std::vector< bool > &  visited,
std::stack< int > &  topo_stack 
)
private

Helper function for topological sorting.

Parameters
vThe current vertex
visitedA vector indicating whether each vertex has been visited
topo_stackThe stack used for topological sorting

Definition at line 227 of file graphs.cpp.

229  {
230  visited[v] = true;
231 
232  for (const auto &neighbor : adj_list[v]) {
233  int u = neighbor.first;
234  if (!visited[u]) {
235  topo_sort_util(u, visited, topo_stack);
236  }
237  }
238 
239  topo_stack.push(v);
240 }

References u.

◆ union_sets()

void gpmp::Graph::union_sets ( std::vector< int > &  parent,
int  x,
int  y 
)
private

Unions two sets by rank in the disjoint set data structure.

Parameters
parentThe parent vector representing disjoint sets
xThe representative element of the first set
yThe representative element of the second set

Definition at line 248 of file graphs.cpp.

248  {
249  int setX = find(parent, x);
250  int setY = find(parent, y);
251  parent[setX] = setY;
252 }

Member Data Documentation

◆ adj_list

std::vector<std::vector<std::pair<int, int> > > gpmp::Graph::adj_list

Definition at line 52 of file graphs.hpp.

Referenced by add_edge().

◆ is_matched

std::vector<bool> gpmp::Graph::is_matched
private

Definition at line 259 of file graphs.hpp.

◆ vertices

int gpmp::Graph::vertices

Definition at line 51 of file graphs.hpp.


The documentation for this class was generated from the following files: