Commit 65c9d1a9 authored by Tiago Peixoto's avatar Tiago Peixoto

Small improvements to sfdp_layout()

parent 39089ded
Pipeline #93 failed with stage
...@@ -49,7 +49,7 @@ public: ...@@ -49,7 +49,7 @@ public:
power(_ur[1] - _ll[1], 2)); power(_ur[1] - _ll[1], 2));
} }
QuadTree& get_leaf(size_t i) vector<QuadTree>& get_leafs()
{ {
if (_max_level > 0 && _leafs.empty()) if (_max_level > 0 && _leafs.empty())
{ {
...@@ -65,11 +65,11 @@ public: ...@@ -65,11 +65,11 @@ public:
lll[1] += (_ur[1] - _ll[1]) / 2; lll[1] += (_ur[1] - _ll[1]) / 2;
else else
lur[1] -= (_ur[1] - _ll[1]) / 2; lur[1] -= (_ur[1] - _ll[1]) / 2;
_leafs.push_back(QuadTree(lll, lur, _max_level - 1)); _leafs.emplace_back(lll, lur, _max_level - 1);
} }
} }
return _leafs[i]; return _leafs;
} }
vector<std::tuple<Pos,Weight> >& get_dense_leafs() vector<std::tuple<Pos,Weight> >& get_dense_leafs()
...@@ -85,8 +85,6 @@ public: ...@@ -85,8 +85,6 @@ public:
if (_max_level == 0) if (_max_level == 0)
{ {
if (_count == w)
_dense_leafs.reserve(10);
_dense_leafs.push_back(std::make_tuple(p, w)); _dense_leafs.push_back(std::make_tuple(p, w));
return 1; return 1;
} }
...@@ -95,7 +93,7 @@ public: ...@@ -95,7 +93,7 @@ public:
int i = p[0] > (_ll[0] + (_ur[0] - _ll[0]) / 2); int i = p[0] > (_ll[0] + (_ur[0] - _ll[0]) / 2);
int j = p[1] > (_ll[1] + (_ur[1] - _ll[1]) / 2); int j = p[1] > (_ll[1] + (_ur[1] - _ll[1]) / 2);
size_t sc = (_max_level > 0 && _leafs.empty()) ? 4 : 0; size_t sc = (_max_level > 0 && _leafs.empty()) ? 4 : 0;
return sc + get_leaf(i + 2 * j).put_pos(p, w); return sc + get_leafs()[i + 2 * j].put_pos(p, w);
} }
return 0; return 0;
} }
...@@ -212,38 +210,30 @@ struct get_sfdp_layout ...@@ -212,38 +210,30 @@ struct get_sfdp_layout
typedef typename property_traits<VertexWeightMap>::value_type vweight_t; typedef typename property_traits<VertexWeightMap>::value_type vweight_t;
pos_t ll(2, numeric_limits<val_t>::max()),
ur(2, -numeric_limits<val_t>::max());
vector<pos_t> group_cm; vector<pos_t> group_cm;
vector<vweight_t> group_size; vector<vweight_t> group_size;
vector<size_t> vertices; vector<size_t> vertices;
int i, N = num_vertices(g), HN=0; int HN=0;
for (i = 0; i < N; ++i) for (auto v : vertices_range(g))
{ {
typename graph_traits<Graph>::vertex_descriptor v =
vertex(i, g);
if (v == graph_traits<Graph>::null_vertex())
continue;
if (pin[v] == 0) if (pin[v] == 0)
vertices.push_back(v); vertices.push_back(v);
pos[v].resize(2, 0); pos[v].resize(2, 0);
size_t s = group[v]; if (gamma != 0 || mu != 0)
if (s >= group_cm.size())
{ {
group_cm.resize(s + 1); size_t s = group[v];
group_size.resize(s + 1, 0);
}
group_cm[s].resize(2, 0);
group_size[s] += get(vweight, v);
for (size_t j = 0; j < 2; ++j) if (s >= group_cm.size())
{ {
ll[j] = min(pos[v][j], ll[j]); group_cm.resize(s + 1);
ur[j] = max(pos[v][j], ur[j]); group_size.resize(s + 1, 0);
group_cm[s][j] += pos[v][j] * get(vweight, v); }
group_cm[s].resize(2, 0);
group_size[s] += get(vweight, v);
for (size_t j = 0; j < 2; ++j)
group_cm[s][j] += pos[v][j] * get(vweight, v);
} }
HN++; HN++;
} }
...@@ -269,24 +259,44 @@ struct get_sfdp_layout ...@@ -269,24 +259,44 @@ struct get_sfdp_layout
E0 = E; E0 = E;
E = 0; E = 0;
pos_t nll(2, numeric_limits<val_t>::max()), pos_t ll(2, numeric_limits<val_t>::max()),
nur(2, -numeric_limits<val_t>::max()); ur(2, -numeric_limits<val_t>::max());
for (auto v : vertices_range(g))
{
for (size_t j = 0; j < 2; ++j)
{
ll[j] = min(pos[v][j], ll[j]);
ur[j] = max(pos[v][j], ur[j]);
}
}
QuadTree<pos_t, vweight_t> qt(ll, ur, max_level); if (gamma != 0 || mu != 0)
for (i = 0; i < N; ++i)
{ {
typename graph_traits<Graph>::vertex_descriptor v = for (size_t s = 0; s < group_size.size(); ++s)
vertex(i, g); {
if (v == graph_traits<Graph>::null_vertex()) if (group_size[s] == 0)
continue; continue;
qt.put_pos(pos[v], vweight[v]); group_cm[s] = {0, 0};
}
for (auto v : vertices_range(g))
{
size_t s = group[v];
for (size_t j = 0; j < 2; ++j)
group_cm[s][j] += pos[v][j] * get(vweight, v) /
group_size[s];
}
} }
QuadTree<pos_t, vweight_t> qt(ll, ur, max_level);
for (auto v : vertices_range(g))
qt.put_pos(pos[v], vweight[v]);
std::shuffle(vertices.begin(), vertices.end(), rng); std::shuffle(vertices.begin(), vertices.end(), rng);
size_t nmoves = 0; size_t nmoves = 0;
N = vertices.size(); int i = 0, N = vertices.size();
vector<std::reference_wrapper<QuadTree<pos_t, vweight_t>>> Q; vector<QuadTree<pos_t, vweight_t>*> Q;
#pragma omp parallel for default(shared) private(i, Q) \ #pragma omp parallel for default(shared) private(i, Q) \
reduction(+:E, delta, nmoves) schedule(runtime) if (N > 100) reduction(+:E, delta, nmoves) schedule(runtime) if (N > 100)
for (i = 0; i < N; ++i) for (i = 0; i < N; ++i)
...@@ -296,23 +306,22 @@ struct get_sfdp_layout ...@@ -296,23 +306,22 @@ struct get_sfdp_layout
pos_t diff(2, 0), pos_u(2, 0), ftot(2, 0), cm(2, 0); pos_t diff(2, 0), pos_u(2, 0), ftot(2, 0), cm(2, 0);
// global repulsive forces // global repulsive forces
Q.push_back(std::ref(qt)); Q.push_back(&qt);
while (!Q.empty()) while (!Q.empty())
{ {
auto& q = Q.back().get(); auto& q = *Q.back();
Q.pop_back(); Q.pop_back();
if (q.max_level() == 0) if (q.max_level() == 0)
{ {
auto& dleafs = q.get_dense_leafs(); auto& dleafs = q.get_dense_leafs();
for(size_t j = 0; j < dleafs.size(); ++j) for (auto& dleaf : dleafs)
{ {
val_t d = get_diff(get<0>(dleafs[j]), pos[v], val_t d = get_diff(get<0>(dleaf), pos[v], diff);
diff);
if (d == 0) if (d == 0)
continue; continue;
val_t f = f_r(C, K, p, pos[v], get<0>(dleafs[j])); val_t f = f_r(C, K, p, pos[v], get<0>(dleaf));
f *= get<1>(dleafs[j]) * get(vweight, v); f *= get<1>(dleaf) * get(vweight, v);
for (size_t l = 0; l < 2; ++l) for (size_t l = 0; l < 2; ++l)
ftot[l] += f * diff[l]; ftot[l] += f * diff[l];
} }
...@@ -324,11 +333,10 @@ struct get_sfdp_layout ...@@ -324,11 +333,10 @@ struct get_sfdp_layout
double d = get_diff(cm, pos[v], diff); double d = get_diff(cm, pos[v], diff);
if (w > theta * d) if (w > theta * d)
{ {
for(size_t j = 0; j < 4; ++j) for (auto& leaf : q.get_leafs())
{ {
auto& leaf = q.get_leaf(j);
if (leaf.get_count() > 0) if (leaf.get_count() > 0)
Q.push_back(std::ref(leaf)); Q.push_back(&leaf);
} }
} }
else else
...@@ -345,17 +353,15 @@ struct get_sfdp_layout ...@@ -345,17 +353,15 @@ struct get_sfdp_layout
} }
// local attractive forces // local attractive forces
auto& pos_v = pos[v];
for (auto e : out_edges_range(v, g)) for (auto e : out_edges_range(v, g))
{ {
auto u = target(e, g); auto u = target(e, g);
if (u == v) if (u == v)
continue; continue;
#pragma omp critical pos_u = pos[u];
{ get_diff(pos_u, pos_v, diff);
pos_u = pos[u]; val_t f = f_a(K, pos_u, pos_v);
}
get_diff(pos_u, pos[v], diff);
val_t f = f_a(K, pos_u, pos[v]);
f *= get(eweight, e) * get(vweight, u) * get(vweight, v); f *= get(eweight, e) * get(vweight, u) * get(vweight, v);
for (size_t l = 0; l < 2; ++l) for (size_t l = 0; l < 2; ++l)
ftot[l] += f * diff[l]; ftot[l] += f * diff[l];
...@@ -401,7 +407,7 @@ struct get_sfdp_layout ...@@ -401,7 +407,7 @@ struct get_sfdp_layout
} }
// intra-group attractive forces // intra-group attractive forces
if (group_size[group[v]] > 1 && mu > 0) if (mu > 0 && group_size[group[v]] > 1)
{ {
val_t d = get_diff(group_cm[group[v]], pos[v], diff); val_t d = get_diff(group_cm[group[v]], pos[v], diff);
if (d > 0) if (d > 0)
...@@ -416,29 +422,16 @@ struct get_sfdp_layout ...@@ -416,29 +422,16 @@ struct get_sfdp_layout
E += power(norm(ftot), 2); E += power(norm(ftot), 2);
#pragma omp critical for (size_t l = 0; l < 2; ++l)
{ {
for (size_t l = 0; l < 2; ++l) ftot[l] *= step;
{ pos[v][l] += ftot[l];
group_cm[group[v]][l] *= group_size[group[v]];
group_cm[group[v]][l] -= pos[v][l];
ftot[l] *= step;
pos[v][l] += ftot[l];
nll[l] = min(pos[v][l], nll[l]);
nur[l] = max(pos[v][l], nur[l]);
group_cm[group[v]][l] += pos[v][l];
group_cm[group[v]][l] /= group_size[group[v]];
}
} }
delta += norm(ftot); delta += norm(ftot);
nmoves++; nmoves++;
} }
n_iter++; n_iter++;
ll = nll;
ur = nur;
delta /= nmoves; delta /= nmoves;
if (verbose) if (verbose)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment