#pragma once #include "graph.hpp" #include #include // Its assumed that u,v are distinct. // Check if all four vertices are distinct bool edgeConflicts(const Edge& e1, const Edge& e2) { return (e1.u == e2.u || e1.u == e2.v || e1.v == e2.u || e1.v == e2.v); } class SwitchChain { public: SwitchChain() : mt(std::random_device{}()), permutationDistribution(0.5) // permutationDistribution(0, 2) { // random_device uses hardware entropy if available // std::random_device rd; // mt.seed(rd()); } ~SwitchChain() {} bool initialize(const Graph& gstart) { if (gstart.edgeCount() == 0) return false; g = gstart; edgeDistribution.param( std::uniform_int_distribution<>::param_type(0, g.edgeCount() - 1)); return true; } bool doMove() { int e1index, e2index; int timeout = 0; // Keep regenerating while conflicting edges do { e1index = edgeDistribution(mt); e2index = edgeDistribution(mt); if (++timeout % 100 == 0) { std::cerr << "Warning: sampled " << timeout << " random edges but they keep conflicting.\n"; } } while (edgeConflicts(g.getEdge(e1index), g.getEdge(e2index))); // Consider one of the three possible permutations // 1) e1.u - e1.v and e2.u - e2.v (original) // 2) e1.u - e2.u and e1.v - e2.v // 3) e1.u - e2.v and e1.v - e2.u bool switchType = permutationDistribution(mt); return g.exchangeEdges(e1index, e2index, switchType); } Graph g; std::mt19937 mt; std::uniform_int_distribution<> edgeDistribution; //std::uniform_int_distribution<> permutationDistribution; std::bernoulli_distribution permutationDistribution; };