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 + -
显示快捷键?