13 VuoDirectedAcyclicGraph::Vertex::~Vertex(
void)
22 cycleVerticesCacheReady =
false;
30 for (map<
Vertex *, vector<Vertex *> >::iterator i = edges.begin(); i != edges.end(); ++i)
49 for (map<
Vertex *, vector<Vertex *> >::iterator i = edges.begin(); i != edges.end(); ++i)
51 for (vector<Vertex *>::iterator j = i->second.begin(); j != i->second.end(); )
54 j = i->second.erase(j);
60 for (map<
Vertex *, vector<Vertex *> >::iterator i = edges.begin(); i != edges.end(); )
62 if (i->first == vertex)
70 downstreamVerticesCache.clear();
71 upstreamVerticesCache.clear();
72 cycleVerticesCacheReady =
false;
73 longestDownstreamPathsCache.clear();
81 for (map<
Vertex *, vector<Vertex *> >::iterator i = edges.begin(); i != edges.end(); ++i)
82 if (i->first->key() == key)
96 if (find(edges[fromVertex].begin(), edges[fromVertex].end(), toVertex) == edges[fromVertex].end())
98 edges[fromVertex].push_back(toVertex);
102 downstreamVerticesCache.clear();
103 upstreamVerticesCache.clear();
104 cycleVerticesCacheReady =
false;
105 longestDownstreamPathsCache.clear();
116 map< Vertex *, vector<Vertex *> >::iterator iter = downstreamVerticesCache.find(vertex);
117 if (iter != downstreamVerticesCache.end())
120 set<Vertex *> unused;
121 vector<Vertex *> downstreamVertices = getReachableVertices(vertex, edges, unused);
123 downstreamVerticesCache[vertex] = downstreamVertices;
125 return downstreamVertices;
136 map< Vertex *, vector<Vertex *> >::iterator iter = upstreamVerticesCache.find(vertex);
137 if (iter != upstreamVerticesCache.end())
140 map< Vertex *, vector<Vertex *> > backEdges;
141 for (map<
Vertex *, vector<Vertex *> >::iterator i = edges.begin(); i != edges.end(); ++i)
143 for (vector<Vertex *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
144 if (find(backEdges[*j].begin(), backEdges[*j].end(), i->first) == backEdges[*j].end())
145 backEdges[*j].push_back(i->first);
150 set<Vertex *> unused;
151 vector<Vertex *> upstreamVertices = getReachableVertices(vertex, backEdges, unused);
153 upstreamVerticesCache[vertex] = upstreamVertices;
155 return upstreamVertices;
163 if (cycleVerticesCacheReady)
164 return cycleVerticesCache;
166 set<Vertex *> cycleVertices;
167 for (map<
Vertex *, vector<Vertex *> >::iterator i = edges.begin(); i != edges.end(); ++i)
170 getReachableVertices(i->first, edges, c);
171 cycleVertices.insert(c.begin(), c.end());
174 cycleVerticesCacheReady =
true;
175 cycleVerticesCache = cycleVertices;
177 return cycleVertices;
185 auto iter = longestDownstreamPathsCache.find(vertex);
186 if (iter != longestDownstreamPathsCache.end())
193 longest = std::max(longest, curr);
202 vector<VuoDirectedAcyclicGraph::Vertex *> VuoDirectedAcyclicGraph::getReachableVertices(Vertex *vertex,
203 const map< Vertex *, vector<Vertex *> > &edges,
204 set<Vertex *> &cycleVertices)
206 map<Vertex *, vector<Vertex *> > reachableVertices;
208 if (edges.find(vertex) == edges.end())
209 return vector<Vertex *>();
211 list<Vertex *> toVisit;
212 toVisit.push_back(vertex);
214 while (! toVisit.empty())
217 Vertex *currVertex = toVisit.back();
219 set<Vertex *> nextVertices;
220 bool areCurrVerticesComplete =
true;
223 map< Vertex *, vector<Vertex *> >::const_iterator edgesIter = edges.find(currVertex);
224 if (edgesIter != edges.end())
226 for (vector<Vertex *>::const_iterator j = edgesIter->second.begin(); j != edgesIter->second.end(); ++j)
228 Vertex *nextVertex = *j;
229 nextVertices.insert(nextVertex);
231 map<Vertex *, vector<Vertex *> >::iterator nextNextVerticesIter = reachableVertices.find(nextVertex);
232 if (nextNextVerticesIter != reachableVertices.end())
235 nextVertices.insert( nextNextVerticesIter->second.begin(), nextNextVerticesIter->second.end() );
239 if (find(toVisit.begin(), toVisit.end(), nextVertex) != toVisit.end())
242 cycleVertices.insert(nextVertex);
247 toVisit.push_back(nextVertex);
248 areCurrVerticesComplete =
false;
254 if (areCurrVerticesComplete)
256 reachableVertices[currVertex].insert(reachableVertices[currVertex].end(), nextVertices.begin(), nextVertices.end());
261 return reachableVertices[vertex];
271 for (map<
Vertex *, vector<Vertex *> >::iterator i = edges.begin(); i != edges.end(); ++i)
273 ss << i->first->key();
274 if (showVertexPointers)
275 ss <<
" (" << i->first <<
")";
278 for (
Vertex *vertex : i->second)
280 ss <<
" " << vertex->
key();
281 if (showVertexPointers)
282 ss <<
" (" << vertex <<
")";
296 vector<VuoDirectedAcyclicGraph::Vertex *> foundVertices;
298 for (map<
VuoDirectedAcyclicGraph *, vector<VuoDirectedAcyclicGraph *> >::const_iterator i = edges.begin(); i != edges.end(); ++i)
302 foundVertices.push_back(vertex);
305 return foundVertices;
315 if (find(edges[fromGraph].begin(), edges[fromGraph].end(), toGraph) == edges[fromGraph].end())
317 edges[fromGraph].push_back(toGraph);
334 return getReachableVertices(vertex, edges,
true);
349 map< VuoDirectedAcyclicGraph *, vector<VuoDirectedAcyclicGraph *> > backEdges;
350 for (map<
VuoDirectedAcyclicGraph *, vector<VuoDirectedAcyclicGraph *> >::iterator i = edges.begin(); i != edges.end(); ++i)
352 for (vector<VuoDirectedAcyclicGraph *>::iterator j = i->second.begin(); j != i->second.end(); ++j)
353 if (find(backEdges[*j].begin(), backEdges[*j].end(), i->first) == backEdges[*j].end())
354 backEdges[*j].push_back(i->first);
359 return getReachableVertices(vertex, backEdges,
false);
369 vector<VuoDirectedAcyclicGraph::Vertex *> reachableVertices;
372 for (map<
VuoDirectedAcyclicGraph *, vector<VuoDirectedAcyclicGraph *> >::const_iterator i = edges.begin(); i != edges.end(); ++i)
374 if (i->first->edges.find(vertex) != i->first->edges.end())
376 containingGraph = i->first;
381 if (! containingGraph)
382 return reachableVertices;
384 list< pair< VuoDirectedAcyclicGraph *, vector<VuoDirectedAcyclicGraph::Vertex *> > > toVisit;
385 toVisit.push_back( make_pair(containingGraph, vector<VuoDirectedAcyclicGraph::Vertex *>(1, vertex)) );
387 while (! toVisit.empty())
390 vector<VuoDirectedAcyclicGraph::Vertex *> currVertices = toVisit.front().second;
393 map< VuoDirectedAcyclicGraph *, vector<VuoDirectedAcyclicGraph *> >::const_iterator edgesIter = edges.find(currGraph);
394 if (edgesIter != edges.end())
396 map< VuoDirectedAcyclicGraph *, vector<VuoDirectedAcyclicGraph::Vertex *> > moreToVisit;
398 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator i = currVertices.begin(); i != currVertices.end(); ++i)
401 vector<VuoDirectedAcyclicGraph::Vertex *> currReachableVertices = (isDownstream ?
405 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = currReachableVertices.begin(); j != currReachableVertices.end(); ++j)
409 if (find(reachableVertices.begin(), reachableVertices.end(), currReachableVertex) == reachableVertices.end())
410 reachableVertices.push_back(currReachableVertex);
413 vector<VuoDirectedAcyclicGraph::Vertex *> candidateVertices;
414 candidateVertices.push_back(currVertex);
415 candidateVertices.insert(candidateVertices.end(), currReachableVertices.begin(), currReachableVertices.end());
417 for (vector<VuoDirectedAcyclicGraph::Vertex *>::iterator j = candidateVertices.begin(); j != candidateVertices.end(); ++j)
421 for (vector<VuoDirectedAcyclicGraph *>::const_iterator k = edgesIter->second.begin(); k != edgesIter->second.end(); ++k)
426 if (matchingVertexInOtherGraph)
428 moreToVisit[otherGraph].push_back(matchingVertexInOtherGraph);
430 if (find(reachableVertices.begin(), reachableVertices.end(), matchingVertexInOtherGraph) == reachableVertices.end())
431 reachableVertices.push_back(matchingVertexInOtherGraph);
437 for (map<
VuoDirectedAcyclicGraph *, vector<VuoDirectedAcyclicGraph::Vertex *> >::iterator i = moreToVisit.begin(); i != moreToVisit.end(); ++i)
438 toVisit.push_back( make_pair(i->first, i->second) );
442 return reachableVertices;
452 for (map<
VuoDirectedAcyclicGraph *, vector<VuoDirectedAcyclicGraph *> >::iterator i = edges.begin(); i != edges.end(); ++i)
454 ss << i->first <<
" ->";
460 for (map<
VuoDirectedAcyclicGraph *, vector<VuoDirectedAcyclicGraph *> >::iterator i = edges.begin(); i != edges.end(); ++i)
462 string graphString = i->first->
toString(showVertexAddresses);
463 if (! graphString.empty())
464 ss <<
"\n" << i->first <<
":\n" << graphString <<
"\n";