ViennaLS
Loading...
Searching...
No Matches
lsGraph.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <unordered_map>
4#include <unordered_set>
5#include <vector>
6
7#include <vcLogger.hpp>
8
9namespace lsInternal {
10
11using namespace viennacore;
12
13class Graph {
14 // type for indexing components
15 using IndexType = std::size_t;
16 // edges must be unique
17 typedef typename std::unordered_set<IndexType> edgeListType;
18 // points must be unique and adressable
19 typedef typename std::unordered_map<IndexType, edgeListType>
20 adjacencyListType;
21
22 adjacencyListType adjacencyList;
23 std::vector<IndexType> componentIds;
24
25 void depthFirstComponentSearch(const std::size_t &currentVertex,
26 int &currentComponent) {
27 // set component for this vertex
28 componentIds[currentVertex] = currentComponent;
29
30 // cylce through all connected vertices and set their component
31 auto vertexListIt = adjacencyList.find(currentVertex);
32 if (vertexListIt == adjacencyList.end()) {
33 Logger::getInstance().addError(
34 "Graph: Vertex " + std::to_string(currentVertex) +
35 " could not be found although it should exist!");
36 }
37
38 for (auto it = vertexListIt->second.begin();
39 it != vertexListIt->second.end(); ++it) {
40 // vertex has not been visited
41 if (componentIds[*it] == -1) {
42 depthFirstComponentSearch(*it, currentComponent);
43 }
44 }
45 }
46
47public:
49 std::size_t insertNextVertex() {
50 adjacencyList.insert(std::make_pair(adjacencyList.size(), edgeListType()));
51 // return new key
52 return adjacencyList.size() - 1;
53 }
54
56 void insertNextEdge(std::size_t vertex1, std::size_t vertex2) {
57 // try to insert element into vertex list
58 // if it already exists, add vertex2 to vertex1 edges
59 auto it =
60 adjacencyList.insert(std::make_pair(vertex1, edgeListType())).first;
61 it->second.insert(vertex2);
62
63 // do the same for vertex2
64 it = adjacencyList.insert(std::make_pair(vertex2, edgeListType())).first;
65 it->second.insert(vertex1);
66 }
67
68 // returns an std::vector, where the value at each
69 // index denotes the component, the vertex belongs to
70 std::vector<IndexType> getConnectedComponents() {
71 // traverse all vertices and stop at unvisited ones
72 // to build connectivity.
73 componentIds.resize(adjacencyList.size(), -1);
74 int currentComponent = 0;
75 std::size_t currentVertex = 0;
76
77 for (auto it = adjacencyList.begin(); it != adjacencyList.end(); ++it) {
78 // this vertex has not been visited, so it
79 // must be part of a new component
80 if (componentIds[currentVertex] == -1) {
81 depthFirstComponentSearch(currentVertex, currentComponent);
82
83 ++currentComponent;
84 }
85 ++currentVertex;
86 }
87
88 return componentIds;
89 }
90
91 void print() {
92 std::cout << "Graph structure: " << std::endl;
93 for (auto it = adjacencyList.begin(); it != adjacencyList.end(); ++it) {
94 auto &edges = (*it).second;
95 std::cout << "Vertex: " << (*it).first << std::endl;
96 for (auto edgeIt = edges.begin(); edgeIt != edges.end(); ++edgeIt) {
97 std::cout << *edgeIt << ", ";
98 }
99 std::cout << std::endl;
100 }
101 }
102};
103} // namespace lsInternal
Definition lsGraph.hpp:13
std::size_t insertNextVertex()
add new vertex
Definition lsGraph.hpp:49
std::vector< IndexType > getConnectedComponents()
Definition lsGraph.hpp:70
void insertNextEdge(std::size_t vertex1, std::size_t vertex2)
add connection of vertex1 to vertex2
Definition lsGraph.hpp:56
void print()
Definition lsGraph.hpp:91
Definition lsAdvect.hpp:37