mCRL2
Loading...
Searching...
No Matches
SCC_impl.h
Go to the documentation of this file.
1// Copyright (c) 2009-2013 University of Twente
2// Copyright (c) 2009-2013 Michael Weber <michaelw@cs.utwente.nl>
3// Copyright (c) 2009-2013 Maks Verver <maksverver@geocities.com>
4// Copyright (c) 2009-2013 Eindhoven University of Technology
5//
6// Distributed under the Boost Software License, Version 1.0.
7// (See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9
10// Don't include this directly; include SCC.h instead!
11
12
13#ifndef MCRL2_PG_SCC_IMPL_H
14#define MCRL2_PG_SCC_IMPL_H
15
16#include "mcrl2/pg/Graph.h"
17
18
34template<class Callback>
35class SCC
36{
37public:
38 SCC(const StaticGraph &graph, Callback &callback)
39 : graph_(graph), callback_(callback)
40 {
41 }
42
43 int run()
44 {
45 // Initialize data structures used in the algorithm
46 next_index = 0;
47 info.clear();
48 info.insert( info.end(), graph_.V(),
49 std::make_pair(NO_VERTEX, NO_VERTEX) );
50 stack.clear();
51
52 // Process all vertices
53 for (verti v = 0; v < graph_.V();++v)
54 {
55 if (info[v].first == NO_VERTEX)
56 {
57 assert(stack.empty());
58 add(v);
59 int res = dfs();
60 if (res != 0) return res;
61 }
62 }
63 assert(stack.empty());
64 return 0;
65 }
66
67private:
68 void add(verti v)
69 {
70 // Mark vertex as visited and part of the current component
71 info[v].first = info[v].second = next_index++;
72 component.push_back(v);
73
74 // Add to stack to be processed in depth-first-search
75 stack.push_back(std::make_pair(v, 0));
76 }
77
78 /* This implements depth-first-search using a stack, which is a bit more
79 complicated but allows us to process arbitrarily large graphs limited
80 by available heap space only (instead of being limited by the call
81 stack size) as well as conserving some memory. */
82 int dfs()
83 {
84 int res = 0;
85
86 while (res == 0 && !stack.empty())
87 {
88 verti v = stack.back().first;
90 graph_.succ_begin(v) + stack.back().second++;
91
92 if (edge_it != graph_.succ_end(v))
93 {
94 // Find next successor `w` of `v`
95 verti w = *edge_it;
96
97 if (info[w].first == NO_VERTEX) // unvisited?
98 {
99 add(w);
100 }
101 else
102 if (info[w].second != NO_VERTEX) // part of current component?
103 {
104 /* Check if w's index is lower than v's lowest link, if so,
105 set it to be our lowest link index. */
106 info[v].second = std::min(info[v].second, info[w].first);
107 }
108 }
109 else
110 {
111 // We're done with this vertex
112 stack.pop_back();
113
114 if (!stack.empty())
115 {
116 /* Push my lower link index to parent vertex `u`, if it
117 is lower than the parent's current lower link index. */
118 int u = stack.back().first;
119 info[u].second = std::min(info[u].second, info[v].second);
120 }
121
122 // Check if v is the component's root (idx == lowest link idx)
123 if (info[v].first == info[v].second)
124 {
125 // Find v in the current component
126 std::vector<verti>::iterator it = component.end();
127 do {
128 assert(it != component.begin());
129 info[*--it].second = NO_VERTEX; // mark as removed
130 } while (*it != v);
131
132 // Call callback functor to handle this component
133 res = callback_((const verti*)&*it, component.end() - it);
134
135 // Remove vertices from current component
136 component.erase(it, component.end());
137 }
138 }
139 }
140
141 return res;
142 }
143
144public:
146 Callback &callback_;
147
148private:
151
153 std::vector<std::pair<verti, verti> > info;
154
156 std::vector<verti> component;
157
165 std::vector< std::pair< verti, verti > > stack;
166};
167
168#endif // MCRL2_PG_SCC_IMPL_H
std::size_t verti
type used to number vertices
Definition Graph.h:24
#define NO_VERTEX
Definition Graph.h:27
Definition SCC_impl.h:36
verti next_index
Index of next vertex to be labelled by inorder traversal.
Definition SCC_impl.h:150
const StaticGraph & graph_
Definition SCC_impl.h:145
int dfs()
Definition SCC_impl.h:82
void add(verti v)
Definition SCC_impl.h:68
Callback & callback_
Definition SCC_impl.h:146
SCC(const StaticGraph &graph, Callback &callback)
Definition SCC_impl.h:38
std::vector< std::pair< verti, verti > > info
Inorder index and lowest link index of each vertex.
Definition SCC_impl.h:153
std::vector< verti > component
Vertex indices of the current component.
Definition SCC_impl.h:156
std::vector< std::pair< verti, verti > > stack
Definition SCC_impl.h:165
int run()
Definition SCC_impl.h:43
const_iterator succ_end(verti v) const
Definition Graph.h:193
const_iterator succ_begin(verti v) const
Definition Graph.h:188
verti V() const
Definition Graph.h:179
const verti * const_iterator
Definition Graph.h:66