minimum_degree_ordering.hpp
来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 670 行 · 第 1/2 页
HPP
670 行
//-*-c++-*-//=======================================================================// Copyright 1997-2001 University of Notre Dame.// Authors: Lie-Quan Lee, Jeremy Siek//// This file is part of the Boost Graph Library//// You should have received a copy of the License Agreement for the// Generic Graph Component Library along with the software; see the// file LICENSE. If not, contact Office of Research, University of Notre// Dame, Notre Dame, IN 46556.//// Permission to modify the code and to distribute modified code is// granted, provided the text of this NOTICE is retained, a notice that// the code was modified is included with the above COPYRIGHT NOTICE and// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE// file is distributed with the modified code.//// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.// By way of example, but not limitation, Licensor MAKES NO// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS// OR OTHER RIGHTS.//=======================================================================//#ifndef MINIMUM_DEGREE_ORDERING_HPP#define MINIMUM_DEGREE_ORDERING_HPP#include <vector>#include <cassert>#include <boost/config.hpp>#include <boost/pending/bucket_sorter.hpp>#include <boost/detail/numeric_traits.hpp> // for integer_traitsnamespace boost { namespace detail { // // Given a set of n integers (where the integer values range from // zero to n-1), we want to keep track of a collection of stacks // of integers. It so happens that an integer will appear in at // most one stack at a time, so the stacks form disjoint sets. // Because of these restrictions, we can use one big array to // store all the stacks, intertwined with one another. // No allocation/deallocation happens in the push()/pop() methods // so this is faster than using std::stack's. // template <class SignedInteger> class Stacks { typedef SignedInteger value_type; typedef typename std::vector<value_type>::size_type size_type; public: Stacks(size_type n) : data(n) {} //: stack class stack { typedef typename std::vector<value_type>::iterator Iterator; public: stack(Iterator _data, const value_type& head) : data(_data), current(head) {} // did not use default argument here to avoid internal compiler error // in g++. stack(Iterator _data) : data(_data), current(-(std::numeric_limits<value_type>::max)()) {} void pop() { assert(! empty()); current = data[current]; } void push(value_type v) { data[v] = current; current = v; } bool empty() { return current == -(std::numeric_limits<value_type>::max)(); } value_type& top() { return current; } private: Iterator data; value_type current; }; // To return a stack object stack make_stack() { return stack(data.begin()); } protected: std::vector<value_type> data; }; // marker class, a generalization of coloring. // // This class is to provide a generalization of coloring which has // complexity of amortized constant time to set all vertices' color // back to be untagged. It implemented by increasing a tag. // // The colors are: // not tagged // tagged // multiple_tagged // done // template <class SignedInteger, class Vertex, class VertexIndexMap> class Marker { typedef SignedInteger value_type; typedef typename std::vector<value_type>::size_type size_type; static value_type done() { return (std::numeric_limits<value_type>::max)()/2; } public: Marker(size_type _num, VertexIndexMap index_map) : tag(1 - (std::numeric_limits<value_type>::max)()), data(_num, - (std::numeric_limits<value_type>::max)()), id(index_map) {} void mark_done(Vertex node) { data[id[node]] = done(); } bool is_done(Vertex node) { return data[id[node]] == done(); } void mark_tagged(Vertex node) { data[id[node]] = tag; } void mark_multiple_tagged(Vertex node) { data[id[node]] = multiple_tag; } bool is_tagged(Vertex node) const { return data[id[node]] >= tag; } bool is_not_tagged(Vertex node) const { return data[id[node]] < tag; } bool is_multiple_tagged(Vertex node) const { return data[id[node]] >= multiple_tag; } void increment_tag() { const size_type num = data.size(); ++tag; if ( tag >= done() ) { tag = 1 - (std::numeric_limits<value_type>::max)(); for (size_type i = 0; i < num; ++i) if ( data[i] < done() ) data[i] = - (std::numeric_limits<value_type>::max)(); } } void set_multiple_tag(value_type mdeg0) { const size_type num = data.size(); multiple_tag = tag + mdeg0; if ( multiple_tag >= done() ) { tag = 1-(std::numeric_limits<value_type>::max)(); for (size_type i=0; i<num; i++) if ( data[i] < done() ) data[i] = -(std::numeric_limits<value_type>::max)(); multiple_tag = tag + mdeg0; } } void set_tag_as_multiple_tag() { tag = multiple_tag; } protected: value_type tag; value_type multiple_tag; std::vector<value_type> data; VertexIndexMap id; }; template< class Iterator, class SignedInteger, class Vertex, class VertexIndexMap, int offset = 1 > class Numbering { typedef SignedInteger number_type; number_type num; //start from 1 instead of zero Iterator data; number_type max_num; VertexIndexMap id; public: Numbering(Iterator _data, number_type _max_num, VertexIndexMap id) : num(1), data(_data), max_num(_max_num), id(id) {} void operator()(Vertex node) { data[id[node]] = -num; } bool all_done(number_type i = 0) const { return num + i > max_num; } void increment(number_type i = 1) { num += i; } bool is_numbered(Vertex node) const { return data[id[node]] < 0; } void indistinguishable(Vertex i, Vertex j) { data[id[i]] = - (id[j] + offset); } }; template <class SignedInteger, class Vertex, class VertexIndexMap> class degreelists_marker { public: typedef SignedInteger value_type; typedef typename std::vector<value_type>::size_type size_type; degreelists_marker(size_type n, VertexIndexMap id) : marks(n, 0), id(id) {} void mark_need_update(Vertex i) { marks[id[i]] = 1; } bool need_update(Vertex i) { return marks[id[i]] == 1; } bool outmatched_or_done (Vertex i) { return marks[id[i]] == -1; } void mark(Vertex i) { marks[id[i]] = -1; } void unmark(Vertex i) { marks[id[i]] = 0; } private: std::vector<value_type> marks; VertexIndexMap id; }; // Helper function object for edge removal template <class Graph, class MarkerP, class NumberD, class Stack, class VertexIndexMap> class predicateRemoveEdge1 { typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; typedef typename graph_traits<Graph>::edge_descriptor edge_t; public: predicateRemoveEdge1(Graph& _g, MarkerP& _marker, NumberD _numbering, Stack& n_e, VertexIndexMap id) : g(&_g), marker(&_marker), numbering(_numbering), neighbor_elements(&n_e), id(id) {} bool operator()(edge_t e) { vertex_t dist = target(e, *g); if ( marker->is_tagged(dist) ) return true; marker->mark_tagged(dist); if (numbering.is_numbered(dist)) { neighbor_elements->push(id[dist]); return true; } return false; } private: Graph* g; MarkerP* marker; NumberD numbering; Stack* neighbor_elements; VertexIndexMap id; }; // Helper function object for edge removal template <class Graph, class MarkerP> class predicate_remove_tagged_edges { typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; typedef typename graph_traits<Graph>::edge_descriptor edge_t; public: predicate_remove_tagged_edges(Graph& _g, MarkerP& _marker) : g(&_g), marker(&_marker) {} bool operator()(edge_t e) { vertex_t dist = target(e, *g); if ( marker->is_tagged(dist) ) return true; return false; } private: Graph* g; MarkerP* marker; }; template<class Graph, class DegreeMap, class InversePermutationMap, class PermutationMap, class SuperNodeMap, class VertexIndexMap> class mmd_impl { // Typedefs typedef graph_traits<Graph> Traits; typedef typename Traits::vertices_size_type size_type; typedef typename detail::integer_traits<size_type>::difference_type diff_t; typedef typename Traits::vertex_descriptor vertex_t; typedef typename Traits::adjacency_iterator adj_iter; typedef iterator_property_map<vertex_t*, identity_property_map, vertex_t, vertex_t&> IndexVertexMap; typedef detail::Stacks<diff_t> Workspace; typedef bucket_sorter<size_type, vertex_t, DegreeMap, VertexIndexMap> DegreeLists; typedef Numbering<InversePermutationMap, diff_t, vertex_t,VertexIndexMap> NumberingD; typedef degreelists_marker<diff_t, vertex_t, VertexIndexMap> DegreeListsMarker; typedef Marker<diff_t, vertex_t, VertexIndexMap> MarkerP; // Data Members // input parameters Graph& G; int delta; DegreeMap degree; InversePermutationMap inverse_perm; PermutationMap perm; SuperNodeMap supernode_size; VertexIndexMap vertex_index_map; // internal data-structures std::vector<vertex_t> index_vertex_vec; size_type n; IndexVertexMap index_vertex_map; DegreeLists degreelists; NumberingD numbering; DegreeListsMarker degree_lists_marker; MarkerP marker; Workspace work_space; public: mmd_impl(Graph& g, size_type n_, int delta, DegreeMap degree, InversePermutationMap inverse_perm, PermutationMap perm, SuperNodeMap supernode_size, VertexIndexMap id) : G(g), delta(delta), degree(degree), inverse_perm(inverse_perm), perm(perm), supernode_size(supernode_size), vertex_index_map(id), index_vertex_vec(n_), n(n_), degreelists(n_ + 1, n_, degree, id), numbering(inverse_perm, n_, vertex_index_map), degree_lists_marker(n_, vertex_index_map), marker(n_, vertex_index_map), work_space(n_) { typename graph_traits<Graph>::vertex_iterator v, vend; size_type vid = 0; for (tie(v, vend) = vertices(G); v != vend; ++v, ++vid) index_vertex_vec[vid] = *v; index_vertex_map = IndexVertexMap(&index_vertex_vec[0]); // Initialize degreelists. Degreelists organizes the nodes // according to their degree. for (tie(v, vend) = vertices(G); v != vend; ++v) { put(degree, *v, out_degree(*v, G)); degreelists.push(*v);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?