#include "analysis_tools.hpp" std::pair, std::set> find_minimal_crack(const network& n, unsigned i0) { std::set removed_edges = n.get_cycle_edges(n.G.dual_edges[i0].v[0]); std::vector, std::set>> cycles; cycles.reserve(removed_edges.size()); for (unsigned edge : removed_edges) { cycles.push_back(n.get_cycle(removed_edges, n.G.dual_edges[edge].v[0], n.G.dual_edges[edge].v[1])); cycles.back().second.insert(edge); if (n.G.dual_edges[edge].crossings[0]) cycles.back().first[0]++; if (n.G.dual_edges[edge].crossings[1]) cycles.back().first[1]++; } if (cycles.size() == 1) { return cycles.front(); } bool all_good = true; unsigned not_good; for (unsigned i = 0; i < 2; i++) { if (!((cycles[i].first[0] % 2 == 0 && cycles[i].first[1] % 2 == 1) || (cycles[i].first[0] % 2 == 1 && cycles[i].first[1] % 2 == 0))) { all_good = false; not_good = i; } } if (all_good) { if (n.two_sides) { if (cycles[0].second.size() > cycles[1].second.size()) { return cycles[1]; } else { return cycles[0]; } } else { if (cycles[0].first[0] % 2 == 0) { return cycles[0]; } else { return cycles[1]; } } } else if (!n.two_sides) { if (cycles[!not_good].first[0] % 2 == 0) { return cycles[!not_good]; } } const auto& cycle1 = cycles[0]; const auto& cycle2 = cycles[1]; unsigned sum_sig_0 = cycle1.first[0] + cycle2.first[0]; unsigned sum_sig_1 = cycle1.first[1] + cycle2.first[1]; std::valarray bool_cycle1(n.G.edges.size()); std::valarray bool_cycle2(n.G.edges.size()); for (auto v : cycle1.second) { bool_cycle1[v] = 1; } for (auto v : cycle2.second) { bool_cycle2[v] = 1; } std::valarray new_bool_cycle = bool_cycle1 ^ bool_cycle2; std::set new_cycle; unsigned pos = 0; for (uint8_t included : new_bool_cycle) { if (included) { new_cycle.insert(pos); } pos++; } if (cycles[!not_good].second.size() > new_cycle.size() || !n.two_sides) { return {{sum_sig_0, sum_sig_1}, new_cycle}; } else { return cycles[!not_good]; } }