Alpha Expansion Library
C++ library for the Alpha-Expansion graph-cut algorithm with Python bindings
Loading...
Searching...
No Matches
ORToolsSolver.hpp
Go to the documentation of this file.
1#pragma once
2
4#include "ortools/graph/max_flow.h"
5#include <vector>
6#include <cassert>
7
14template <typename T>
15class ORToolsSolver : public MaxFlowSolver<T> {
16 operations_research::SimpleMaxFlow max_flow_;
17 int num_vars_;
18 int source_node_;
19 int sink_node_;
20 T e_const_;
21 std::vector<bool> in_source_cut_;
22
23public:
24 ORToolsSolver() : num_vars_(0), e_const_(0) {
25 source_node_ = 0;
26 sink_node_ = 1;
27 }
28
29 ~ORToolsSolver() override = default;
30
31 typename MaxFlowSolver<T>::Var add_variable() override {
32 num_vars_++;
33 sink_node_ = num_vars_ + 1;
34 return num_vars_;
35 }
36
37 void add_constant(T E) override {
38 e_const_ += E;
39 }
40
41 void add_edge(int i, int j, T cap, T rev_cap) {
42 if (cap > 0) max_flow_.AddArcWithCapacity(i, j, cap);
43 if (rev_cap > 0) max_flow_.AddArcWithCapacity(j, i, rev_cap);
44 }
45
46 void add_tweights(int i, T cap_source, T cap_sink) {
47 T delta = cap_source < cap_sink ? cap_source : cap_sink;
48 if (delta < 0) {
49 e_const_ += delta;
50 cap_source -= delta;
51 cap_sink -= delta;
52 }
53 if (cap_source > 0) max_flow_.AddArcWithCapacity(source_node_, i, static_cast<operations_research::SimpleMaxFlow::FlowQuantity>(cap_source));
54 if (cap_sink > 0) max_flow_.AddArcWithCapacity(i, sink_node_, static_cast<operations_research::SimpleMaxFlow::FlowQuantity>(cap_sink));
55 }
56
57 void add_term1(typename MaxFlowSolver<T>::Var x, T E0, T E1) override {
58 this->add_tweights(x, E1, E0);
59 }
60
61 void add_term2(typename MaxFlowSolver<T>::Var x, typename MaxFlowSolver<T>::Var y, T A, T B, T C, T D) override {
62 this->add_tweights(x, D, A);
63 B -= A;
64 C -= D;
65
66 assert(B + C >= 0);
67 if (B < 0) {
68 this->add_tweights(x, 0, B);
69 this->add_tweights(y, 0, -B);
70 this->add_edge(x, y, 0, B + C);
71 } else if (C < 0) {
72 this->add_tweights(x, 0, -C);
73 this->add_tweights(y, 0, C);
74 this->add_edge(x, y, B + C, 0);
75 } else {
76 this->add_edge(x, y, B, C);
77 }
78 }
79
80 T minimize() override {
81 max_flow_.Solve(source_node_, sink_node_);
82 std::vector<int> source_cut;
83 max_flow_.GetSourceSideMinCut(&source_cut);
84 in_source_cut_.assign(num_vars_ + 2, false);
85 for (int node: source_cut) {
86 in_source_cut_[node] = true;
87 }
88
89 return e_const_ + static_cast<T>(max_flow_.OptimalFlow());
90 }
91
92 int get_var(typename MaxFlowSolver<T>::Var x) override {
93 return in_source_cut_[x] ? 0 : 1;
94 }
95};
Abstract interface for a binary max-flow / QPBO solver.
Definition MaxFlowSolver.hpp:15
int Var
Integer handle identifying a binary variable.
Definition MaxFlowSolver.hpp:20
MaxFlowSolver backed by Google OR-Tools SimpleMaxFlow.
Definition ORToolsSolver.hpp:15
void add_term2(typename MaxFlowSolver< T >::Var x, typename MaxFlowSolver< T >::Var y, T A, T B, T C, T D) override
Definition ORToolsSolver.hpp:61
void add_term1(typename MaxFlowSolver< T >::Var x, T E0, T E1) override
Definition ORToolsSolver.hpp:57
~ORToolsSolver() override=default
T minimize() override
Minimizes the energy and returns the minimum value.
Definition ORToolsSolver.hpp:80
MaxFlowSolver< T >::Var add_variable() override
Introduces a new binary variable and returns its handle.
Definition ORToolsSolver.hpp:31
void add_edge(int i, int j, T cap, T rev_cap)
Definition ORToolsSolver.hpp:41
void add_constant(T E) override
Adds a constant term to the energy function.
Definition ORToolsSolver.hpp:37
ORToolsSolver()
Definition ORToolsSolver.hpp:24
int get_var(typename MaxFlowSolver< T >::Var x) override
Definition ORToolsSolver.hpp:92
void add_tweights(int i, T cap_source, T cap_sink)
Definition ORToolsSolver.hpp:46