/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
DataFormats/Math/interface/GraphWalker.h
177 строк
5 KB
Shahzad Malik Muzaffar
[DataFormats][clang-tidy] make deleted function public
28 июл 2021, 15:38
28 июл 2021, 15:38
4fd5d99
Код
Авторство
О чём код?
#ifndef DATA_FORMATS_MATH_GRAPH_WALKER_H #define DATA_FORMATS_MATH_GRAPH_WALKER_H #include "DataFormats/Math/interface/Graph.h" #include <queue> #include <vector> namespace math { /** a walker for an acyclic directed multigraph */ template <class N, class E> class GraphWalker { public: using index_type = typename math::Graph<N, E>::index_type; using index_result = typename math::Graph<N, E>::index_result; using edge_type = typename math::Graph<N, E>::edge_type; using edge_list = typename math::Graph<N, E>::edge_list; using edge_iterator = typename math::Graph<N, E>::edge_iterator; using const_edge_iterator = typename math::Graph<N, E>::const_edge_iterator; // only a const-edge_range! using edge_range = std::pair<const_edge_iterator, const_edge_iterator>; using stack_type = std::vector<edge_range>; using bfs_type = std::queue<edge_type>; using result_type = bool; using value_type = typename math::Graph<N, E>::value_type; public: //! creates a walker rooted by the first candidate root found in the underlying Graph GraphWalker(const Graph<N, E> &); //! creates a walker rooted by the node given GraphWalker(const Graph<N, E> &, const N &); GraphWalker() = delete; // operations result_type firstChild(); result_type nextSibling(); result_type parent(); result_type next(); inline value_type current() const; result_type next_bfs(); value_type current_bfs() const; void reset(); const stack_type &stack() const { return stack_; } protected: // stack_.back().first corresponds to index of the current node! stack_type stack_; // hierarchical stack used in navigation bfs_type queue_; // breath first search queue edge_list root_; // root of the walker const Graph<N, E> &graph_; }; template <class N, class E> GraphWalker<N, E>::GraphWalker(const Graph<N, E> &g) : graph_(g) { // complexity = (no nodes) * (no edges) graph_.findRoots(root_); stack_.emplace_back(edge_range(root_.begin(), root_.end())); if (!root_.empty()) { queue_.push(root_[0]); } } template <class N, class E> GraphWalker<N, E>::GraphWalker(const Graph<N, E> &g, const N &root) : graph_(g) { index_result rr = graph_.nodeIndex(root); if (!rr.second) // no such root node, no walker can be created! throw root; root_.emplace_back(edge_type(rr.first, 0)); stack_.emplace_back(edge_range(root_.begin(), root_.end())); queue_.push(root_[0]); } template <class N, class E> typename GraphWalker<N, E>::value_type GraphWalker<N, E>::current() const { const edge_range &er = stack_.back(); return value_type(graph_.nodeData(er.first->first), graph_.edgeData(er.first->second)); } template <class N, class E> typename GraphWalker<N, E>::value_type GraphWalker<N, E>::current_bfs() const { const edge_type &e = queue_.front(); return value_type(graph_.nodeData(e.first), graph_.edgeData(e.second)); } template <class N, class E> void GraphWalker<N, E>::reset() { stack_.clear(); stack_.emplace_back(edge_range(root_.begin(), root_.end())); queue_.clear(); if (root_.size()) { queue_.push(root_[0]); } } template <class N, class E> typename GraphWalker<N, E>::result_type GraphWalker<N, E>::firstChild() { result_type result = false; const edge_range &adjEdges = graph_.edges(stack_.back().first->first); if (adjEdges.first != adjEdges.second) { stack_.emplace_back(adjEdges); result = true; } return result; } template <class N, class E> typename GraphWalker<N, E>::result_type GraphWalker<N, E>::nextSibling() { result_type result = false; edge_range &siblings = stack_.back(); if (siblings.first != (siblings.second - 1)) { ++siblings.first; result = true; } return result; } template <class N, class E> typename GraphWalker<N, E>::result_type GraphWalker<N, E>::parent() { result_type result = false; if (stack_.size() > 1) { stack_.pop_back(); result = true; } return result; } template <class N, class E> typename GraphWalker<N, E>::result_type GraphWalker<N, E>::next() { result_type result = false; if (firstChild()) { result = true; } else if (stack_.size() > 1 && nextSibling()) { result = true; } else { while (parent()) { if (stack_.size() > 1 && nextSibling()) { result = true; break; } } } return result; } template <class N, class E> typename GraphWalker<N, E>::result_type GraphWalker<N, E>::next_bfs() { result_type result(false); if (!queue_.empty()) { const edge_type &e = queue_.front(); const edge_range &er = graph_.edges(e.first); const_edge_iterator it(er.first), ed(er.second); for (; it != ed; ++it) { queue_.push(*it); } queue_.pop(); if (!queue_.empty()) { result = true; } } return result; } } // namespace math #endif