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:
_cj = pow(max_j+1,1.0/(_L-1)) - 1.0;
_ck = pow(max_k+1,1.0/(_L-1)) - 1.0;
_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)
{
size_t j_bin, k_bin;
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);
}
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)
{
......@@ -144,19 +173,43 @@ public:
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;
size_t j_bin, k_bin;
tie(j_bin, k_bin) = get_bin(j, k);
if (!(*this)[j_bin][k_bin].empty())
candidates.push_back(*(*this)[j_bin][k_bin].begin());
if ((*this)[j_bin][k_bin].empty())
{
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
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);
size_t distance = size_t(sqrt(dist(candidates.front(), vertex_t(j,k))));
......@@ -170,9 +223,10 @@ public:
continue;
search_bin(jb, kb, j, k, candidates);
}
}
uniform_int<size_t> sample(0, candidates.size() - 1);
return make_pair(candidates[sample(rng)], true);
return candidates[sample(rng)];
}
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)
{
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)))
{
candidates.clear();
......@@ -205,11 +265,14 @@ private:
candidates.push_back(*iter);
}
}
}
size_t _L;
double _cj;
double _ck;
size_t _avg_deg;
base_t _nearest_bins;
size_t _size;
};
//==============================================================================
......@@ -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);
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;
tie(jl,kl) = corr_sample(); // target (j,k)
......@@ -391,31 +449,11 @@ void GraphInterface::GenerateCorrelatedConfigurationalModel(size_t N, pjk_t pjk,
else
{
// select the (j,k) which is the closest in the j,k plane.
tie(deg, accept) = degree_matrix.find_closest(jl, kl, rng);
if (!accept)
++misses;
else
deg = degree_matrix.find_closest(jl, kl, rng);
target = targets.find(deg)->second;
if(misses > target_degrees.size())
{
// 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;
}
}
// cerr << "wanted: " << jl << ", " << kl
// << " got: " << deg.first << ", " << deg.second << "\n";
}
}
......@@ -474,7 +512,7 @@ void GraphInterface::GenerateCorrelatedConfigurationalModel(size_t N, pjk_t pjk,
for (size_t j = 0; j < str.str().length(); ++j)
cout << "\b";
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;
}
......
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