File: kcore.hh

package info (click to toggle)
graph-tool 2.98%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 29,324 kB
  • sloc: cpp: 87,937; python: 31,476; makefile: 952; xml: 101; sh: 42
file content (66 lines) | stat: -rw-r--r-- 2,140 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "graph_tool.hh"

using namespace graph_tool;
using namespace boost;
using namespace std;

// This template function takes a graph 'g' and a vertex property map 'core_map'
// where the core values will be stored. Their exact types are unspecified at
// this point.

template <typename Graph, typename CoreMap>
void kcore_decomposition(Graph& g, CoreMap core_map)
{
    // Create some auxiliary property maps
    typedef typename vprop_map_t<size_t>::unchecked_t vmap_t;

    vmap_t deg(num_vertices(g));  // Remaining degree
    vmap_t pos(num_vertices(g));  // Position in bin (core)

    typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;

    vector<vector<vertex_t>> bins; // Each bin stores the set of vertices of a
                                   // core

    // Put each vertex to the bin corresponding to its degree
    for (auto v : vertices_range(g))
    {
        size_t k = out_degree(v, g);
        deg[v] = k;
        if (k >= bins.size())
            bins.resize(k + 1);
        bins[k].push_back(v);
        pos[v] = bins[k].size() - 1;
    }

    // Proceed from smallest bin to largest. For each vertex in bin, check the
    // neighbours; if any of them have a larger remaining degree, reduce it by
    // one, and put it in the correct bin.
    for (size_t k = 0; k < bins.size(); ++k)
    {
        auto& bins_k = bins[k];
        while (!bins_k.empty())
        {
            auto v = bins_k.back();
            bins_k.pop_back();
            core_map[v] = k;
            for (auto e : out_edges_range(v, g))
            {
                auto u = target(e, g);
                auto& ku = deg[u];
                if (ku > deg[v])
                {
                    auto& bins_ku = bins[ku];
                    auto w = bins_ku.back();
                    auto pos_w = pos[w] = pos[u];
                    bins_ku[pos_w] = w;
                    bins_ku.pop_back();
                    auto& bins_ku_m = bins[ku - 1];
                    bins_ku_m.push_back(u);
                    pos[u] = bins_ku_m.size() - 1;
                    --ku;
                }
            }
        }
    }
}