3 template<typename VertexProperty, typename EdgeProperty, bool UniqueVertices>
4 void ForwardHyperGraph<VertexProperty,EdgeProperty,UniqueVertices>::toDot(const std::string& filename) const {
5 std::ofstream out(filename);
6 out << "digraph G {" << std::endl;
7 for (Vertex v = 0; v < mVertexProperties.size(); v++) {
8 out << "\t" << v << " [label=\"" << mVertexProperties[v] << "\"];" << std::endl;
10 std::size_t edgeid = 0;
11 for (Vertex src = 0; src < mEdges.size(); src++) {
12 for (const auto& e: mEdges[src]) {
13 out << "\tedge_" << edgeid << " [label=\"" << *e << "\", shape=box];" << std::endl;
14 out << "\t" << src << " -> edge_" << edgeid << ";" << std::endl;
15 for (const auto& dest: e.out()) {
16 out << "\t" << "edge_" << edgeid << " -> " << dest << ";" << std::endl;
21 out << "}" << std::endl;
25 template<typename VP, typename EP, bool UV>
26 std::ostream& operator<<(std::ostream& os, const ForwardHyperGraph<VP,EP,UV>& fhg) {
27 os << "ForwardHyperGraph:" << std::endl;
28 for (typename ForwardHyperGraph<VP,EP>::Vertex v = 0; v < fhg.mEdges.size(); v++) {
29 os << "\t" << v << " (" << fhg.mVertexProperties[v] << ")" << std::endl;
30 for (const auto& e: fhg.mEdges[v]) {
31 os << "\t\t(" << *e << ") ->";
32 for (const auto& out: e.out()) os << " " << out;
39 /* ***** Pseudo-Code for the algorithm implemented below *****
40 block[v]: is vertex v blocked?
41 B[b]: list of vertices that are blocked due to vertex v
42 stack: vertices on the current path
46 for u in B[v]: unblock(u)
48 function enumerate(src, v):
53 if u = src: output stack, found = true
55 if enumerate(src, u): found = true
67 look at subgraph induced by vertices s, ..., n
68 unblock all vertices in subgraph
69 find circuits starting from s: enumerate(s, s)
72 template<typename FHG, typename Collector>
73 bool CycleEnumerator<FHG,Collector>::enumerate(CycleEnumerator<FHG,Collector>::Vertex src, CycleEnumerator<FHG,Collector>::Vertex v) {
75 mVertexStack.push_back(v);
77 for (const auto& edge: mGraph.out(v)) {
78 for (Vertex u: edge.out()) {
80 mEdgeStack.push_back(edge);
81 mAborted = mCollector(mGraph, mVertexStack, mEdgeStack);
82 if (mAborted) return false;
84 mEdgeStack.pop_back();
85 } else if (!mBlocked[u]) {
86 mEdgeStack.push_back(edge);
87 found = found || enumerate(src, u);
88 if (mAborted) return false;
89 mEdgeStack.pop_back();
93 if (found) unblock(v);
95 for (const auto& edge: mGraph.out(v)) {
96 for (Vertex u: edge.out()) {
97 mBlockDependencies[u].push_back(v);
101 mVertexStack.pop_back();
105 template<typename FHG, typename Collector>
106 bool CycleEnumerator<FHG,Collector>::findAll() {
108 auto n = mGraph.begin();
109 while (!mAborted && (n < mGraph.end())) {
110 for (auto m = n; m < mGraph.end(); m++) unblock(m);
111 for (auto m = mGraph.begin(); m < n; m++) mBlocked[m] = true;