2 #ifndef OPENGM_EXTERNAL_QPBO_HXX
3 #define OPENGM_EXTERNAL_QPBO_HXX
51 strongPersistency_ =
true;
52 useImproveing_ =
false;
57 QPBO(
const GraphicalModelType& gm,
const Parameter para = Parameter());
60 std::string
name()
const;
64 template<
class VisitorType>
68 virtual typename GM::ValueType
bound()
const;
69 virtual typename GM::ValueType
value()
const;
73 const GraphicalModelType& gm_;
75 kolmogorov::qpbo::QPBO<ValueType>* qpbo_;
94 : gm_(gm), bound_(-
std::numeric_limits<ValueType>::infinity()) {
96 label_ =
new int[gm_.numberOfVariables()];
97 defaultLabel_ =
new int[gm_.numberOfVariables()];
98 for(
size_t i = 0; i < gm_.numberOfVariables(); ++i) {
100 defaultLabel_[i] = 0;
102 if(parameter_.label_.size() > 0) {
103 for(
size_t i = 0; i < parameter_.label_.size(); ++i) {
104 defaultLabel_[i] = parameter_.label_[i];
107 size_t numVariables = gm_.numberOfVariables();
108 size_t numPairwiseFactors = 0;
112 size_t vec00[] = {0, 0};
113 size_t vec01[] = {0, 1};
114 size_t vec10[] = {1, 0};
115 size_t vec11[] = {1, 1};
116 for(
size_t j = 0; j < gm_.numberOfVariables(); ++j) {
117 if(gm_.numberOfLabels(j) != 2) {
118 throw RuntimeError(
"This implementation of QPBO supports only binary variables.");
121 for(
size_t j = 0; j < gm_.numberOfFactors(); ++j) {
122 if(gm_[j].numberOfVariables() == 2) {
123 ++numPairwiseFactors;
125 else if(gm_[j].numberOfVariables() > 2) {
126 throw RuntimeError(
"This implementation of QPBO supports only factors of order <= 2.");
129 qpbo_ =
new kolmogorov::qpbo::QPBO<ValueType > (numVariables, numPairwiseFactors);
130 qpbo_->AddNode(numVariables);
131 for(
size_t j = 0; j < gm_.numberOfFactors(); ++j) {
132 if(gm_[j].numberOfVariables() == 0) {
135 else if(gm_[j].numberOfVariables() == 1) {
136 qpbo_->AddUnaryTerm((
int) (gm_[j].variableIndex(0)), gm_[j](vec0), gm_[j](vec1));
138 else if(gm_[j].numberOfVariables() == 2) {
139 qpbo_->AddPairwiseTerm((
int) (gm_[j].variableIndex(0)), (
int) (gm_[j].variableIndex(1)),
140 gm_[j](vec00), gm_[j](vec01), gm_[j](vec10), gm_[j](vec11));
143 qpbo_->MergeParallelEdges();
150 delete defaultLabel_;
177 template<
class VisitorType>
181 visitor.begin(*
this);
183 if(!parameter_.strongPersistency_) {
184 qpbo_->ComputeWeakPersistencies();
187 bound_ = constTerm_ + 0.5 * qpbo_->ComputeTwiceLowerBound();
189 int countUnlabel = 0;
190 int *listUnlabel =
new int[gm_.numberOfVariables()];
191 for(
size_t i = 0; i < gm_.numberOfVariables(); ++i) {
192 label_[i] = qpbo_->GetLabel(i);
194 listUnlabel[countUnlabel++] = i;
199 int *mapping =
new int[gm_.numberOfVariables()];
200 for(
int i = 0; i < static_cast<int>(gm_.numberOfVariables()); i++) {
205 if(parameter_.useProbeing_ && countUnlabel > 0) {
206 typename kolmogorov::qpbo::QPBO<ValueType>::ProbeOptions options;
209 options.weak_persistencies = 1;
212 int *new_mapping =
new int[gm_.numberOfVariables()];
213 qpbo_->Probe(new_mapping, options);
214 qpbo_->MergeMappings(gm_.numberOfVariables(), mapping, new_mapping);
215 qpbo_->ComputeWeakPersistencies();
220 for(
IndexType i = 0; i < gm_.numberOfVariables(); ++i) {
221 label_[i] = qpbo_->GetLabel(mapping[i] / 2);
223 listUnlabel[countUnlabel++] = i;
225 label_[i] = (label_[i] + mapping[i]) % 2;
228 if(parameter_.useImproveing_ && countUnlabel > 0) {
229 int *improve_order =
new int[countUnlabel];
232 for(
size_t i = 0;
static_cast<int>(i) < countUnlabel; i++) {
233 improve_order[i] = mapping[listUnlabel[i]] / 2;
234 qpbo_->SetLabel(improve_order[i], defaultLabel_[improve_order[i]]);
238 for(
int i = 0; i < countUnlabel - 1; ++i) {
239 int j = i + (int) (((
double) rand() / ((
double) RAND_MAX + 1)) * (countUnlabel - i));
241 int k = improve_order[j];
242 improve_order[j] = improve_order[i];
243 improve_order[i] = k;
247 qpbo_->Improve(countUnlabel, improve_order);
248 delete improve_order;
251 for(
int i = 0; i < countUnlabel; ++i) {
252 label_[listUnlabel[i]] = (qpbo_->GetLabel(mapping[listUnlabel[i]] / 2) + mapping[listUnlabel[i]]) % 2;
265 ::arg(std::vector<LabelType>& arg,
const size_t& n)
const {
270 arg.resize(gm_.numberOfVariables());
271 for(
size_t i = 0; i < gm_.numberOfVariables(); ++i) {
272 if(label_[i] < 0) arg[i] = defaultLabel_[i];
273 else arg[i] = label_[i];
282 ::arg(std::vector<TriBool>& arg,
const size_t& n)
const {
287 arg.resize(gm_.numberOfVariables(), TBX);
288 for(
int i = 0; i < gm_.numberOfVariables(); ++i) {
289 if(label_[i] < 0) arg[i] = TBX;
290 if(label_[i] == 0) arg[i] = TB0;
301 opt.resize(gm_.numberOfVariables());
302 for(
IndexType i = 0; i < gm_.numberOfVariables(); ++i) {
303 if(label_[i] < 0) {opt[i] = 0;}
304 else {opt[i] = 1; ++p;}
306 return p/gm_.numberOfVariables();
311 inline typename GM::ValueType
318 inline typename GM::ValueType
321 std::vector<LabelType> c;
323 return gm_.evaluate(c);
330 #endif // #ifndef OPENGM_EXTERNAL_QPBO_HXX
bool useProbeing_
using probeing technique
visitors::VerboseVisitor< QPBO< GM > > VerboseVisitorType
std::vector< size_t > label_
initial configuration for improving
double partialOptimality(std::vector< bool > &) const
#define OPENGM_ASSERT(expression)
Parameter for opengm::external::QPBO.
opengm::Minimizer AccumulationType
bool strongPersistency_
forcing strong persistency
GraphicalModelType::IndexType IndexType
GraphicalModelType::ValueType ValueType
visitors::TimingVisitor< QPBO< GM > > TimingVisitorType
Inference algorithm interface.
InferenceTermination arg(std::vector< LabelType > &, const size_t &=1) const
virtual GM::ValueType bound() const
return a bound on the solution
InferenceTermination infer()
virtual GM::ValueType value() const
return the solution (value)
visitors::EmptyVisitor< QPBO< GM > > EmptyVisitorType
Minimization as a unary accumulation.
bool useImproveing_
using improving technique
QPBO(const GraphicalModelType &gm, const Parameter para=Parameter())
const GraphicalModelType & graphicalModel() const