diff options
| -rw-r--r-- | Makefile | 11 | ||||
| -rw-r--r-- | excitation.cpp (renamed from rbmp.cpp) | 87 | ||||
| -rw-r--r-- | order.cpp | 55 | ||||
| -rw-r--r-- | rbmp.hpp | 106 | 
4 files changed, 169 insertions, 90 deletions
| @@ -4,15 +4,18 @@ BLOSSOM_DIRS := $(BLOSSOM_DIR) $(BLOSSOM_DIR)/MinCost $(BLOSSOM_DIR)/GEOM  BLOSSOM_SOURCES := $(filter-out $(BLOSSOM_DIR)/example.cpp, $(foreach dir, $(BLOSSOM_DIRS), $(wildcard $(dir)/*.cpp)))
  BLOSSOM_OBJS := $(patsubst %.cpp, %.o, $(BLOSSOM_SOURCES))
 -CFLAGS := -flto -O3 -D_NDEBUG -DPERFECT_MATCHING_DOUBLE
 +CFLAGS := -flto -O3 -Os -march=native -D_NDEBUG -DPERFECT_MATCHING_DOUBLE
  CXX = clang++
  LD = ld.lld
  LIBS := -lrt
 -all: rbmp
 +all: excitation order
 -rbmp: rbmp.cpp $(BLOSSOM_DIR)/blossom5.o
 -	$(CXX) $(CFLAGS) $(BLOSSOM_DIR)/blossom5.o rbmp.cpp -o $@
 +order: order.cpp $(BLOSSOM_DIR)/blossom5.o
 +	$(CXX) $(CFLAGS) $(BLOSSOM_DIR)/blossom5.o order.cpp -o $@
 +
 +excitation: excitation.cpp $(BLOSSOM_DIR)/blossom5.o
 +	$(CXX) $(CFLAGS) $(BLOSSOM_DIR)/blossom5.o excitation.cpp -o $@
  $(BLOSSOM_DIR)/blossom5.o: ${BLOSSOM_OBJS}
  	$(LD) -r -o $@ ${BLOSSOM_OBJS}
 diff --git a/rbmp.cpp b/excitation.cpp index 8ddc591..05cb8c6 100644 --- a/rbmp.cpp +++ b/excitation.cpp @@ -1,91 +1,6 @@  #include <iostream> -#include <cmath> -#include <functional> -#include <random> -#include <vector> -#include <limits> -#include "randutils/randutils.hpp" -#include "pcg-cpp/include/pcg_random.hpp" - -#include "blossom5-v2.05.src/PerfectMatching.h" - -using Rng = randutils::random_generator<pcg32>; - -class Edge; -class HalfEdge; - -class Vertex { -public: -  unsigned index; -  std::vector<std::reference_wrapper<HalfEdge>> neighbors; -  std::array<unsigned, 2> coordinate; - -  void addEdge(HalfEdge& e) { -    neighbors.push_back(e); -  } -}; - -class HalfEdge { -private: -  Vertex* tail; -  Vertex* head; - -public: -  const Edge& edge; - -  HalfEdge(const Edge& e) : edge(e) {} -  void setVertices(Vertex& vt, Vertex& vh) { -    tail = &vt; -    head = &vh; -  } -  const Vertex& getHead() const { -    return *head; -  } -  const Vertex& getTail() const { -    return *tail; -  } -}; - -class Edge { -public: -  std::array<HalfEdge, 2> halfedges; -  double weight; - -  Edge() : halfedges{*this, *this} {}; -  void setVertices(Vertex& red, Vertex& blue) { -    halfedges[0].setVertices(red, blue); -    halfedges[1].setVertices(blue, red); -    red.addEdge(halfedges[0]); -    blue.addEdge(halfedges[1]); -  } -}; - -class Graph { -public: -  std::vector<Vertex> vertices; -  std::vector<Edge> edges; - -  Graph(unsigned n, Rng& r) : vertices(2 * n * (n + 1)), edges(pow(2 * n, 2)) { -    unsigned M = vertices.size() / 2; -    for (unsigned i = 0; i < M; i++) { -      vertices[i].index = i; -      vertices[i].coordinate = {2 * (i % (n + 1)), 2 * (i / (n + 1)) + 1}; -      vertices[M + i].index = M + i; -      vertices[M + i].coordinate = {2 * (i % n) + 1, 2 * (i / n)}; -    } -    for (unsigned i = 0; i < edges.size(); i++) { -      Vertex& redVertex = vertices[(1 + (i % (2 * n))) / 2 + (n + 1) * ((i / 4) / n)]; -      Vertex& blueVertex = vertices[M + (i % (2 * n)) / 2 + n * (((i + 2 * n) / 4) / n)]; -      edges[i].setVertices(redVertex, blueVertex); -      edges[i].weight = r.variate<double, std::exponential_distribution>(1); -    } -  } -}; - -bool edgeMatched(PerfectMatching& pm, const Edge& e) { -  return e.halfedges[0].getTail().index == pm.GetMatch(e.halfedges[0].getHead().index); -} +#include "rbmp.hpp"  int main(int argc, char* argv[]) {    unsigned n = 100; diff --git a/order.cpp b/order.cpp new file mode 100644 index 0000000..3ca57af --- /dev/null +++ b/order.cpp @@ -0,0 +1,55 @@ +#include <iostream> +#include <random> + +#include "rbmp.hpp" + +int main(int argc, char* argv[]) { +  unsigned n = 100; +  unsigned m = 100; + +  int opt; + +  while ((opt = getopt(argc, argv, "n:m:")) != -1) { +    switch (opt) { +    case 'n': +      n = atoi(optarg); +      break; +    case 'm': +      m = atoi(optarg); +      break; +    default: +      exit(1); +    } +  } + +  Rng r; +  Graph G(n, r); + +  std::vector<Coordinate> data(G.vertices.size() / 2); + +  for (unsigned i = 0; i < m; i++) { +    PerfectMatching pm(G.vertices.size(), G.edges.size()); + +    for (const Edge& e : G.edges) { +      pm.AddEdge(e.halfedges[0].getHead().index, e.halfedges[0].getTail().index, r.variate<double, std::exponential_distribution>(1)); +    } + +    pm.options.verbose = false; +    pm.Solve(); + +    for (unsigned i = 0; i < G.vertices.size() / 2; i++) { +      unsigned j = pm.GetMatch(i); + +      data[i] += G.vertices[i].coordinate; +      data[i] -= G.vertices[j].coordinate; +    } +  } + +  std::cout << n << std::endl; + +  for (unsigned i = 0; i < G.vertices.size() / 2; i++) { +    std::cout << data[i][0] << " " << data[i][1] << std::endl; +  } + +  return 0; +} diff --git a/rbmp.hpp b/rbmp.hpp new file mode 100644 index 0000000..571fb05 --- /dev/null +++ b/rbmp.hpp @@ -0,0 +1,106 @@ +#include <cmath> +#include <functional> +#include <random> +#include <vector> +#include <limits> + +#include "randutils/randutils.hpp" +#include "pcg-cpp/include/pcg_random.hpp" + +#include "blossom5-v2.05.src/PerfectMatching.h" + +using Rng = randutils::random_generator<pcg32>; + +class Edge; +class HalfEdge; + +class Coordinate { +  std::array<int, 2> r; +  public: +  void operator=(const std::array<int, 2>& rp) { +    r = rp; +  } +  void operator+=(const Coordinate& x) { +    r[0] += x.r[0]; +    r[1] += x.r[1]; +  } +  void operator-=(const Coordinate& x) { +    r[0] -= x.r[0]; +    r[1] -= x.r[1]; +  } +  int operator[](unsigned i) const { +    return r[i]; +  } +}; + +class Vertex { +public: +  unsigned index; +  std::vector<std::reference_wrapper<HalfEdge>> neighbors; +  Coordinate coordinate; + +  void addEdge(HalfEdge& e) { +    neighbors.push_back(e); +  } +}; + +class HalfEdge { +private: +  Vertex* tail; +  Vertex* head; + +public: +  const Edge& edge; + +  HalfEdge(const Edge& e) : edge(e) {} +  void setVertices(Vertex& vt, Vertex& vh) { +    tail = &vt; +    head = &vh; +  } +  const Vertex& getHead() const { +    return *head; +  } +  const Vertex& getTail() const { +    return *tail; +  } +}; + +class Edge { +public: +  std::array<HalfEdge, 2> halfedges; +  double weight; + +  Edge() : halfedges{*this, *this} {}; +  void setVertices(Vertex& red, Vertex& blue) { +    halfedges[0].setVertices(red, blue); +    halfedges[1].setVertices(blue, red); +    red.addEdge(halfedges[0]); +    blue.addEdge(halfedges[1]); +  } +}; + +class Graph { +public: +  std::vector<Vertex> vertices; +  std::vector<Edge> edges; + +  Graph(int n, Rng& r) : vertices(2 * n * (n + 1)), edges(pow(2 * n, 2)) { +    unsigned M = vertices.size() / 2; +    for (int i = 0; i < M; i++) { +      vertices[i].index = i; +      vertices[i].coordinate = {2 * (i % (n + 1)), 2 * (i / (n + 1)) + 1}; +      vertices[M + i].index = M + i; +      vertices[M + i].coordinate = {2 * (i % n) + 1, 2 * (i / n)}; +    } +    for (unsigned i = 0; i < edges.size(); i++) { +      Vertex& redVertex = vertices[(1 + (i % (2 * n))) / 2 + (n + 1) * ((i / 4) / n)]; +      Vertex& blueVertex = vertices[M + (i % (2 * n)) / 2 + n * (((i + 2 * n) / 4) / n)]; +      edges[i].setVertices(redVertex, blueVertex); +      edges[i].weight = r.variate<double, std::exponential_distribution>(1); +    } +  } +}; + +bool edgeMatched(PerfectMatching& pm, const Edge& e) { +  return e.halfedges[0].getTail().index == pm.GetMatch(e.halfedges[0].getHead().index); +} | 
