-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgeneral_cascade.hpp
More file actions
66 lines (60 loc) · 2.12 KB
/
Copy pathgeneral_cascade.hpp
File metadata and controls
66 lines (60 loc) · 2.12 KB
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
#pragma once
#include <random>
#include "graph.hpp"
#include "parlay/sequence.h"
#include "utilities.h"
using namespace std;
struct GeneralCascade {
GeneralCascade(Graph* graph) : graph(graph) {}
double Run(const parlay::sequence<NodeId>& seeds, int num_iter, bool random = false) {
auto Simulate = [&]() -> double {
parlay::sequence<bool> activated(graph->n, false);
int num = 0;
auto frontier = seeds;
if (random) {
auto k = seeds.size();
frontier.clear();
while (frontier.size() < k) {
NodeId t = rand() % graph->n;
if (std::find(frontier.begin(), frontier.end(), t) == frontier.end()) {
frontier.push_back(t);
}
}
}
while (!frontier.empty()) {
parlay::parallel_for(0, frontier.size(), [&](int i) {
assert(!activated[frontier[i]]);
activated[frontier[i]] = true;
});
num += frontier.size();
parlay::sequence<parlay::sequence<NodeId>> new_nodes(frontier.size());
parlay::parallel_for(0, frontier.size(), [&](int i) {
auto u = frontier[i];
auto nghs = parlay::delayed_tabulate(
graph->offset[u + 1] - graph->offset[u], [&](int j) {
auto offset = graph->offset[u] + j;
return make_pair(graph->E[offset], graph->W[offset]);
});
auto good_nghs = parlay::filter(nghs, [&](pair<NodeId, float> p) {
auto v = p.first;
auto w = p.second;
auto t = (double)rand() / (double)RAND_MAX;
return !activated[v] && t < w;
});
new_nodes[i] = parlay::map(
good_nghs, [](pair<NodeId, float> p) { return p.first; });
});
auto all = parlay::flatten(new_nodes);
parlay::sort_inplace(all);
auto new_frontier = parlay::unique(all);
frontier = new_frontier;
}
return num;
};
parlay::sequence<double> res(num_iter);
parlay::parallel_for(0, num_iter, [&](int i) { res[i] = Simulate(); });
auto tot = parlay::reduce(res);
return tot / num_iter;
}
Graph* graph;
};