libsemigroups  v3.0.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
gabow.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2023-2025 James D. Mitchell
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17//
18
19// This file contains the declaration of a class implementing Gabow's algorithm
20// for WordGraphs.
21
22#ifndef LIBSEMIGROUPS_GABOW_HPP_
23#define LIBSEMIGROUPS_GABOW_HPP_
24
25#include <cstddef> // for size_t
26#include <iterator> // for pair
27#include <queue> // for queue
28#include <stack> // for stack
29#include <string> // for string
30#include <vector> // for vector
31
32#include "constants.hpp" // for UNDEFINED, operator!=, Undefined
33#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
34#include "exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
35#include "forest.hpp" // for Forest
36#include "ranges.hpp" // for iterator_range, transform
37#include "word-graph.hpp" // for WordGraph
38
39namespace libsemigroups {
40
60 template <typename Node>
61 class Gabow {
62 public:
64 using node_type = Node;
65
68
70 using size_type = size_t;
71
72 private:
73 WordGraph<node_type> const* _graph;
75 mutable bool _finished;
76 mutable std::vector<size_type> _id;
77 mutable Forest _bckwd_forest;
78 mutable bool _bckwd_forest_defined;
79 mutable Forest _forwd_forest;
80 mutable bool _forwd_forest_defined;
81
82 public:
87 Gabow() = delete;
88
92 Gabow(Gabow const&) = default;
93
97 Gabow(Gabow&&) = default;
98
102 Gabow& operator=(Gabow const&) = default;
103
107 Gabow& operator=(Gabow&&) = default;
108
109 ~Gabow();
110
121 explicit Gabow(WordGraph<node_type> const& wg) {
122 init(wg);
123 }
124
142
160 [[nodiscard]] size_type id_no_checks(node_type n) const {
161 run();
162 return _id[n];
163 }
164
180 // Not noexcept because throw_if_node_out_of_range isn't
181 [[nodiscard]] size_type id(node_type n) const {
182 run();
183 throw_if_node_out_of_range(n);
184 return id_no_checks(n);
185 }
186
202 [[nodiscard]] std::vector<std::vector<node_type>> const&
203 components() const {
204 run();
205 return _comps;
206 }
207
226 [[nodiscard]] std::vector<node_type> const& component(size_type i) const {
227 run();
228 throw_if_scc_index_out_of_range(i);
229 return _comps[i];
230 }
231
253 [[nodiscard]] std::vector<node_type>
255 run();
256 return _comps[i];
257 }
258
272 [[nodiscard]] size_t number_of_components() const {
273 run();
274 return _comps.size();
275 }
276
291 [[nodiscard]] auto roots() const {
292 run();
293 return (rx::iterator_range(_comps.cbegin(), _comps.cend())
294 | rx::transform([](auto const& comp) { return comp[0]; }));
295 }
296
315 // Not noexcept because scc_id isn't
316 [[nodiscard]] node_type root_of(node_type n) const {
317 return component_of(n)[0];
318 }
319
341 [[nodiscard]] node_type root_of_no_checks(node_type n) const {
342 return component_of_no_checks(n)[0];
343 }
344
362 [[nodiscard]] std::vector<node_type> const&
364 run();
365 throw_if_node_out_of_range(n);
366 return _comps[_id[n]];
367 }
368
388 [[nodiscard]] std::vector<node_type> const&
390 run();
391 return _comps[_id[n]];
392 }
393
408 Forest const& spanning_forest() const;
409
426
439 WordGraph<Node> const& word_graph() const noexcept {
440 return *_graph;
441 }
442
453 [[nodiscard]] bool has_components() const noexcept {
454 return _finished;
455 }
456
457 private:
458 void reset() const noexcept;
459 void run() const;
460 void throw_if_node_out_of_range(node_type n) const;
461 void throw_if_scc_index_out_of_range(size_t i) const;
462 };
463
467 template <typename Node>
468 Gabow(WordGraph<Node> const&) -> Gabow<Node>;
469
484 template <typename Node>
485 std::string to_human_readable_repr(Gabow<Node> const& g);
486
487} // namespace libsemigroups
488
489#include "gabow.tpp"
490#endif // LIBSEMIGROUPS_GABOW_HPP_
Class representing a collection of spanning trees of a word graph.
Definition forest.hpp:42
Forest const & spanning_forest() const
Returns a spanning forest of the strongly connected components.
Node node_type
Type of the nodes in the underlying WordGraph.
Definition gabow.hpp:64
Gabow & operator=(Gabow &&)=default
Default move assignment operator.
WordGraph< Node > const & word_graph() const noexcept
Returns a const reference to the underlying word graph.
Definition gabow.hpp:439
std::vector< node_type > const & component_of(node_type n) const
Returns a const reference to a vector containing the strongly connected component of a given node.
Definition gabow.hpp:363
std::string to_human_readable_repr(Gabow< uint32_t > const &g)
std::vector< node_type > const & component(size_type i) const
Returns a const reference to a vector containing the strongly connected component with given index.
Definition gabow.hpp:226
Gabow(WordGraph< uint32_t > const &) -> Gabow< uint32_t >
size_t number_of_components() const
Returns the number of strongly connected components.
Definition gabow.hpp:272
size_type id(node_type n) const
Returns the id-number of the strongly connected component of a node.
Definition gabow.hpp:181
bool has_components() const noexcept
Check whether the strongly connected components have been found.
Definition gabow.hpp:453
Gabow & operator=(Gabow const &)=default
Default copy assignment operator.
std::vector< node_type > component_no_checks(size_type i) const
Returns a const reference to a vector containing the strongly connected component with given index.
Definition gabow.hpp:254
std::vector< std::vector< node_type > > const & components() const
Returns a const reference to a vector of vectors containing the strongly connected components.
Definition gabow.hpp:203
size_t size_type
Size type used for indices of strongly connected components.
Definition gabow.hpp:70
Gabow(Gabow &&)=default
Default move constructor.
Gabow(WordGraph< node_type > const &wg)
Construct from WordGraph.
Definition gabow.hpp:121
Gabow & init(WordGraph< node_type > const &wg)
Reinitialize a Gabow object.
Gabow()=delete
Deleted.
std::vector< node_type > const & component_of_no_checks(node_type n) const
Returns a const reference to a vector containing the strongly connected component of a given node.
Definition gabow.hpp:389
size_type id_no_checks(node_type n) const
Get the id of a strongly connected component of a node.
Definition gabow.hpp:160
typename WordGraph< node_type >::label_type label_type
Type of the edge labels in the underlying WordGraph.
Definition gabow.hpp:67
auto roots() const
Returns a range object consisting of roots of the strongly connected components.
Definition gabow.hpp:291
node_type root_of(node_type n) const
Returns the root of the strongly connected component containing a given node.
Definition gabow.hpp:316
Forest const & reverse_spanning_forest() const
Returns a reverse spanning forest of the strongly connected components (if they are not already known...
Gabow(Gabow const &)=default
Default copy constructor.
node_type root_of_no_checks(node_type n) const
Returns the root of the strongly connected component containing a given node.
Definition gabow.hpp:341
Class for representing word graphs.
Definition word-graph.hpp:82
Node label_type
The type of edge labels in a word graph.
Definition word-graph.hpp:101
Namespace for everything in the libsemigroups library.
Definition action.hpp:44