epoc32/include/stdapis/boost/graph/detail/sparse_ordering.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
williamr@2
     1
//=======================================================================
williamr@2
     2
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
williamr@2
     3
// Copyright 2004, 2005 Trustees of Indiana University
williamr@2
     4
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
williamr@2
     5
//          Doug Gregor, D. Kevin McGrath
williamr@2
     6
//
williamr@2
     7
// Distributed under the Boost Software License, Version 1.0. (See
williamr@2
     8
// accompanying file LICENSE_1_0.txt or copy at
williamr@2
     9
// http://www.boost.org/LICENSE_1_0.txt)
williamr@2
    10
//=======================================================================//
williamr@2
    11
#ifndef BOOST_GRAPH_DETAIL_SPARSE_ORDERING_HPP
williamr@2
    12
#define BOOST_GRAPH_DETAIL_SPARSE_ORDERING_HPP
williamr@2
    13
williamr@2
    14
#include <boost/config.hpp>
williamr@2
    15
#include <vector>
williamr@2
    16
#include <queue>
williamr@2
    17
#include <boost/pending/queue.hpp>
williamr@2
    18
#include <boost/pending/mutable_queue.hpp>
williamr@2
    19
#include <boost/graph/graph_traits.hpp>
williamr@2
    20
#include <boost/graph/breadth_first_search.hpp>
williamr@2
    21
#include <boost/graph/properties.hpp>
williamr@2
    22
#include <boost/pending/indirect_cmp.hpp>
williamr@2
    23
#include <boost/property_map.hpp>
williamr@2
    24
#include <boost/bind.hpp>
williamr@2
    25
#include <boost/graph/iteration_macros.hpp>
williamr@2
    26
#include <boost/graph/depth_first_search.hpp>
williamr@2
    27
williamr@2
    28
