2 #ifndef OPENGM_QPBO_HXX
3 #define OPENGM_QPBO_HXX
18 template<
class GM,
class MIN_ST_CUT>
32 std::string
name()
const;
35 template<
class VISITOR>
41 void addUnaryFactorType(
const FactorType& factor);
43 void addEdgeCapacity(
size_t v,
size_t w,
ValueType val);
44 void addPairwiseFactorType(
const FactorType& factor);
48 size_t neg(
size_t var)
const {
return (var+numVars_)%(2*numVars_); }
50 const GraphicalModelType& gm_;
52 std::vector<bool> stateBool_;
61 template<
class GM,
class MIN_ST_CUT>
65 typename QPBO<GM,MIN_ST_CUT>::Parameter
68 numVars_(gm_.numberOfVariables()),
69 minStCut_(2*gm_.numberOfVariables()+2, 6*gm_.numberOfVariables())
73 sink_ = 2*numVars_ + 1;
76 for(
size_t j=0; j<gm_.numberOfFactors(); ++j) {
77 switch (gm_[j].numberOfVariables()) {
81 constTerm_ += gm_[j](c);
85 addUnaryFactorType(gm_[j]);
88 addPairwiseFactorType(gm_[j]);
90 default:
throw std::runtime_error(
"This implementation of the QPBO optimizer does not support factors of order >2.");
95 template<
class GM,
class MIN_ST_CUT>
102 template<
class GM,
class MIN_ST_CUT>
109 template<
class GM,
class MIN_ST_CUT>
116 template<
class GM,
class MIN_ST_CUT>
117 template<
class VISITOR>
121 visitor.begin(*
this);
122 minStCut_.calculateCut(stateBool_);
127 template<
class GM,
class MIN_ST_CUT>
131 std::vector<LabelType>&
arg,
139 arg.resize(numVars_);
140 for(
size_t j=0; j<arg.size(); ++j) {
141 if (stateBool_[j+2] ==
true && stateBool_[neg(j)+2] ==
false)
143 else if (stateBool_[j+2] ==
false && stateBool_[neg(j)+2] ==
true)
152 template<
class GM,
class MIN_ST_CUT>
156 std::vector<bool>& optVec
160 optVec.resize(numVars_);
161 for(
size_t j=0; j<optVec.size(); ++j)
162 if (stateBool_[j+2] != stateBool_[neg(j)+2]) {
168 return opt/gm_.numerOfVariables();
171 template<
class GM,
class MIN_ST_CUT>
175 minStCut_.addEdge((v+2)%(2*numVars_+2),(w+2)%(2*numVars_+2),val);
178 template<
class GM,
class MIN_ST_CUT>
180 QPBO<GM,MIN_ST_CUT>::addUnaryFactorType(
const FactorType& factor)
183 size_t x_i = factor.variableIndex(0);
184 size_t nx_i = neg(x_i);
194 ValueType delta = std::min(c_nx_i, c_x_i);
199 addEdgeCapacity(x_i, sink_, 0.5*c_nx_i);
200 addEdgeCapacity(source_, nx_i, 0.5*c_nx_i);
202 addEdgeCapacity(nx_i, sink_, 0.5*c_x_i);
203 addEdgeCapacity(source_, x_i, 0.5*c_x_i);
206 template<
class GM,
class MIN_ST_CUT>
208 QPBO<GM,MIN_ST_CUT>::addPairwiseFactorType
213 size_t x_i = factor.variableIndex(0);
214 size_t x_j = factor.variableIndex(1);
215 size_t nx_i = neg(x_i);
216 size_t nx_j = neg(x_j);
238 ValueType delta = std::min(c_nx_i_nx_j, c_x_i_nx_j);
241 c_nx_i_nx_j -= delta;
243 delta_c_nx_j += delta;
247 delta = std::min(c_nx_i_x_j, c_x_i_x_j);
252 delta_c_x_j += delta;
256 delta = std::min(c_nx_i_nx_j, c_nx_i_x_j);
259 c_nx_i_nx_j -= delta;
261 delta_c_nx_i += delta;
265 delta = std::min(c_x_i_nx_j, c_x_i_x_j);
270 delta_c_x_i += delta;
275 if (c_nx_i_nx_j != 0) {
276 addEdgeCapacity(x_i, nx_j, 0.5*c_nx_i_nx_j);
277 addEdgeCapacity(x_j, nx_i, 0.5*c_nx_i_nx_j);
279 if (c_nx_i_x_j != 0) {
280 addEdgeCapacity(x_i, x_j, 0.5*c_nx_i_x_j);
281 addEdgeCapacity(nx_j, nx_i, 0.5*c_nx_i_x_j);
283 if (c_x_i_nx_j != 0) {
284 addEdgeCapacity(nx_i, nx_j, 0.5*c_x_i_nx_j);
285 addEdgeCapacity(x_j, x_i, 0.5*c_x_i_nx_j);
287 if (c_x_i_x_j != 0) {
288 addEdgeCapacity(nx_i, x_j, 0.5*c_x_i_x_j);
289 addEdgeCapacity(nx_j, x_i, 0.5*c_x_i_x_j);
294 if (delta_c_nx_j != 0) {
295 addEdgeCapacity(x_j, sink_, 0.5*delta_c_nx_j);
296 addEdgeCapacity(source_, nx_j, 0.5*delta_c_nx_j);
298 if (delta_c_x_j != 0) {
299 addEdgeCapacity(nx_j, sink_, 0.5*delta_c_x_j);
300 addEdgeCapacity(source_, x_j, 0.5*delta_c_x_j);
302 if (delta_c_nx_i != 0) {
303 addEdgeCapacity(x_i, sink_, 0.5*delta_c_nx_i);
304 addEdgeCapacity(source_, nx_i, 0.5*delta_c_nx_i);
306 if (delta_c_x_i != 0) {
307 addEdgeCapacity(nx_i, sink_, 0.5*delta_c_x_i);
308 addEdgeCapacity(source_, x_i, 0.5*delta_c_x_i);
314 #endif // #ifndef OPENGM_EXTERNAL_QPBO_HXX
visitors::TimingVisitor< QPBO< GM, MIN_ST_CUT > > TimingVisitorType
QPBO(const GraphicalModelType &, Parameter=Parameter())
InferenceTermination arg(std::vector< LabelType > &, const size_t &=1) const
double partialOptimality(std::vector< bool > &) const
GraphicalModelType::FactorType FactorType
visitors::EmptyVisitor< QPBO< GM, MIN_ST_CUT > > EmptyVisitorType
GraphicalModelType::ValueType ValueType
QPBO Algorithm C. Rother, V. Kolmogorov, V. Lempitsky, and M. Szummer, "Optimizing binary MRFs via e...
Inference algorithm interface.
opengm::Minimizer AccumulationType
InferenceTermination infer()
visitors::VerboseVisitor< QPBO< GM, MIN_ST_CUT > > VerboseVisitorType
Minimization as a unary accumulation.
const GraphicalModelType & graphicalModel() const