11#ifndef GRAPH_MATCHING_H_
12#define GRAPH_MATCHING_H_
14#include <gudhi/Neighbors_finder.h>
17#include <unordered_set>
22namespace persistence_diagram {
31 explicit Graph_matching(Persistence_graph &g);
40 Persistence_graph* gp;
43 std::vector<int> v_to_u;
45 std::unordered_set<int> unmatched_in_u;
48 Layered_neighbors_finder layering()
const;
50 bool augment(Layered_neighbors_finder & layered_nf,
int u_start_index,
int max_depth);
52 void update(std::vector<int> & path);
55inline Graph_matching::Graph_matching(Persistence_graph& g)
56 : gp(&g), r(0.), v_to_u(g.size(), null_point_index()), unmatched_in_u(g.size()) {
57 for (
int u_point_index = 0; u_point_index < g.size(); ++u_point_index)
58 unmatched_in_u.insert(u_point_index);
61inline bool Graph_matching::perfect()
const {
62 return unmatched_in_u.empty();
65inline bool Graph_matching::multi_augment() {
68 Layered_neighbors_finder layered_nf(layering());
69 int max_depth = layered_nf.vlayers_number()*2 - 1;
70 double rn = sqrt(gp->size());
72 if (max_depth < 0 || (unmatched_in_u.size() > rn && max_depth >= rn))
74 bool successful =
false;
75 std::vector<int> tries(unmatched_in_u.cbegin(), unmatched_in_u.cend());
76 for (
auto it = tries.cbegin(); it != tries.cend(); it++)
78 successful = augment(layered_nf, *it, max_depth) || successful;
82inline void Graph_matching::set_r(
double r) {
86inline bool Graph_matching::augment(Layered_neighbors_finder & layered_nf,
int u_start_index,
int max_depth) {
88 std::vector<int> path;
89 path.emplace_back(u_start_index);
91 if (
static_cast<int> (path.size()) > max_depth) {
97 path.emplace_back(layered_nf.pull_near(path.back(),
static_cast<int> (path.size()) / 2));
98 while (path.back() == null_point_index()) {
104 path.emplace_back(layered_nf.pull_near(path.back(), path.size() / 2));
106 path.emplace_back(v_to_u.at(path.back()));
107 }
while (path.back() != null_point_index());
114inline Layered_neighbors_finder Graph_matching::layering()
const {
115 std::vector<int> u_vertices(unmatched_in_u.cbegin(), unmatched_in_u.cend());
116 std::vector<int> v_vertices;
117 Neighbors_finder nf(*gp, r);
118 for (
int v_point_index = 0; v_point_index < gp->size(); ++v_point_index)
119 nf.add(v_point_index);
120 Layered_neighbors_finder layered_nf(*gp, r);
121 for (
int layer = 0; !u_vertices.empty(); layer++) {
123 for (
auto it1 = u_vertices.cbegin(); it1 != u_vertices.cend(); ++it1) {
124 std::vector<int> u_succ(nf.pull_all_near(*it1));
125 for (
auto it2 = u_succ.begin(); it2 != u_succ.end(); ++it2) {
126 layered_nf.add(*it2, layer);
127 v_vertices.emplace_back(*it2);
133 for (
auto it = v_vertices.cbegin(); it != v_vertices.cend(); it++)
134 if (v_to_u.at(*it) == null_point_index())
138 u_vertices.emplace_back(v_to_u.at(*it));
147inline void Graph_matching::update(std::vector<int>& path) {
149 unmatched_in_u.erase(path.front());
150 for (
auto it = path.cbegin(); it != path.cend(); ++it) {
153 v_to_u[*(++it)] = tmp;