52 throw invalid_argument(
53 "Cannot explore a branch of the graph when the "
54 "exploration is started from a vertex that does not exist within the "
58 throw invalid_argument(
59 "Edge does not exist in the graph so exploration of"
60 " the graph branch cannot continue");
62 if (!edge.
contains(starting_vertex)) {
63 throw invalid_argument(
64 "The edge determining which branch to explore does "
65 "not contain the starting vertex.");
68 set<Edge> branch_edges;
70 branch_edges.insert(edge);
75 pair<Index, GraphNode> pr_gn(starting_vertex, gn);
80 branch_edges.insert(edge);
81 while (!gv_breadth_first.
queEmpty()) {
83 branch_edges.insert(ed);
84 gv_breadth_first.
exec(g, ed);
88 for (
Edge& ed : neigh_edges) {
89 Index neigh_vertex = ed.getOtherEndPoint(starting_vertex);
90 if (neigh_vertex != starting_vertex) {
92 branch_edges.insert(ed);
113 class ExplorationRecord {
115 unordered_map<Index, std::pair<bool, Index>> vertex_explored_;
116 size_t unexplored_vertex_count_;
119 explicit ExplorationRecord(
120 const unordered_map<
Index, std::pair<bool, Index>>& vertex_explored)
121 : vertex_explored_(vertex_explored),
122 unexplored_vertex_count_(vertex_explored.size()) {};
124 void explore(
Index vertex) {
125 vertex_explored_[vertex].first =
true;
126 --unexplored_vertex_count_;
129 bool unexploredVerticesExist() {
return unexplored_vertex_count_ > 0; }
131 Index getUnexploredVertex() {
133 vector<Index> remaining_unexplored;
134 for (
const pair<
const Index, pair<bool, Index>>& vertex_record :
136 bool vertex_explored = vertex_record.second.first;
137 if (!vertex_explored) {
138 Index degree = vertex_record.second.second;
140 return vertex_record.first;
142 remaining_unexplored.push_back(vertex_record.first);
147 for (
const Index& vertex : remaining_unexplored) {
148 if (vertex_explored_[vertex].second == 1) {
155 for (
const Index& vertex : remaining_unexplored) {
156 if (!vertex_explored_[vertex].first) {
162 "You cannot get an unexplored vertex as they have all"
167 unordered_map<Index, pair<bool, Index>> unexplored_vertices;
169 for (
const Index& vertex : vertices) {
170 unexplored_vertices[vertex] =
171 pair<bool, Index>(
false, graph.
getDegree(vertex));
174 ExplorationRecord exploration_record(unexplored_vertices);
176 vector<vector<Index>> chains;
178 while (exploration_record.unexploredVerticesExist()) {
180 Index starting_vertex = exploration_record.getUnexploredVertex();
181 exploration_record.explore(starting_vertex);
185 vector<Index> chain{starting_vertex};
186 Index old_vertex = starting_vertex;
187 bool new_chain =
false;
193 if (unexplored_vertex.size() == 0) {
195 chain.push_back(old_vertex);
199 chain.push_back(old_vertex);
204 if (unexplored_vertex.size() == 0) {
205 chain.push_back(new_vertex);
206 chains.push_back(chain);
209 }
else if (graph.
getDegree(new_vertex) == 1) {
210 chain.push_back(new_vertex);
211 chains.push_back(chain);
213 exploration_record.explore(new_vertex);
215 }
else if (graph.
getDegree(new_vertex) > 2) {
216 chain.push_back(new_vertex);
217 chains.push_back(chain);
219 exploration_record.explore(new_vertex);
221 }
else if (unexplored_vertex.size() == 1) {
222 chain.push_back(new_vertex);
223 old_vertex = new_vertex;
224 exploration_record.explore(new_vertex);
227 graph_visitor.
exec(graph, edge);
230 vector<ReducedEdge> reduced_edges;
231 for (vector<Index> chain : chains) {
233 reduced_edges.push_back(reduced_edge);
237 auto nodes_graph = graph.
getNodes();
240 auto nodes_reduced_g = reduced_g.
getNodes();
246 const std::vector<Index>& vertices = graph.
getVertices();
248 std::vector<bool> vertex_analysed = std::vector<bool>(vertices.size(),
false);
250 std::vector<Graph> subGraphs;
252 while (i <
Index(vertices.size())) {
253 if (vertex_analysed[i]) {
260 set<Index> sub_graph_explored_vertices =
263 for (
Index vertex : sub_graph_explored_vertices) {
264 for (
Index j = 0; j <
Index(vertices.size()); j++) {
265 if (vertex_analysed[j]) {
268 if (vertex == vertices[j]) {
269 vertex_analysed[j] =
true;
275 set<Edge> sub_graph_edges;
276 unordered_map<Index, GraphNode> sub_graph_nodes;
277 for (
Index vertex : sub_graph_explored_vertices) {
280 sub_graph_edges.insert(sub_graph_edge);
282 sub_graph_nodes[vertex] = graph.
getNode(vertex);
285 Graph(std::vector<Edge>(sub_graph_edges.begin(), sub_graph_edges.end()),
294 string err =
"Cannot explore graph starting at vertex " +
296 " because it does not exist in the "
297 "graph. You can change the starting vertex by using the "
298 "setStartingVertex method of the visitor instance.";
299 throw invalid_argument(err);
306 graph_visitor.
exec(graph, edge);
base class for all analysis tools