forked from aepasto/triest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TriangleCounter.h
121 lines (91 loc) · 3.07 KB
/
TriangleCounter.h
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#ifndef TRIANGLE_COUNTER_H_
#define TRIANGLE_COUNTER_H_
#include "GraphScheduler.h"
#include "UDynGraph.h"
// hashing pairs
namespace std {
template <> struct hash<std::pair<int, int>> {
inline size_t operator()(const std::pair<int, int> &v) const {
std::hash<int> int_hasher;
return int_hasher(v.first) ^ int_hasher(v.second);
}
};
}
using namespace std;
// For each edge update:
// 1) call new_update
// 2) if the edge need to be added the sample call add_edge
// or if need to be removed remove_edge
// NEW_UPDATE ASSUMES: all edges added are not present (in the original graph) and all removed are present (in the original graph)
// remove_edge assumes that the edge was in the sample.
// Not crucial can be eliminated used only for speedup
#define MAX_NUM_NODES 50000000
unsigned long long edge_to_id(const int u,
const int v);
class TriangleCounter {
public:
TriangleCounter(bool local);
virtual ~TriangleCounter();
void clear();
// Add or remove edge from sample (no other operation executed)
bool add_edge_sample(const int u, const int v);
bool remove_edge_sample(const int u, const int v);
// Increments the counters of seen edges
void new_update(const EdgeUpdate& update);
// Increase or decrease the triangles (notice the sample is not affected)
void add_triangles(const int u, const int v, double weight);
void remove_triangles(const int u, const int v, double weight);
unsigned long long int edges_present_original() const;
inline unsigned long long int triangles() const{
return triangles_;
}
inline double triangles_weight() const{
return triangles_weight_;
}
inline unsigned long long int triangles_local(int n) const{
if (triangles_local_map_.find(n)==triangles_local_map_.end()){
return 0;
} else {
return triangles_local_map_.at(n);
}
}
inline double triangles_weight_local(int n) const{
if (triangles_weight_local_map_.find(n)==triangles_weight_local_map_.end()){
return 0.0;
} else {
return triangles_weight_local_map_.at(n);
}
}
inline int size_sample() const {
return graph_.num_edges();
}
inline bool is_local() const {
return local_;
}
void add_edge_weight(const int u, const int v, const double w){
edge_weight_[make_pair(u,v)] = w;
edge_weight_[make_pair(v,u)] = w;
}
void remove_edge_weight(const int u, const int v) {
edge_weight_.erase(make_pair(u,v));
edge_weight_.erase(make_pair(v,u));
}
void get_nodes(vector<int>*nodes_v){
nodes_v->clear();
graph_.nodes(nodes_v);
}
private:
bool local_;
int common_neighbors(const int u, const int v) const;
UDynGraph graph_;
unordered_set<unsigned long long> set_edge_ids_;//used for fast lookup of x,y edge
unsigned long long int triangles_;
double triangles_weight_;
unordered_map<int, unsigned long long> triangles_local_map_;
unordered_map<int, double> triangles_weight_local_map_;
unsigned long long int edges_present_original_; // count of current edges in
//the original graph (not in the sampled graph).
// used only for add/rem reservoir
unordered_map<pair<int,int>, double> edge_weight_;
};
#endif /* TRIANGLE_COUNTER_H_ */