12 template<
class INDEX_TYPE>
16 : maxSize_(maxIndex+1),
17 indexInSet_(maxIndex+1,0),
24 if(indexInSet_[index]==0){
25 setElements_[setSize_]=index;
30 return indexInSet_[index]!=0;
34 for(
size_t i=0;i<setSize_;++i){
35 indexInSet_[setElements_[i]]=0;
40 std::vector<unsigned char> indexInSet_;
41 std::vector<INDEX_TYPE > setElements_;
49 template<
class GM,
class ACC>
50 class HighLevelFusionMover{
52 typedef ACC AccumulationType;
54 typedef GM GraphicalModelType;
56 typedef double QpboValueType
61 typedef detail_fusion::ViewFixVariablesFunction<GM> FixFunction;
62 typedef detail_fusion::FuseViewFunction<GM> FuseViewingFunction;
63 typedef detail_fusion::FuseViewFixFunction<GM> FuseViewingFixingFunction;
64 typedef ExplicitFunction<ValueType, IndexType, LabelType> ArrayFunction;
70 typedef kolmogorov::qpbo::QPBO<QpboValueType> QpboType;
74 typedef std::vector<LabelType> StateVector;
87 struct ReductionParameter
92 bool ConnectedComponents_;
94 const bool Persistency=
false,
95 const bool Tentacle=
false,
96 const bool ConnectedComponents=
true
99 Persistency_ (Persistency),
100 Tentacle_ (Tentacle),
101 ConnectedComponents_ (ConnectedComponents)
107 struct FusionSolverParam{
109 const size_t subgraphSize=3,
110 const size_t steps=0,
111 const double damping=0.75
114 subgraphSize_(subgraphSize),
118 size_t subgraphSize_;
124 enum UnknownStateBehavior{
135 const FusionSolver fusionSolver = DefaultFusionSolver,
136 const bool useReduction =
true,
137 const ReductionParameter & reductionParameter = ReductionParameter(),
138 const UnknownStateBehavior unknownStateBehavior = TakeA
140 : fusionSolver_(fusionSolver),
141 useReduction_(useReduction),
142 reductionParameter_(reductionParameter),
143 unknownStateBehavior_(unknownStateBehavior){
146 FusionSolver fusionSolver_;
148 ReductionParameter reductionParameter_;
149 UnknownStateBehavior unknownStateBehavior_;
153 struct FusionMoveResult{
154 bool changeOrImprovement_;
158 HighLevelFusionMover(
const GM & gm,
const Parameter & parameter)
160 parameter_(parameter){
162 this->setUpParameter();
167 FusionMoveResult fuse(
168 const StateVector & proposalLabelsA,
169 const StateVector & proposalLabelsB,
170 StateVector & resultLabels
173 this->getForwardBackwardMapping(proposalLabelsA,proposalLabelsB);
175 return fuse2Impl(proposalLabelsA,proposalLabelsB,resultLabels);
179 FusionMoveResult fuse(
180 const StateVector & proposalLabelsA,
181 StateVector & proposalLabelsBAndResult,
184 this->getForwardBackwardMapping(proposalLabelsA,proposalLabelsB);
186 return fuse2Impl(proposalLabelsA,proposalLabelsBAndResult,proposalLabelsBAndResult);
190 template<
class PROPOSAL_LABEL_ITERATOR>
191 FusionMoveResult fuse(
192 PROPOSAL_LABEL_ITERATOR proposalLabelsBegin,
193 PROPOSAL_LABEL_ITERATOR proposalLabelsEnd,
194 StateVector & resultLabels
197 raise RuntimeError(
"not yet implemented");
201 template<
class PROPOSAL_LABELS_A,
class PROPOSAL_LABELS_B>
202 void getForwardBackwardMapping(
203 const PROPOSAL_LABELS_A & proposalLabelsA,
204 const PROPOSAL_LABELS_B & proposalLabelsB
207 for (IndexType vi = 0; vi < gm_.numberOfVariables(); ++vi)
209 if (proposalLabelsA[vi] != proposalLabelsB[vi])
211 localToGlobalVi_[nLocalVar_] = vi;
212 globalToLocalVi_[vi] = nLocalVar_;
218 template<
class PROPOSAL_LABELS_A,
class PROPOSAL_LABELS_B,
class MODEL_PROXY>
219 void setupSubmodelProxy(
220 const PROPOSAL_LABELS_A & proposalLabelsA,
221 const PROPOSAL_LABELS_B & proposalLabelsB
222 MODEL_PROXY & modelProxy
225 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
227 const IndexType fi = gm_.factorOfVariable(vi, f);
228 const IndexType fOrder = gm_.numberOfVariables(fi);
233 OPENGM_CHECK_OP( localToGlobalVi_[lvi], == , gm_[fi].variableIndex(0),
"internal error");
234 OPENGM_CHECK_OP( globalToLocalVi_[gm_[fi].variableIndex(0)], == , lvi,
"internal error");
236 const IndexType vis[] = {lvi};
237 const IndexType globalVi = localToGlobalVi_[lvi];
241 ArrayFunction f(&aTwo,&aTwo+1);
242 const LabelType c[] = { proposalLabelsA[globalVi],proposalLabelsB[globalVi]};
244 f(1) = gm_[fi](c + 1);
245 modelProxy.addFactor(f, vis, vis + 1);
248 else if ( addedFactors_.hasIndex(fi) == false )
250 addedFactors_.insert(fi);
251 IndexType fixedVar = 0;
252 IndexType notFixedVar = 0;
254 for (IndexType vf = 0; vf < fOrder; ++vf)
256 const IndexType viFactor = gm_[fi].variableIndex(vf);
257 if (proposalLabelsA[viFactor] != proposalLabelsB[viFactor])
268 std::vector<IndexType> lvis(fOrder);
269 for (IndexType vf = 0; vf < fOrder; ++vf)
270 lvis[vf] = globalToLocalVi_[gm_[fi].variableIndex(vf)];
272 FuseViewingFunction f(gm_[fi], *argA_, *argB_);
273 modelProxy.addFactor(f, lvis.begin(), lvis.end());
280 std::vector<IndexType> lvis;
281 lvis.reserve(notFixedVar);
282 for (IndexType vf = 0; vf < fOrder; ++vf)
284 const IndexType gvi = gm_[fi].variableIndex(vf);
285 if ( proposalLabelsA[gvi] != proposalLabelsB[gvi])
286 lvis.push_back(globalToLocalVi_[gvi]);
289 FuseViewingFixingFunction f(gm_[fi], *argA_, *argB_);
290 modelProxy.addFactor(f, lvis.begin(), lvis.end());
294 addedFactors_.removeAll();
297 template<
class PROPOSAL_LABELS_A,
class PROPOSAL_LABELS_B,
class PROPOSAL_LABELS_RESULT>
298 FusionMoveResult fuse2Impl(
299 const PROPOSAL_LABELS_A & proposalLabelsA,
300 const PROPOSAL_LABELS_B & proposalLabelsB,
301 PROPOSAL_LABELS_RESULT & proposalLabelsResult
307 if(param_.fusionSolver_==QpboFusionSolver)
308 return this->fuse2Qpbo(proposalLabelsA,proposalLabelsB,proposalLabelsResult);
314 template<
class PROPOSAL_LABELS_A,
class PROPOSAL_LABELS_B,
class PROPOSAL_LABELS_RESULT>
315 FusionMoveResult fuse2Qpbo(
316 const PROPOSAL_LABELS_A & proposalLabelsA,
317 const PROPOSAL_LABELS_B & proposalLabelsB,
318 PROPOSAL_LABELS_RESULT & proposalLabelsResult
320 if(maxFactorOrder_<=2)
321 return this->fuse2QpboImproment2Order(proposalLabelsA,proposalLabelsB,proposalLabelsResult);
323 return this->fuse2QpboAnyOrder(proposalLabelsA,proposalLabelsB,proposalLabelsResult);
326 template<
class PROPOSAL_LABELS_A,
class PROPOSAL_LABELS_B,
class PROPOSAL_LABELS_RESULT>
327 FusionMoveResult fuse2Native(
328 const PROPOSAL_LABELS_A & proposalLabelsA,
329 const PROPOSAL_LABELS_B & proposalLabelsB,
330 PROPOSAL_LABELS_RESULT & proposalLabelsResult
335 template<
class PROPOSAL_LABELS_A,
class PROPOSAL_LABELS_B,
class PROPOSAL_LABELS_RESULT>
336 FusionMoveResult fuse2QpboImproment2Order(
337 const PROPOSAL_LABELS_A & proposalLabelsA,
338 const PROPOSAL_LABELS_B & proposalLabelsB,
339 PROPOSAL_LABELS_RESULT & proposalLabelsResult
344 setupSubmodelProxy(proposalLabelsA,proposalLabelsB,qpboModelProxy_);
348 qpboModelProxy_.model_->Improve();
351 if(param_.unknownStateBehavior_==TakeA || param_.unknownStateBehavior_==TakeB){
352 for (IndexType lvi = 0; lvi < nLocalVar_; ++lvi)
354 const IndexType globalVi = localToGlobalVi_[lvi];
355 const LabelType l = modelProxy.model_->GetLabel(lvi);
357 proposalLabelsResult[globalVi] = proposalLabelsA)[globalVi] ;
359 proposalLabelsResult[globalVi] = proposalLabelsB[globalVi] ;
362 if(param_.unknownStateBehavior_==TakeA )
363 proposalLabelsResult[globalVi] = proposalLabelsA)[globalVi] ;
365 proposalLabelsResult[globalVi] = proposalLabelsB)[globalVi] ;
370 throw RuntimeError(
"not yet implemented");
375 qpboModelProxy_.reset();
377 return FusionMoveResult();
380 throw RuntimeError(
"fuse2QpboImproment2Order needs WITH_QPBO to be enabled");
381 return FusionMoveResult();
385 template<
class PROPOSAL_LABELS_A,
class PROPOSAL_LABELS_B,
class PROPOSAL_LABELS_RESULT>
386 FusionMoveResult fuse2QpboAnyOrder(
387 const PROPOSAL_LABELS_A & proposalLabelsA,
388 const PROPOSAL_LABELS_B & proposalLabelsB,
389 PROPOSAL_LABELS_RESULT & proposalLabelsResult
400 void setUpParameter(){
406 const Parameter parameter_;
412 size_t maxFactorOrder_;
414 std::vector<IndexType> localToGlobalVi_;
415 std::vector<IndexType> globalToLocalVi_;
416 IndexType nLocalVar_;
426 detail_fusion::QpboModelProxy<QpboType> qpboModelProxy_;
IntegralUnorderedMaxSizeSet(const size_t maxIndex)
#define OPENGM_CHECK_OP(A, OP, B, TXT)
void insert(const IndexType index)
#define OPENGM_GM_TYPE_TYPEDEFS