Commit b11d52fd authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

improved correlated vertex sampling

git-svn-id: https://svn.forked.de/graph-tool/trunk@12 d4600afd-f417-0410-95de-beed9576f240
parent 6855de1e
...@@ -123,14 +123,43 @@ public: ...@@ -123,14 +123,43 @@ public:
_cj = pow(max_j+1,1.0/(_L-1)) - 1.0; _cj = pow(max_j+1,1.0/(_L-1)) - 1.0;
_ck = pow(max_k+1,1.0/(_L-1)) - 1.0; _ck = pow(max_k+1,1.0/(_L-1)) - 1.0;
_avg_deg = avg_deg; _avg_deg = avg_deg;
_nearest_bins = base_t(_L, vector<vector<pair<size_t,size_t> > >(_L));
_size = 0;
} }
void insert(const pair<size_t, size_t>& v) void insert(const pair<size_t, size_t>& v)
{ {
size_t j_bin, k_bin; size_t j_bin, k_bin;
tie(j_bin, k_bin) = get_bin(v.first, v.second); tie(j_bin, k_bin) = get_bin(v.first, v.second);
if ((*this)[j_bin][k_bin].empty())
_size++;
(*this)[j_bin][k_bin].push_back(v); (*this)[j_bin][k_bin].push_back(v);
}
void arrange_proximity()
{
for(size_t j = 0; j < _L; ++j)
for(size_t k = 0; k < _L; ++k)
{
_nearest_bins[j][k].clear();
if ((*this)[j][k].empty())
{
for(size_t w = 1; w < _L; ++w)
{
for (size_t i = ((j>w)?j-w:0); i < ((j+w<=_L)?j+w:_L); ++i)
for (size_t l = ((k>w)?k-w:0); l < ((k+w<=_L)?k+w:_L); ++l)
{
if (!(*this)[i][l].empty())
_nearest_bins[j][k].push_back(make_pair(i,l));
}
if (!_nearest_bins[j][k].empty())
break;
}
} }
}
}
void erase(const pair<size_t,size_t>& v) void erase(const pair<size_t,size_t>& v)
{ {
...@@ -144,19 +173,43 @@ public: ...@@ -144,19 +173,43 @@ public:
break; break;
} }
} }
if ((*this)[j_bin][k_bin].empty())
{
_size--;
if (_size > _L)
arrange_proximity();
}
} }
pair<pair<size_t,size_t>, bool> find_closest(size_t j, size_t k, rng_t& rng) pair<size_t,size_t> find_closest(size_t j, size_t k, rng_t& rng)
{ {
vector<pair<size_t,size_t> > candidates; vector<pair<size_t,size_t> > candidates;
size_t j_bin, k_bin; size_t j_bin, k_bin;
tie(j_bin, k_bin) = get_bin(j, k); tie(j_bin, k_bin) = get_bin(j, k);
if (!(*this)[j_bin][k_bin].empty()) if ((*this)[j_bin][k_bin].empty())
candidates.push_back(*(*this)[j_bin][k_bin].begin()); {
if (_size > _L)
{
if (_nearest_bins[j_bin][k_bin].empty())
arrange_proximity();
for(size_t i = 0; i < _nearest_bins[j_bin][k_bin].size(); ++i)
{
size_t jb,kb;
tie(jb,kb) = _nearest_bins[j_bin][k_bin][i];
search_bin(jb, kb, j, k, candidates);
}
}
else else
return make_pair(make_pair(j,k), false); {
for(size_t jb = 0; jb < _L; ++jb)
for(size_t kb = 0; kb < _L; ++kb)
search_bin(jb, kb, j, k, candidates);
}
}
else
{
search_bin(j_bin, k_bin, j, k, candidates); search_bin(j_bin, k_bin, j, k, candidates);
size_t distance = size_t(sqrt(dist(candidates.front(), vertex_t(j,k)))); size_t distance = size_t(sqrt(dist(candidates.front(), vertex_t(j,k))));
...@@ -170,9 +223,10 @@ public: ...@@ -170,9 +223,10 @@ public:
continue; continue;
search_bin(jb, kb, j, k, candidates); search_bin(jb, kb, j, k, candidates);
} }
}
uniform_int<size_t> sample(0, candidates.size() - 1); uniform_int<size_t> sample(0, candidates.size() - 1);
return make_pair(candidates[sample(rng)], true); return candidates[sample(rng)];
} }
private: private:
...@@ -195,6 +249,12 @@ private: ...@@ -195,6 +249,12 @@ private:
void search_bin(size_t j_bin, size_t k_bin, size_t j, size_t k, vector<pair<size_t,size_t> >& candidates) void search_bin(size_t j_bin, size_t k_bin, size_t j, size_t k, vector<pair<size_t,size_t> >& candidates)
{ {
for (typeof((*this)[j_bin][k_bin].begin()) iter = (*this)[j_bin][k_bin].begin(); iter != (*this)[j_bin][k_bin].end(); ++iter) for (typeof((*this)[j_bin][k_bin].begin()) iter = (*this)[j_bin][k_bin].begin(); iter != (*this)[j_bin][k_bin].end(); ++iter)
{
if (candidates.empty())
{
candidates.push_back(*iter);
continue;
}
if (dist(vertex_t(*iter), vertex_t(j,k)) < dist(vertex_t(candidates.front()),vertex_t(j,k))) if (dist(vertex_t(*iter), vertex_t(j,k)) < dist(vertex_t(candidates.front()),vertex_t(j,k)))
{ {
candidates.clear(); candidates.clear();
...@@ -205,11 +265,14 @@ private: ...@@ -205,11 +265,14 @@ private:
candidates.push_back(*iter); candidates.push_back(*iter);
} }
} }
}
size_t _L; size_t _L;
double _cj; double _cj;
double _ck; double _ck;
size_t _avg_deg; size_t _avg_deg;
base_t _nearest_bins;
size_t _size;
}; };
//============================================================================== //==============================================================================
...@@ -338,11 +401,6 @@ void GraphInterface::GenerateCorrelatedConfigurationalModel(size_t N, pjk_t pjk, ...@@ -338,11 +401,6 @@ void GraphInterface::GenerateCorrelatedConfigurationalModel(size_t N, pjk_t pjk,
inv_ceil_t inv_ceil = lambda::bind(inv_ceil_corr,lambda::_1,lambda::_2,j,k); inv_ceil_t inv_ceil = lambda::bind(inv_ceil_corr,lambda::_1,lambda::_2,j,k);
sample_from_distribution<pjk_t, pjk_t, inv_ceil_t> corr_sample(prob_func, ceil, inv_ceil, ceil_corr_bound, rng); sample_from_distribution<pjk_t, pjk_t, inv_ceil_t> corr_sample(prob_func, ceil, inv_ceil, ceil_corr_bound, rng);
size_t misses = 0;
bool accept = false;
while(!accept)
{
accept = true;
size_t jl,kl; size_t jl,kl;
tie(jl,kl) = corr_sample(); // target (j,k) tie(jl,kl) = corr_sample(); // target (j,k)
...@@ -391,31 +449,11 @@ void GraphInterface::GenerateCorrelatedConfigurationalModel(size_t N, pjk_t pjk, ...@@ -391,31 +449,11 @@ void GraphInterface::GenerateCorrelatedConfigurationalModel(size_t N, pjk_t pjk,
else else
{ {
// select the (j,k) which is the closest in the j,k plane. // select the (j,k) which is the closest in the j,k plane.
tie(deg, accept) = degree_matrix.find_closest(jl, kl, rng); deg = degree_matrix.find_closest(jl, kl, rng);
if (!accept)
++misses;
else
target = targets.find(deg)->second; target = targets.find(deg)->second;
if(misses > target_degrees.size()) // cerr << "wanted: " << jl << ", " << kl
{ // << " got: " << deg.first << ", " << deg.second << "\n";
// if one close can't be found after some time, just get the closest in the entire graph
vector<pair<size_t,size_t> > candidates;
candidates.push_back(*target_degrees.begin());
for(iter = target_degrees.begin(); iter != target_degrees.end(); ++iter)
if (dist(vertex_t(*iter), vertex_t(make_pair(jl,kl))) < dist(vertex_t(candidates.front()), vertex_t(make_pair(jl,kl))))
{
candidates.clear();
candidates.push_back(*iter);
}
else if (dist(vertex_t(*iter), vertex_t(make_pair(jl,kl))) == dist(vertex_t(candidates.front()), vertex_t(make_pair(jl,kl))))
{
candidates.push_back(*iter);
}
uniform_int<size_t> sample(0, candidates.size() - 1);
target = targets.find(candidates[sample(rng)])->second;
accept = true;
}
}
} }
} }
...@@ -474,7 +512,7 @@ void GraphInterface::GenerateCorrelatedConfigurationalModel(size_t N, pjk_t pjk, ...@@ -474,7 +512,7 @@ void GraphInterface::GenerateCorrelatedConfigurationalModel(size_t N, pjk_t pjk,
for (size_t j = 0; j < str.str().length(); ++j) for (size_t j = 0; j < str.str().length(); ++j)
cout << "\b"; cout << "\b";
str.str(""); str.str("");
str << (i+1) << " of " << E << " (" << (i+1)*100/E << "%, misses: " << misses << ")"; str << (i+1) << " of " << E << " (" << (i+1)*100/E << "%)";
cout << str.str() << flush; cout << str.str() << flush;
} }
......
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