2 #ifndef OPENGM_EXTERNAL_QPBO_HXX 3 #define OPENGM_EXTERNAL_QPBO_HXX 43 template<
class _GM,
class _ACC>
65 strongPersistency_(p.strongPersistency_),
66 useImproveing_ (p.useImproveing_),
67 useProbeing_ (p.useProbeing_)
74 strongPersistency_ =
true;
75 useImproveing_ =
false;
83 std::string
name()
const;
87 template<
class VisitorType>
91 virtual typename GM::ValueType
bound()
const;
92 virtual typename GM::ValueType
value()
const;
96 const GraphicalModelType& gm_;
98 kolmogorov::qpbo::QPBO<ValueType>* qpbo_;
117 : gm_(gm), bound_(-std::numeric_limits<ValueType>::infinity()) {
119 label_ =
new int[gm_.numberOfVariables()];
120 defaultLabel_ =
new int[gm_.numberOfVariables()];
121 for(
size_t i = 0; i < gm_.numberOfVariables(); ++i) {
123 defaultLabel_[i] = 0;
125 if(parameter_.label_.size() > 0) {
126 for(
size_t i = 0; i < parameter_.label_.size(); ++i) {
127 defaultLabel_[i] = parameter_.
label_[i];
130 size_t numVariables = gm_.numberOfVariables();
131 size_t numPairwiseFactors = 0;
135 size_t vec00[] = {0, 0};
136 size_t vec01[] = {0, 1};
137 size_t vec10[] = {1, 0};
138 size_t vec11[] = {1, 1};
139 for(
size_t j = 0; j < gm_.numberOfVariables(); ++j) {
140 if(gm_.numberOfLabels(j) != 2) {
141 throw RuntimeError(
"This implementation of QPBO supports only binary variables.");
144 for(
size_t j = 0; j < gm_.numberOfFactors(); ++j) {
145 if(gm_[j].numberOfVariables() == 2) {
146 ++numPairwiseFactors;
148 else if(gm_[j].numberOfVariables() > 2) {
149 throw RuntimeError(
"This implementation of QPBO supports only factors of order <= 2.");
152 qpbo_ =
new kolmogorov::qpbo::QPBO<ValueType > (numVariables, numPairwiseFactors);
153 qpbo_->AddNode(numVariables);
154 for(
size_t j = 0; j < gm_.numberOfFactors(); ++j) {
155 if(gm_[j].numberOfVariables() == 0) {
158 else if(gm_[j].numberOfVariables() == 1) {
159 qpbo_->AddUnaryTerm((
int) (gm_[j].variableIndex(0)), gm_[j](vec0), gm_[j](vec1));
161 else if(gm_[j].numberOfVariables() == 2) {
162 qpbo_->AddPairwiseTerm((
int) (gm_[j].variableIndex(0)), (
int) (gm_[j].variableIndex(1)),
163 gm_[j](vec00), gm_[j](vec01), gm_[j](vec10), gm_[j](vec11));
166 qpbo_->MergeParallelEdges();
173 delete defaultLabel_;
200 template<
class VisitorType>
204 visitor.begin(*
this);
206 if(!parameter_.strongPersistency_) {
207 qpbo_->ComputeWeakPersistencies();
210 bound_ = constTerm_ + 0.5 * qpbo_->ComputeTwiceLowerBound();
212 int countUnlabel = 0;
213 int *listUnlabel =
new int[gm_.numberOfVariables()];
214 for(
size_t i = 0; i < gm_.numberOfVariables(); ++i) {
215 label_[i] = qpbo_->GetLabel(i);
217 listUnlabel[countUnlabel++] = i;
222 int *mapping =
new int[gm_.numberOfVariables()];
223 for(
int i = 0; i < static_cast<int>(gm_.numberOfVariables()); i++) {
228 if(parameter_.useProbeing_ && countUnlabel > 0) {
229 typename kolmogorov::qpbo::QPBO<ValueType>::ProbeOptions options;
232 options.weak_persistencies = 1;
235 int *new_mapping =
new int[gm_.numberOfVariables()];
236 qpbo_->Probe(new_mapping, options);
237 qpbo_->MergeMappings(gm_.numberOfVariables(), mapping, new_mapping);
238 qpbo_->ComputeWeakPersistencies();
243 for(
IndexType i = 0; i < gm_.numberOfVariables(); ++i) {
244 label_[i] = qpbo_->GetLabel(mapping[i] / 2);
246 listUnlabel[countUnlabel++] = i;
248 label_[i] = (label_[i] + mapping[i]) % 2;
251 if(parameter_.useImproveing_ && countUnlabel > 0) {
252 int *improve_order =
new int[countUnlabel];
255 for(
size_t i = 0;
static_cast<int>(i) < countUnlabel; i++) {
256 improve_order[i] = mapping[listUnlabel[i]] / 2;
257 qpbo_->SetLabel(improve_order[i], defaultLabel_[improve_order[i]]);
261 for(
int i = 0; i < countUnlabel - 1; ++i) {
262 int j = i + (int) (((
double) rand() / ((
double) RAND_MAX + 1)) * (countUnlabel - i));
264 int k = improve_order[j];
265 improve_order[j] = improve_order[i];
266 improve_order[i] = k;
270 qpbo_->Improve(countUnlabel, improve_order);
271 delete improve_order;
274 for(
int i = 0; i < countUnlabel; ++i) {
275 label_[listUnlabel[i]] = (qpbo_->GetLabel(mapping[listUnlabel[i]] / 2) + mapping[listUnlabel[i]]) % 2;
288 ::arg(std::vector<LabelType>&
arg,
const size_t& n)
const {
293 arg.resize(gm_.numberOfVariables());
294 for(
size_t i = 0; i < gm_.numberOfVariables(); ++i) {
295 if(label_[i] < 0) arg[i] = defaultLabel_[i];
296 else arg[i] = label_[i];
305 ::arg(std::vector<TriBool>&
arg,
const size_t& n)
const {
310 arg.resize(gm_.numberOfVariables(),
TBX);
311 for(
int i = 0; i < gm_.numberOfVariables(); ++i) {
312 if(label_[i] < 0) arg[i] =
TBX;
313 if(label_[i] == 0) arg[i] =
TB0;
324 opt.resize(gm_.numberOfVariables());
325 for(
IndexType i = 0; i < gm_.numberOfVariables(); ++i) {
326 if(label_[i] < 0) {opt[i] = 0;}
327 else {opt[i] = 1; ++p;}
329 return p/gm_.numberOfVariables();
334 inline typename GM::ValueType
341 inline typename GM::ValueType
344 std::vector<LabelType> c;
346 return gm_.evaluate(c);
353 #endif // #ifndef OPENGM_EXTERNAL_QPBO_HXX
bool useProbeing_
using probeing technique
visitors::VerboseVisitor< QPBO< GM > > VerboseVisitorType
const GraphicalModelType & graphicalModel() const
std::vector< size_t > label_
initial configuration for improving
#define OPENGM_ASSERT(expression)
Parameter for opengm::external::QPBO.
opengm::Minimizer AccumulationType
bool strongPersistency_
forcing strong persistency
double partialOptimality(std::vector< bool > &) const
GraphicalModelType::IndexType IndexType
GraphicalModelType::ValueType ValueType
visitors::TimingVisitor< QPBO< GM > > TimingVisitorType
Inference algorithm interface.
Parameter(const P &p)
constructor
InferenceTermination infer()
virtual GM::ValueType value() const
return the solution (value)
InferenceTermination arg(std::vector< LabelType > &, const size_t &=1) const
virtual GM::ValueType bound() const
return a bound on the solution
visitors::EmptyVisitor< QPBO< GM > > EmptyVisitorType
Minimization as a unary accumulation.
bool useImproveing_
using improving technique
QPBO(const GraphicalModelType &gm, const Parameter para=Parameter())