os/ossrv/ossrv_pub/boost_apis/boost/graph/page_rank.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright 2004-5 The Trustees of Indiana University.
sl@0
     2
// Copyright 2002 Brad King and Douglas Gregor
sl@0
     3
sl@0
     4
// Distributed under the Boost Software License, Version 1.0.
sl@0
     5
// (See accompanying file LICENSE_1_0.txt or copy at
sl@0
     6
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     7
sl@0
     8
//  Authors: Douglas Gregor
sl@0
     9
//           Andrew Lumsdaine
sl@0
    10
sl@0
    11
#ifndef BOOST_GRAPH_PAGE_RANK_HPP
sl@0
    12
#define BOOST_GRAPH_PAGE_RANK_HPP
sl@0
    13
sl@0
    14
#include <boost/property_map.hpp>
sl@0
    15
#include <boost/graph/graph_traits.hpp>
sl@0
    16
#include <boost/graph/properties.hpp>
sl@0
    17
#include <boost/graph/iteration_macros.hpp>
sl@0
    18
#include <vector>
sl@0
    19
sl@0
    20
namespace boost { namespace graph {
sl@0
    21
sl@0
    22
struct n_iterations
sl@0
    23
{
sl@0
    24
  explicit n_iterations(std::size_t n) : n(n) { }
sl@0
    25
sl@0
    26
  template<typename RankMap, typename Graph>
sl@0
    27
  bool 
sl@0
    28
  operator()(const RankMap&, const Graph&)
sl@0
    29
  {
sl@0
    30
    return n-- == 0;
sl@0
    31
  }
sl@0
    32
sl@0
    33
 private:
sl@0
    34
  std::size_t n;
sl@0
    35
};
sl@0
    36
sl@0
    37
namespace detail {
sl@0
    38
  template<typename Graph, typename RankMap, typename RankMap2>
sl@0
    39
  void page_rank_step(const Graph& g, RankMap from_rank, RankMap2 to_rank,
sl@0
    40
                      typename property_traits<RankMap>::value_type damping,
sl@0
    41
                      incidence_graph_tag)
sl@0
    42
  {
sl@0
    43
    typedef typename property_traits<RankMap>::value_type rank_type;
sl@0
    44
sl@0
    45
    // Set new rank maps 
sl@0
    46
    BGL_FORALL_VERTICES_T(v, g, Graph) put(to_rank, v, rank_type(1 - damping));
sl@0
    47
sl@0
    48
    BGL_FORALL_VERTICES_T(u, g, Graph) {
sl@0
    49
      rank_type u_rank_out = damping * get(from_rank, u) / out_degree(u, g);
sl@0
    50
      BGL_FORALL_ADJ_T(u, v, g, Graph)
sl@0
    51
        put(to_rank, v, get(to_rank, v) + u_rank_out);
sl@0
    52
    }
sl@0
    53
  }
sl@0
    54
sl@0
    55
  template<typename Graph, typename RankMap, typename RankMap2>
sl@0
    56
  void page_rank_step(const Graph& g, RankMap from_rank, RankMap2 to_rank,
sl@0
    57
                      typename property_traits<RankMap>::value_type damping,
sl@0
    58
                      bidirectional_graph_tag)
sl@0
    59
  {
sl@0
    60
    typedef typename property_traits<RankMap>::value_type damping_type;
sl@0
    61
    BGL_FORALL_VERTICES_T(v, g, Graph) {
sl@0
    62
      typename property_traits<RankMap>::value_type rank(0);
sl@0
    63
      BGL_FORALL_INEDGES_T(v, e, g, Graph)
sl@0
    64
        rank += get(from_rank, source(e, g)) / out_degree(source(e, g), g);
sl@0
    65
      put(to_rank, v, (damping_type(1) - damping) + damping * rank);
sl@0
    66
    }
sl@0
    67
  }
sl@0
    68
} // end namespace detail
sl@0
    69
sl@0
    70
template<typename Graph, typename RankMap, typename Done, typename RankMap2>
sl@0
    71
void
sl@0
    72
page_rank(const Graph& g, RankMap rank_map, Done done, 
sl@0
    73
          typename property_traits<RankMap>::value_type damping,
sl@0
    74
          typename graph_traits<Graph>::vertices_size_type n,
sl@0
    75
          RankMap2 rank_map2)
sl@0
    76
{
sl@0
    77
  typedef typename property_traits<RankMap>::value_type rank_type;
sl@0
    78
sl@0
    79
  rank_type initial_rank = rank_type(rank_type(1) / n);
sl@0
    80
  BGL_FORALL_VERTICES_T(v, g, Graph) put(rank_map, v, initial_rank);
sl@0
    81
sl@0
    82
  bool to_map_2 = true;
sl@0
    83
  while ((to_map_2 && !done(rank_map, g)) ||
sl@0
    84
         (!to_map_2 && !done(rank_map2, g))) {
sl@0
    85
    typedef typename graph_traits<Graph>::traversal_category category;
sl@0
    86
sl@0
    87
    if (to_map_2) {
sl@0
    88
      detail::page_rank_step(g, rank_map, rank_map2, damping, category());
sl@0
    89
    } else {
sl@0
    90
      detail::page_rank_step(g, rank_map2, rank_map, damping, category());
sl@0
    91
    }
sl@0
    92
    to_map_2 = !to_map_2;
sl@0
    93
  }
sl@0
    94
sl@0
    95
  if (!to_map_2) {
sl@0
    96
    BGL_FORALL_VERTICES_T(v, g, Graph) put(rank_map, v, get(rank_map2, v));
sl@0
    97
  }
sl@0
    98
}
sl@0
    99
sl@0
   100
template<typename Graph, typename RankMap, typename Done>
sl@0
   101
void
sl@0
   102
page_rank(const Graph& g, RankMap rank_map, Done done, 
sl@0
   103
          typename property_traits<RankMap>::value_type damping,
sl@0
   104
          typename graph_traits<Graph>::vertices_size_type n)
sl@0
   105
{
sl@0
   106
  typedef typename property_traits<RankMap>::value_type rank_type;
sl@0
   107
sl@0
   108
  std::vector<rank_type> ranks2(num_vertices(g));
sl@0
   109
  page_rank(g, rank_map, done, damping, n,
sl@0
   110
            make_iterator_property_map(ranks2.begin(), get(vertex_index, g)));
sl@0
   111
}
sl@0
   112
sl@0
   113
template<typename Graph, typename RankMap, typename Done>
sl@0
   114
inline void
sl@0
   115
page_rank(const Graph& g, RankMap rank_map, Done done, 
sl@0
   116
          typename property_traits<RankMap>::value_type damping = 0.85)
sl@0
   117
{
sl@0
   118
  page_rank(g, rank_map, done, damping, num_vertices(g));
sl@0
   119
}
sl@0
   120
sl@0
   121
template<typename Graph, typename RankMap>
sl@0
   122
inline void
sl@0
   123
page_rank(const Graph& g, RankMap rank_map)
sl@0
   124
{
sl@0
   125
  page_rank(g, rank_map, n_iterations(20));
sl@0
   126
}
sl@0
   127
sl@0
   128
// TBD: this could be _much_ more efficient, using a queue to store
sl@0
   129
// the vertices that should be reprocessed and keeping track of which
sl@0
   130
// vertices are in the queue with a property map. Baah, this only
sl@0
   131
// applies when we have a bidirectional graph.
sl@0
   132
template<typename MutableGraph>
sl@0
   133
void
sl@0
   134
remove_dangling_links(MutableGraph& g)
sl@0
   135
{
sl@0
   136
  typename graph_traits<MutableGraph>::vertices_size_type old_n;
sl@0
   137
  do {
sl@0
   138
    old_n = num_vertices(g);
sl@0
   139
sl@0
   140
    typename graph_traits<MutableGraph>::vertex_iterator vi, vi_end;
sl@0
   141
    for (tie(vi, vi_end) = vertices(g); vi != vi_end; /* in loop */) {
sl@0
   142
      typename graph_traits<MutableGraph>::vertex_descriptor v = *vi++;
sl@0
   143
      if (out_degree(v, g) == 0) {
sl@0
   144
        clear_vertex(v, g);
sl@0
   145
        remove_vertex(v, g);
sl@0
   146
      }
sl@0
   147
    }
sl@0
   148
  } while (num_vertices(g) < old_n);
sl@0
   149
}
sl@0
   150
sl@0
   151
} } // end namespace boost::graph
sl@0
   152
sl@0
   153
#endif // BOOST_GRAPH_PAGE_RANK_HPP