-
Notifications
You must be signed in to change notification settings - Fork 2
/
DynDSAlg.cpp
120 lines (94 loc) · 2.62 KB
/
DynDSAlg.cpp
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
/*
* DynDSAlg.cpp
*
* Created on: Oct 15, 2014
* Author: aepasto
*/
#include "DynDSAlg.h"
#include "DynGraphUtils.h"
#include <stack>
#include <cmath>
DynDSAdd::DynDSAdd(const double epsilon) :
EPS_ERR(0.01), epsilon_(epsilon), beta_(0.25 / (1.0 + epsilon)), edges_densest_subgraph_(
0) {
}
DynDSAdd::~DynDSAdd() {
}
bool DynDSAdd::add_edge(const int u, const int v) {
bool new_add = graph_.add_edge(u, v);
if (!new_add) {
return false;
}
if (densest_subgraph_set_.find(u) != densest_subgraph_set_.end()
&& densest_subgraph_set_.find(v) != densest_subgraph_set_.end()) {
++edges_densest_subgraph_;
}
if (level_map_.find(u) == level_map_.end()) {
level_map_[u] = 1;
}
if (level_map_.find(v) == level_map_.end()) {
level_map_[v] = 1;
}
int min_node, max_node;
if (level_map_[u] < level_map_[v]
|| (level_map_[u] == level_map_[v]
&& orientation_.in_degree(u) <= orientation_.in_degree(v))) {
min_node = u;
max_node = v;
} else {
min_node = v;
max_node = u;
}
orientation_.add_edge(max_node, min_node);
Check(min_node);
return true;
}
void DynDSAdd::Construct() {
DSResult result;
Incremental(graph_, beta_, epsilon_, densest_subgraph_set_.begin(),
densest_subgraph_set_.end(), &result, &level_map_, &orientation_);
densest_subgraph_set_.clear();
densest_subgraph_set_.insert(result.subgraph.begin(),
result.subgraph.end());
pair<int, unsigned long long> nodes_edges_pair =
num_nodes_and_edges_induced(graph_, densest_subgraph_set_.begin(),
densest_subgraph_set_.end());
edges_densest_subgraph_ = nodes_edges_pair.second;
beta_ = result.density * (1 + epsilon_);
}
void DynDSAdd::Check(int first_node) {
stack<int> to_check;
to_check.push(first_node);
double threshold = 2.0 * beta_ * (1.0 + epsilon_);
int max_iter_num = max_iter(graph_.num_nodes(), epsilon_);
while (!to_check.empty()) {
int node = to_check.top();
to_check.pop();
int curr_deg = orientation_.in_degree(node);
if (curr_deg < threshold) {
continue;
}
if (level_map_[node] >= max_iter_num) {
Construct();
return;
}
int edges_to_reverse = ceil(curr_deg - threshold);
vector<int> in_neighbors;
orientation_.in_neighbors(node, &in_neighbors);
for (vector<int>::iterator it = in_neighbors.begin();
it != in_neighbors.end(); ++it) {
int in_neighbor = *it;
if (level_map_[in_neighbor] == level_map_[node]) {
orientation_.remove_edge(in_neighbor, node);
orientation_.add_edge(node, in_neighbor);
--edges_to_reverse;
to_check.push(in_neighbor);
if (edges_to_reverse == 0) {
break;
}
}
}
++level_map_[node];
to_check.push(node);
}
}