Files
@ a410aaa16af7
Branch filter:
Location: AENC/switchchain/cpp/switchchain_mixingtime.cpp
a410aaa16af7
4.2 KiB
text/x-c++src
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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | #include "exports.hpp"
#include "graph.hpp"
#include "graph_powerlaw.hpp"
#include "switchchain.hpp"
#include <algorithm>
#include <array>
#include <fstream>
#include <iostream>
#include <numeric>
#include <random>
#include <vector>
int main(int argc, char* argv[]) {
// Generate a random degree sequence
std::mt19937 rng(std::random_device{}());
// Goal:
// Degrees follow a power-law distribution with some parameter tau
// Expect: #tri = const * n^{ something }
// The goal is to find the 'something' by finding the number of triangles
// for different values of n and tau
//float tauValues[] = {2.5f};
float tauValues[] = {2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f};
Graph g;
Graph g1;
Graph g2;
std::ofstream outfile;
if (argc >= 2)
outfile.open(argv[1]);
else
outfile.open("graphdata_etmt.m");
if (!outfile.is_open()) {
std::cout << "ERROR: Could not open output file.\n";
return 1;
}
outfile << '{';
bool outputComma = false;
for (int numVertices = 100; numVertices <= 1000; numVertices += 100) {
for (float tau : tauValues) {
// For a single n,tau take samples over several instances of
// the degree distribution.
for (int degreeSample = 0; degreeSample < 200; ++degreeSample) {
DegreeSequence ds;
generatePowerlawGraph(numVertices, tau, g, ds, rng);
// Multiple runs from the same degree sequence
for (int i = 0; i < 5; ++i) {
SwitchChain chain;
if (!chain.initialize(g)) {
std::cerr << "Could not initialize Markov chain.\n";
return 1;
}
std::cout << "Running n = " << numVertices << ", tau = " << tau
<< ". \t" << std::flush;
//int mixingTime = (32.0f - 26.0f*(tau - 2.0f)) * numVertices; //40000;
//constexpr int measurements = 50;
//constexpr int measureSkip =
// 200; // Take a sample every ... steps
int mixingTime = 0;
constexpr int measurements = 50000;
constexpr int measureSkip = 1;
int movesTotal = 0;
int movesSuccess = 0;
int triangles[measurements];
for (int i = 0; i < mixingTime; ++i) {
++movesTotal;
if (chain.doMove()) {
++movesSuccess;
}
}
for (int i = 0; i < measurements; ++i) {
for (int j = 0; j < measureSkip; ++j) {
++movesTotal;
if (chain.doMove()) {
++movesSuccess;
}
}
triangles[i] = chain.g.countTriangles();
}
std::cout << '('
<< 100.0f * float(movesSuccess) / float(movesTotal)
<< "% successrate). " << std::flush;
// std::cout << std::endl;
// Take the average over the last 20%
auto trianglesTotal = 0uL;
auto count = 0u;
for (int i = measurements - (measurements / 5); i < measurements; ++i) {
trianglesTotal += triangles[i];
count++;
}
double trianglesAvg = double(trianglesTotal)/double(count);
// Find the ETMT
int ETMT = 0;
for (int i = 0; i < measurements; ++i) {
if (triangles[i] < trianglesAvg) {
ETMT = i;
break;
}
}
if (outputComma)
outfile << ',' << '\n';
outputComma = true;
std::sort(ds.begin(), ds.end());
outfile << '{' << '{' << numVertices << ',' << tau << '}';
outfile << ',' << ETMT;
outfile << '}' << std::flush;
std::cout << std::endl;
}
}
}
}
outfile << '}';
return 0;
}
|