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 std::unordered_set<IndexType> edgeListType;
18 // points must be unique and addressable
19 typedef std::unordered_map<IndexType, edgeListType> adjacencyListType;
20
21 adjacencyListType adjacencyList;
22 std::vector<IndexType> componentIds;
23
24 void depthFirstComponentSearch(const std::size_t &currentVertex,
25 int &currentComponent) {
26 // set component for this vertex
27 componentIds[currentVertex] = currentComponent;
28
29 // cycle through all connected vertices and set their component
30 auto vertexListIt = adjacencyList.find(currentVertex);
31 if (vertexListIt == adjacencyList.end()) {
32 Logger::getInstance().addError(
33 "Graph: Vertex " + std::to_string(currentVertex) +
34 " could not be found although it should exist!");
35 }
36
37 for (unsigned long it : vertexListIt->second) {
38 // vertex has not been visited
39 if (componentIds[it] == -1) {
40 depthFirstComponentSearch(it, currentComponent);
41 }
42 }
43 }
44
45public:
47 std::size_t insertNextVertex() {
48 adjacencyList.insert(std::make_pair(adjacencyList.size(), edgeListType()));
49 // return new key
50 return adjacencyList.size() - 1;
51 }
52
54 void insertNextEdge(std::size_t vertex1, std::size_t vertex2) {
55 // try to insert element into vertex list
56 // if it already exists, add vertex2 to vertex1 edges
57 auto it =
58 adjacencyList.insert(std::make_pair(vertex1, edgeListType())).first;
59 it->second.insert(vertex2);
60
61 // do the same for vertex2
62 it = adjacencyList.insert(std::make_pair(vertex2, edgeListType())).first;
63 it->second.insert(vertex1);
64 }
65
66 // returns a std::vector, where the value at each
67 // index denotes the component, the vertex belongs to
68 std::vector<IndexType> getConnectedComponents() {
69 // traverse all vertices and stop at unvisited ones
70 // to build connectivity.
71 componentIds.resize(adjacencyList.size(), -1);
72 int currentComponent = 0;
73 std::size_t currentVertex = 0;
74
75 for (auto it = adjacencyList.begin(); it != adjacencyList.end(); ++it) {
76 // this vertex has not been visited, so it
77 // must be part of a new component
78 if (componentIds[currentVertex] == -1) {
79 depthFirstComponentSearch(currentVertex, currentComponent);
80
81 ++currentComponent;
82 }
83 ++currentVertex;
84 }
85
86 return componentIds;
87 }
88
89 void print() {
90 std::cout << "Graph structure: " << std::endl;
91 for (auto &[fst, snd] : adjacencyList) {
92 auto &edges = snd;
93 std::cout << "Vertex: " << fst << std::endl;
94 for (const unsigned long edge : edges) {
95 std::cout << edge << ", ";
96 }
97 std::cout << std::endl;
98 }
99 }
100};
101} // namespace lsInternal
Definition lsGraph.hpp:13
std::size_t insertNextVertex()
add new vertex
Definition lsGraph.hpp:47
std::vector< IndexType > getConnectedComponents()
Definition lsGraph.hpp:68
void insertNextEdge(std::size_t vertex1, std::size_t vertex2)
add connection of vertex1 to vertex2
Definition lsGraph.hpp:54
void print()
Definition lsGraph.hpp:89
Definition lsCurvatureFormulas.hpp:9