23#include <py2cpp/dict.hpp>
24#include <py2cpp/set.hpp>
42 constexpr int INF = std::numeric_limits<int>::max() / 2;
56 template <
typename Node,
typename WeightFunc>
58 -> std::vector<std::vector<DualEdge<Node>>> {
61 std::map<std::pair<Node, Node>, std::vector<int>>
edge_face_map;
64 const auto sz =
static_cast<int>(
f.
size());
65 for (
int i = 0;
i <
sz; ++
i) {
67 auto v =
f[(
i + 1) %
sz];
68 if (
u >
v) std::swap(
u,
v);
73 std::map<std::pair<int, int>, std::pair<int, std::pair<Node, Node>>>
best;
77 const int w = weight(
u,
v);
91 std::vector<std::vector<DualEdge<Node>>>
dual(
n_face);
94 const auto& [
w, primal] =
info;
104 template <
typename Node>
106 -> std::pair<std::vector<int>, std::vector<int>>;
109 -> std::vector<int> {
110 std::vector<int>
path;
127 template <
typename Node>
129 -> std::vector<std::pair<int, int>>;
134 template <
typename Node>
136 -> std::vector<std::pair<int, int>>;
141 template <
typename Node>
143 const std::vector<std::vector<int>>&
dist)
144 -> std::vector<std::pair<int, int>> {
174 -> std::vector<py::set<typename Graph::node_t>>;
194 template <
typename Graph,
typename WeightFunc>
196 const std::vector<std::vector<typename Graph::node_t>>&
faces)
198 using node_t =
typename Graph::node_t;
206 if (
faces[
i].size() % 2 == 1) {
214 for (
const auto&
e :
G.edges()) {
225 for (
const auto&
e :
G.edges()) {
243 std::vector<std::vector<int>>(
n_odd));
260 std::map<std::pair<int, int>, std::pair<node_t, node_t>>
dedge_primal;
262 for (
const auto&
e :
dual[
fi]) {
265 if (
a >
b) std::swap(
a,
b);
271 std::set<std::pair<node_t, node_t>>
excluded;
281 if (
a >
b) std::swap(
a,
b);
284 auto [
pu,
pv] =
it->second;
293 for (
const auto&
e :
G.edges()) {
295 if (
u >
v) std::swap(
u,
v);
319template <
typename Graph,
typename WeightFunc>
321 const std::vector<std::vector<typename Graph::node_t>>&
faces)
344 const std::vector<std::vector<std::vector<typename Graph::node_t>>>&
component_faces)
346 using node_t =
typename Graph::node_t;
347 using edge_t = std::pair<node_t, node_t>;
357 std::vector<std::future<py::set<edge_t>>>
futures;
362 const auto& comp_faces = component_faces[i];
364 auto comp_weight = [&weight](node_t u, node_t v) -> int { return weight(u, v); };
367 std::vector<std::pair<node_t, node_t>>
comp_edges;
372 if (
u >
v) std::swap(
u,
v);
381 using node_t =
typename std::remove_reference<
382 decltype(
comp_edges)>::type::value_type::first_type;
383 const std::vector<std::pair<node_t, node_t>>&
edge_list;
405 const py::set<std::pair<typename Graph::node_t, typename Graph::node_t>>&
cut_edges,
407 using node_t =
typename Graph::node_t;
409 std::map<node_t, std::vector<node_t>>
cut_adj;
417 std::map<node_t, int>
colour;
422 std::queue<node_t>
q;
443 const py::set<std::pair<typename Graph::node_t, typename Graph::node_t>>&
cut_edges)
444 -> std::pair<bool, int> {
Read-only map of maps of maps (view into a dict-of-dict-of-dict structure)
Definition coreviews.hpp:109
AdjacencyView(Atlas &d)
Construct an AdjacencyView from an Atlas container.
Definition coreviews.hpp:115
auto begin() const
Get iterator to the beginning of the view.
Definition coreviews.hpp:55
auto size() const -> size_t
Get the number of elements in the view.
Definition coreviews.hpp:49
auto end() const
Get iterator to the end of the view.
Definition coreviews.hpp:61
Definition thread_pool.hpp:35
auto validate_max_cut(const Graph &G, const py::set< std::pair< typename Graph::node_t, typename Graph::node_t > > &cut_edges, WeightFunc weight) -> std::pair< bool, int >
Definition hadlock.hpp:403
auto solve_hadlock_max_cut(const Graph &G, WeightFunc weight, const std::vector< std::vector< typename Graph::node_t > > &faces) -> py::set< std::pair< typename Graph::node_t, typename Graph::node_t > >
Solve MAX-CUT for a planar graph using Hadlock's algorithm.
Definition hadlock.hpp:320
Definition hadlock.hpp:40
auto dijkstra(const std::vector< std::vector< DualEdge< Node > > > &dual, int src) -> std::pair< std::vector< int >, std::vector< int > >
auto reconstruct_path(const std::vector< int > &prev, int src, int dst) -> std::vector< int >
Definition hadlock.hpp:108
auto biconnected_components(const Graph &G) -> std::vector< py::set< typename Graph::node_t > >
Decompose a graph into its biconnected components (blocks).
auto exact_mwpm(const std::vector< int > &odd_faces, const std::vector< std::vector< int > > &dist) -> std::vector< std::pair< int, int > >
auto solve_hadlock_component(const Graph &G, WeightFunc weight, const std::vector< std::vector< typename Graph::node_t > > &faces) -> py::set< std::pair< typename Graph::node_t, typename Graph::node_t > >
Solve MAX-CUT for a single planar biconnected component.
Definition hadlock.hpp:195
auto build_dual(const std::vector< std::vector< Node > > &faces, WeightFunc weight) -> std::vector< std::vector< DualEdge< Node > > >
Definition hadlock.hpp:57
auto min_weight_perfect_matching(const std::vector< int > &odd_faces, const std::vector< std::vector< int > > &dist) -> std::vector< std::pair< int, int > >
Definition hadlock.hpp:142
auto greedy_mwpm(const std::vector< int > &odd_faces, const std::vector< std::vector< int > > &dist) -> std::vector< std::pair< int, int > >
constexpr int INF
Definition hadlock.hpp:42
Definition hadlock.hpp:32
Definition hadlock.hpp:44
std::pair< Node, Node > primal
Definition hadlock.hpp:47
int weight
Definition hadlock.hpp:46
int neighbor
Definition hadlock.hpp:45
size_t operator()(const pair< T1, T2 > &p) const
Definition hadlock.hpp:34