diff options
author | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2022-09-14 10:29:35 +0200 |
---|---|---|
committer | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2022-09-14 10:29:35 +0200 |
commit | 6672459cfc7fe5dc285b3ef43df159f9a6ca4ed1 (patch) | |
tree | d6ef68193ed84f6d1f2e4de1e2e951df57874430 | |
parent | 42c2ccd11ba20a1ae396b6d64caaef68d8506ca0 (diff) | |
download | code-6672459cfc7fe5dc285b3ef43df159f9a6ca4ed1.tar.gz code-6672459cfc7fe5dc285b3ef43df159f9a6ca4ed1.tar.bz2 code-6672459cfc7fe5dc285b3ef43df159f9a6ca4ed1.zip |
Some simplifying refactoring.
-rw-r--r-- | rbmp.cpp | 136 |
1 files changed, 74 insertions, 62 deletions
@@ -14,28 +14,32 @@ using Rng = randutils::random_generator<pcg32>; class HalfEdge; class Vertex { -private: - unsigned index; - public: - std::vector<HalfEdge*> neighbors; + unsigned index; + std::vector<std::reference_wrapper<HalfEdge>> neighbors; + std::array<unsigned, 2> coordinate; - void setIndex(unsigned i) {index = i;} - unsigned getIndex() const {return index;} void addEdge(HalfEdge& e) { - neighbors.push_back(&e); + neighbors.push_back(e); } }; +class Edge; + class HalfEdge { private: Vertex* tail; Vertex* head; public: + const Edge& edge; double oldX; double X; - double weight; + + HalfEdge(const Edge& e) : edge(e) { + X = 0; + oldX = X; + } void setVertices(Vertex& vt, Vertex& vh) { tail = &vt; head = &vh; @@ -54,78 +58,86 @@ public: } }; -class BipartiteGraph { +class Edge { +public: + std::array<HalfEdge, 2> halfedges; + double weight; + + Edge() : halfedges{*this, *this} {}; + void setVertices(Vertex& vt, Vertex& vh) { + halfedges[0].setVertices(vt, vh); + halfedges[1].setVertices(vh, vt); + vt.addEdge(halfedges[0]); + vh.addEdge(halfedges[1]); + } + double belief() const { + return halfedges[0].X + halfedges[1].X; + } + bool active() const { + return belief() >= 0; + } +}; + +class Graph { public: - std::vector<Vertex> redVertices; - std::vector<Vertex> blueVertices; - std::vector<HalfEdge> redEdges; - std::vector<HalfEdge> blueEdges; - - BipartiteGraph(unsigned n, Rng& r) : redVertices(n * (n + 1)), blueVertices(n * (n + 1)), redEdges(pow(2 * n, 2)), blueEdges(pow(2 * n, 2)) { - for (unsigned i = 0; i < redVertices.size(); i++) { - redVertices[i].setIndex(i); - blueVertices[i].setIndex(i); + std::vector<Vertex> vertices; + std::vector<Edge> edges; + + Graph(unsigned n, Rng& r) : vertices(2 * n * (n + 1)), edges(pow(2 * n, 2)) { + for (unsigned i = 0; i < vertices.size() / 2; i++) { + vertices[i].index = i; + vertices[i].coordinate = {2 * (i % (n + 1)), 2 * (i / (n + 1)) + 1}; + vertices[vertices.size() / 2 + i].index = i + vertices.size() / 2; + vertices[vertices.size() / 2 + i].coordinate = {2 * (i % n) + 1, 2 * (i / n)}; } - for (unsigned i = 0; i < redEdges.size(); i++) { - Vertex& blueVertex = blueVertices[(i % (2 * n)) / 2 + n * (((i + 2*n) / 4) / n)]; - Vertex& redVertex = redVertices[(1+(i % (2 * n))) / 2 + (n + 1) * ((i / 4) / (n))]; - redEdges[i].setVertices(redVertex, blueVertex); - blueEdges[i].setVertices(blueVertex, redVertex); - redVertex.addEdge(redEdges[i]); - blueVertex.addEdge(blueEdges[i]); - redEdges[i].X = 0; - blueEdges[i].X = 0; - redEdges[i].oldX = 0; - blueEdges[i].oldX = 0; - double w = r.variate<double, std::exponential_distribution>(1); - redEdges[i].weight = w; - blueEdges[i].weight = w; + for (unsigned i = 0; i < edges.size(); i++) { + Vertex& blueVertex = vertices[vertices.size() / 2 + (i % (2 * n)) / 2 + n * (((i + 2*n) / 4) / n)]; + Vertex& redVertex = vertices[(1+(i % (2 * n))) / 2 + (n + 1) * ((i / 4) / (n))]; + edges[i].setVertices(redVertex, blueVertex); + edges[i].weight = r.variate<double, std::exponential_distribution>(1); } } - void propagateBeliefs() { - for (HalfEdge& e : redEdges) { - double Xt = std::numeric_limits<double>::infinity(); - for (const HalfEdge* en : e.getHead().neighbors) { - if (e.getTail().getIndex() != en->getHead().getIndex()) { - Xt = std::min(en->weight - en->oldX, Xt); + double propagateBeliefs() { + for (Edge& e : edges) { + for (HalfEdge& he : e.halfedges) { + double Xt = std::numeric_limits<double>::infinity(); + for (const HalfEdge& en : he.getHead().neighbors) { + if (he.getTail().index != en.getHead().index) { + Xt = std::min(en.edge.weight - en.oldX, Xt); + } } + he.X = Xt; } - e.X = Xt; } - for (HalfEdge& e : blueEdges) { - double Xt = std::numeric_limits<double>::infinity(); - for (const HalfEdge* en : e.getHead().neighbors) { - if (e.getTail().getIndex() != en->getHead().getIndex()) { - Xt = std::min(en->weight - en->oldX, Xt); - } + + double ΔX = std::numeric_limits<double>::infinity(); + + for (Edge& e : edges) { + ΔX = std::min(ΔX, e.belief()); + + for (HalfEdge& he : e.halfedges) { + he.oldX = he.X; } - e.X = Xt; - } - for (HalfEdge& e : redEdges) { - e.oldX = e.X; - } - for (HalfEdge& e : blueEdges) { - e.oldX = e.X; } + + return ΔX; } }; int main() { Rng r; - BipartiteGraph G(10, r); + Graph G(1000, r); - for (unsigned i = 0; i < 1000; i++) { - G.propagateBeliefs(); -// std::cout << G.redEdges[40].X << " " << G.blueEdges[40].X << std::endl; - } + double Δx = 0; - for (unsigned i = 0; i < G.blueEdges.size(); i++) { - std::cout << G.blueEdges[i].getTail().getIndex() << " " << G.blueEdges[i].getHead().getIndex() + G.blueVertices.size() << std::endl; + while (Δx < 1) { + Δx = G.propagateBeliefs(); } - for (unsigned i = 0; i < G.blueEdges.size(); i++) { - if (G.blueEdges[i].X + G.redEdges[i].X >= 0) { - std::cout << G.blueEdges[i].getTail().getIndex() << " " << G.blueEdges[i].getHead().getIndex() + G.blueVertices.size() << std::endl; + + for (unsigned i = 0; i < G.edges.size(); i++) { + if (G.edges[i].active()) { + std::cout << G.edges[i].halfedges[0].getTail().coordinate[0] << " " << G.edges[i].halfedges[0].getTail().coordinate[1] << " " << G.edges[i].halfedges[0].getHead().coordinate[0] << " " << G.edges[i].halfedges[0].getHead().coordinate[1] << std::endl; } } |