Files
@ a410aaa16af7
Branch filter:
Location: AENC/switchchain/cpp/graph_gcm.hpp - annotation
a410aaa16af7
4.1 KiB
text/x-c++hdr
Remove spectrum computation from canonical switchchain
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 | 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 32c10aa21482 | #include "graph.hpp"
#include <algorithm>
#include <iostream>
#include <random>
#include <vector>
//
// Assumes degree sequence does NOT contain any zeroes!
//
// method2 = true -> take highest degree and finish its pairing completely
// method2 = false -> take new highest degree after every pairing
template <typename RNG>
bool greedyConfigurationModel(DegreeSequence& ds, Graph& g, RNG& rng, bool method2) {
// Similar to Havel-Hakimi but instead of pairing up with the highest ones
// that remain, simply pair up with random ones
unsigned int n = ds.size();
// degree, vertex index
std::vector<std::pair<unsigned int, unsigned int>> degrees(n);
for (unsigned int i = 0; i < n; ++i) {
degrees[i].first = ds[i];
degrees[i].second = i;
}
std::vector<decltype(degrees.begin())> available;
available.reserve(n);
// Clear the graph
g.reset(n);
while (!degrees.empty()) {
std::shuffle(degrees.begin(), degrees.end(), rng);
// Get the highest degree:
// If there are multiple highest ones, we pick a random one,
// ensured by the shuffle.
// The shuffle is needed anyway for the remaining part
unsigned int dmax = 0;
auto uIter = degrees.begin();
for (auto iter = degrees.begin(); iter != degrees.end(); ++iter) {
if (iter->first >= dmax) {
dmax = iter->first;
uIter = iter;
}
}
if (dmax > degrees.size() - 1)
return false;
if (dmax == 0) {
std::cerr << "ERROR 1 in GCM.\n";
}
unsigned int u = uIter->second;
if (method2) {
// Take the highest degree out of the vector
degrees.erase(uIter);
// Now assign randomly to the remaining vertices
// Since its shuffled, we can pick the first 'dmax' ones
auto vIter = degrees.begin();
while (dmax--) {
if (vIter->first == 0)
std::cerr << "ERROR in GCM2.\n";
if (!g.addEdge({u, vIter->second}))
std::cerr << "ERROR. Could not add edge in GCM2.\n";
vIter->first--;
if (vIter->first == 0)
vIter = degrees.erase(vIter);
else
vIter++;
}
} else {
// Pair with a random vertex that is not u itself and to which
// u has not paired yet!
available.clear();
for (auto iter = degrees.begin(); iter != degrees.end(); ++iter) {
if (iter->second != u && !g.hasEdge({u, iter->second}))
available.push_back(iter);
}
if (available.empty())
return false;
std::uniform_int_distribution<> distr(0, available.size() - 1);
auto vIter = available[distr(rng)];
// pair u to v
if (vIter->first == 0)
std::cerr << "ERROR 2 in GCM1.\n";
if (!g.addEdge({u, vIter->second}))
std::cerr << "ERROR. Could not add edge in GCM1.\n";
// Purge anything with degree zero
// Be careful with invalidating the other iterator!
// Degree of u is always greater or equal to the degree of v
if (dmax == 1) {
// Remove both
// Erasure invalidates all iterators AFTER the erased one
if (vIter > uIter) {
degrees.erase(vIter);
degrees.erase(uIter);
} else {
degrees.erase(uIter);
degrees.erase(vIter);
}
} else {
// Remove only v if it reaches zero
uIter->first--;
vIter->first--;
if (vIter->first == 0)
degrees.erase(vIter);
}
//degrees.erase(std::remove_if(degrees.begin(), degrees.end(),
// [](auto x) { return x.first == 0; }));
}
}
return true;
}
|