namespace boost {
williamr@2
    29
williamr@2
    30
  namespace sparse {
williamr@2
    31
williamr@2
    32
    // rcm_queue
williamr@2
    33
    //
williamr@2
    34
    // This is a custom queue type used in the
williamr@2
    35
    // *_ordering algorithms.
williamr@2
    36
    // In addition to the normal queue operations, the
williamr@2
    37
    // rcm_queue provides:
williamr@2
    38
    // 
williamr@2
    39
    //   int eccentricity() const;
williamr@2
    40
    //   value_type spouse() const;
williamr@2
    41
    // 
williamr@2
    42
williamr@2
    43
    // yes, it's a bad name...but it works, so use it
williamr@2
    44
    template < class Vertex, class DegreeMap,
williamr@2
    45
               class Container = std::deque<Vertex> >
williamr@2
    46
    class rcm_queue : public std::queue<Vertex, Container> {
williamr@2
    47
      typedef std::queue<Vertex> base;
williamr@2
    48
    public:
williamr@2
    49
      typedef typename base::value_type value_type;
williamr@2
    50
      typedef typename base::size_type size_type;
williamr@2
    51
williamr@2
    52
      /* SGI queue has not had a contructor queue(const Container&) */
williamr@2
    53
      inline rcm_queue(DegreeMap deg)
williamr@2
    54
        : _size(0), Qsize(1), eccen(-1), degree(deg) { }
williamr@2
    55
williamr@2
    56
      inline void pop() {
williamr@2
    57
        if ( !_size ) 
williamr@2
    58
          Qsize = base::size();
williamr@2
    59
williamr@2
    60
        base::pop();
williamr@2
    61
        if ( _size == Qsize-1 ) {
williamr@2
    62
          _size = 0;
williamr@2
    63
          ++eccen;
williamr@2
    64
        } else 
williamr@2
    65
          ++_size;
williamr@2
    66
williamr@2
    67
      }
williamr@2
    68
williamr@2
    69
      inline value_type& front() {
williamr@2
    70
        value_type& u =  base::front();
williamr@2
    71
        if ( _size == 0 ) 
williamr@2
    72
          w = u;
williamr@2
    73
        else if (get(degree,u) < get(degree,w) )
williamr@2
    74
          w = u;
williamr@2
    75
        return u;
williamr@2
    76
      }
williamr@2
    77
williamr@2
    78
      inline const value_type& front() const {
williamr@2
    79
        const value_type& u =  base::front();
williamr@2
    80
        if ( _size == 0 ) 
williamr@2
    81
          w = u;
williamr@2
    82
        else if (get(degree,u) < get(degree,w) )
williamr@2
    83
          w = u;
williamr@2
    84
        return u;
williamr@2
    85
      }
williamr@2
    86
williamr@2
    87
      inline value_type& top() { return front(); }
williamr@2
    88
      inline const value_type& top() const { return front(); }
williamr@2
    89
williamr@2
    90
      inline size_type size() const { return base::size(); }
williamr@2
    91
williamr@2
    92
      inline size_type eccentricity() const { return eccen; }
williamr@2
    93
      inline value_type spouse() const { return w; }
williamr@2
    94
williamr@2
    95
    protected:
williamr@2
    96
      size_type _size;
williamr@2
    97
      size_type Qsize;
williamr@2
    98
      int eccen;
williamr@2
    99
      mutable value_type w;
williamr@2
   100
      DegreeMap degree;
williamr@2
   101
    };
williamr@2
   102
williamr@2
   103
williamr@2
   104
    template <typename Tp, typename Sequence = std::deque<Tp> >
williamr@2
   105
    class sparse_ordering_queue : public boost::queue<Tp, Sequence>{
williamr@2
   106
    public:      
williamr@2
   107
      typedef typename Sequence::iterator iterator;
williamr@2
   108
      typedef typename Sequence::reverse_iterator reverse_iterator;
williamr@2
   109
      typedef queue<Tp,Sequence> base;
williamr@2
   110
      typedef typename Sequence::size_type size_type;
williamr@2
   111
williamr@2
   112
      inline iterator begin() { return this->c.begin(); }
williamr@2
   113
      inline reverse_iterator rbegin() { return this->c.rbegin(); }
williamr@2
   114
      inline iterator end() { return this->c.end(); }
williamr@2
   115
      inline reverse_iterator rend() { return this->c.rend(); }
williamr@2
   116
      inline Tp &operator[](int n) { return this->c[n]; }
williamr@2
   117
      inline size_type size() {return this->c.size(); }
williamr@2
   118
    protected:
williamr@2
   119
      //nothing
williamr@2
   120
    };
williamr@2
   121
    
williamr@2
   122
  } // namespace sparse 
williamr@2
   123
williamr@2
   124
  // Compute Pseudo peripheral
williamr@2
   125
  //
williamr@2
   126
  // To compute an approximated peripheral for a given vertex. 
williamr@2
   127
  // Used in <tt>king_ordering</tt> algorithm.
williamr@2
   128
  //
williamr@2
   129
  template <class Graph, class Vertex, class ColorMap, class DegreeMap>
williamr@2
   130
  Vertex 
williamr@2
   131
  pseudo_peripheral_pair(Graph& G, const Vertex& u, int& ecc,
williamr@2
   132
                         ColorMap color, DegreeMap degree)
williamr@2
   133
  {
williamr@2
   134
    typedef typename property_traits<ColorMap>::value_type ColorValue;
williamr@2
   135
    typedef color_traits<ColorValue> Color;
williamr@2
   136
    
williamr@2
   137
    sparse::rcm_queue<Vertex, DegreeMap> Q(degree);
williamr@2
   138
williamr@2
   139
    typename boost::graph_traits<Graph>::vertex_iterator ui, ui_end;
williamr@2
   140
    for (tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
williamr@2
   141
      if (get(color, *ui) != Color::red()) put(color, *ui, Color::white());
williamr@2
   142
    breadth_first_visit(G, u, buffer(Q).color_map(color));
williamr@2
   143
williamr@2
   144
    ecc = Q.eccentricity(); 
williamr@2
   145
    return Q.spouse();
williamr@2
   146
  }
williamr@2
   147
williamr@2
   148
  // Find a good starting node
williamr@2
   149
  //
williamr@2
   150
  // This is to find a good starting node for the
williamr@2
   151
  // king_ordering algorithm. "good" is in the sense
williamr@2
   152
  // of the ordering generated by RCM.
williamr@2
   153
  //
williamr@2
   154
  template <class Graph, class Vertex, class Color, class Degree> 
williamr@2
   155
  Vertex find_starting_node(Graph& G, Vertex r, Color color, Degree degree)
williamr@2
   156
  {
williamr@2
   157
    Vertex x, y;
williamr@2
   158
    int eccen_r, eccen_x;
williamr@2
   159
williamr@2
   160
    x = pseudo_peripheral_pair(G, r, eccen_r, color, degree);
williamr@2
   161
    y = pseudo_peripheral_pair(G, x, eccen_x, color, degree);
williamr@2
   162
williamr@2
   163
    while (eccen_x > eccen_r) {
williamr@2
   164
      r = x;
williamr@2
   165
      eccen_r = eccen_x;
williamr@2
   166
      x = y;
williamr@2
   167
      y = pseudo_peripheral_pair(G, x, eccen_x, color, degree);
williamr@2
   168
    }
williamr@2
   169
    return x;
williamr@2
   170
  }
williamr@2
   171
williamr@2
   172
template <typename Graph>
williamr@2
   173
class out_degree_property_map 
williamr@2
   174
  : public put_get_helper<typename graph_traits<Graph>::degree_size_type,
williamr@2
   175
                          out_degree_property_map<Graph> >                  
williamr@2
   176
{
williamr@2
   177
public:
williamr@2
   178
  typedef typename graph_traits<Graph>::vertex_descriptor key_type;
williamr@2
   179
  typedef typename graph_traits<Graph>::degree_size_type value_type;
williamr@2
   180
  typedef value_type reference;
williamr@2
   181
  typedef readable_property_map_tag category;
williamr@2
   182
  out_degree_property_map(const Graph& g) : m_g(g) { }
williamr@2
   183
  value_type operator[](const key_type& v) const {
williamr@2
   184
    return out_degree(v, m_g);
williamr@2
   185
  }
williamr@2
   186
private:
williamr@2
   187
  const Graph& m_g;
williamr@2
   188
};
williamr@2
   189
template <typename Graph>
williamr@2
   190
inline out_degree_property_map<Graph>
williamr@2
   191
make_out_degree_map(const Graph& g) {
williamr@2
   192
  return out_degree_property_map<Graph>(g);
williamr@2
   193
}
williamr@2
   194
williamr@2
   195
} // namespace boost
williamr@2
   196
williamr@2
   197
williamr@2
   198
#endif // BOOST_GRAPH_KING_HPP