10 #include <boost/format.hpp>
11 #include <boost/unordered_set.hpp>
34 template<
class GM,
class LABELS_ITER>
39 typedef typename GM::IndexType IndexType;
44 for(IndexType vi=0;vi<gm.numberOfVariables();++vi){
45 const LabelType label=labels[vi];
46 const IndexType numFacVar =
static_cast<IndexType
>(gm.numberOfFactors(vi));
47 for(IndexType f=0;f<numFacVar;++f){
48 const IndexType fi = gm.factorOfVariable(vi,f);
49 const IndexType numVarFac = gm[fi].numberOfVariables();
50 for(
size_t v=0;v<numVarFac;++v){
51 const IndexType vi2=gm[fi].variableIndex(v);
52 const LabelType label2=labels[vi2];
53 if(vi!=vi2 && label==label2){
59 std::map<IndexType,IndexType> repLabeling;
60 ufd.representativeLabeling(repLabeling);
61 const size_t numberOfCCs=ufd.numberOfSets();
63 for(IndexType vi=0;vi<gm.numberOfVariables();++vi){
64 IndexType findVi=ufd.find(vi);
65 IndexType denseRelabling=repLabeling[findVi];
66 labels[vi]=denseRelabling;
78 template<
class CT,
class C,
class FP,
class F>
85 typedef typename CT::value_type ToFindType;
86 typedef typename FP::value_type ResultTypePosition;
88 typedef std::map<ToFindType,size_t> MapType;
89 typedef typename MapType::const_iterator MapIter;
90 MapType toFindPosition;
91 for(
size_t i=0;i<toFind.size();++i){
92 toFindPosition.insert(std::pair<ToFindType,size_t>(toFind[i],i));
98 for(
size_t i=0;i<container.size();++i){
99 const ToFindType value = container[i];
100 MapIter findVal=toFindPosition.find(value);
102 if( findVal!=toFindPosition.end()){
103 const size_t posInToFind = findVal->second;
104 if(found[posInToFind]==
false){
105 position[posInToFind]=
static_cast<ResultTypePosition
>(i);
106 found[posInToFind]=
true;
109 if(numFound==toFind.size()){
120 template<
class GM,
class ACC>
140 const bool planar =
true,
141 const size_t maxIterations = 1,
142 const bool useBookkeeping =
true,
143 const double threshold = 0.0,
145 const bool doCutMove =
true,
146 const bool doGlueCutMove =
true
170 std::string
name()
const;
175 return bound_+energyOffset_;
178 return value_+energyOffset_;
183 template<
class VisitorType>
199 bool inRecursive2Coloring()
const{
200 return inRecursive2Coloring_;
202 bool inGreedy2Coloring()
const{
203 return inGreedy2Coloring_;
206 void findActiveFactors(std::vector<IndexType> activeFactors){
207 activeFactors.clear();
210 activeFactors.push_back(fi);
214 LabelType setStartingPointFromArgPrimal(
const bool fillQ);
219 template<
class VISITOR>
220 void recursive2Coloring(VISITOR & visitor);
222 template<
class VISITOR>
223 void greedy2ColoringPlanar(VISITOR & visitor);
226 const GraphicalModelType& gmRaw_;
232 std::vector<ValueType> lambdas_;
246 std::vector<LabelType> argPrimal_;
247 std::vector<LabelType> argDual_;
251 std::deque<IndexType> toSplit_;
254 bool inRecursive2Coloring_;
255 bool inGreedy2Coloring_;
260 std::vector<unsigned char> dirtyFactors_;
269 template<
class GM,
class ACC>
273 const GraphicalModelType& gm,
281 numVar_(gm.numberOfVariables()),
285 argPrimal_(gm.numberOfVariables(),0),
288 inRecursive2Coloring_(
false),
289 inGreedy2Coloring_(
false),
298 typedef std::map<UInt64Type,ValueType> MapType;
304 for(IndexType fi=0;fi<gm.numberOfFactors();++fi){
306 const ValueType o = gm[fi].operator()(lAA);
307 const ValueType l = gm[fi].operator()(lAB)-o;
310 const UInt64Type key = gm[fi].variableIndex(0)*gm.numberOfVariables() + gm[fi].variableIndex(1);
312 if(factorMap.find(key)==factorMap.end() ){
323 for(
typename MapType::const_iterator iter=factorMap.begin(); iter!=factorMap.end(); ++iter){
327 const UInt64Type v0 = key/gm.numberOfVariables();
328 const UInt64Type v1 = key - v0*gm.numberOfVariables();
331 PfType f(gm.numberOfLabels(v0),gm.numberOfLabels(v1),0.0,lambda);
332 gm_.addFactor( gm_.addFunction(f) ,vis,vis+2);
335 numDualVar_=gm_.numberOfFactors();
336 argDual_.resize(numDualVar_);
337 dirtyFactors_.resize(numDualVar_);
338 lambdas_.resize(numDualVar_);
346 for(IndexType f=0;f<numDualVar_;++f){
348 OPENGM_CHECK(gm_[f].isPotts(),
"all factors need to be potts factors");
349 OPENGM_CHECK_OP(gm_[f].numberOfVariables(),==,2,
"all factors need to 2. order");
351 const ValueType o = gm_[f].operator()(lAA);
354 const ValueType lambda=gm_[f].operator()(lAB) - o;
365 template<
class GM,
class ACC>
366 template<
class VisitorType>
374 visitor.begin(*
this);
375 if(param_.startFromThreshold_)
377 for(IndexType f=0;f<numDualVar_;++f){
378 const IndexType v1=gm_[f].variableIndex(0);
379 const IndexType v2=gm_[f].variableIndex(1);
384 for(
size_t i=0;i<param_.maxIterations_;++i){
385 if(!timeout_ && param_.doCutMove_ && ( value_<valA || i==0)){
387 this->recursive2Coloring(visitor);
390 if(!timeout_ && param_.doGlueCutMove_ && (value_<valB || i==0)){
392 this->greedy2ColoringPlanar(visitor);
404 template<
class GM,
class ACC>
405 template<
class VISITOR>
409 inRecursive2Coloring_=
true;
410 inGreedy2Coloring_=
false;
413 const LabelType numCCsStart=this->setStartingPointFromArgPrimal(
true);
418 while(!toSplit_.empty()){
423 const LabelType exampleVariableInCC = toSplit_.front();
424 toSplit_.pop_front();
425 const LabelType ccColor = argPrimal_[exampleVariableInCC];
429 IVPairType res = submodel_->inferSubset(argPrimal_,ccColor,exampleVariableInCC,maxColor_+1,toSplit_,param_.planar_,
false );
430 const int numCCArg = res.first;
431 const ValueType value2Coloring = res.second;
438 maxColor_ += numCCArg+1;
440 value_ += value2Coloring;
441 if(visitor(*
this)!=0){
450 inRecursive2Coloring_=
false;
451 inGreedy2Coloring_=
false;
453 const LabelType numCCsEnd=this->setStartingPointFromArgPrimal(
false);
457 template<
class GM,
class ACC>
458 template<
class VISITOR>
460 CGC<GM, ACC>::greedy2ColoringPlanar(VISITOR & visitor){
462 inRecursive2Coloring_=
false;
463 inGreedy2Coloring_=
true;
475 for(IndexType fi=0;fi<dirtyFactors_.size();++fi){
476 if(dirtyFactors_[fi]!=2)
481 while(changes && timeout_==
false){
485 const LabelType numCCsStart=this->setStartingPointFromArgPrimal(
false);
492 typedef std::map< opengm::UInt64Type , IndexType > MapType;
493 typedef typename MapType::const_iterator MapIter;
495 for(IndexType fi=0;fi<numDualVar_;++fi){
496 const LabelType c0 = argPrimal_[ gm_[fi].variableIndex(0) ];
497 const LabelType c1 = argPrimal_[ gm_[fi].variableIndex(1) ];
498 const KeyType cA =
static_cast<KeyType
>(std::min(c0,c1));
499 const KeyType cB =
static_cast<KeyType
>(std::max(c0,c1));
501 const KeyType key = cA + cB*
static_cast<KeyType
>(maxColor_+1);
507 for(MapIter iter=factorCCs.begin();iter!=factorCCs.end();++iter){
508 const IndexType fi = iter->second;
509 if(param_.useBookkeeping_==
false || dirtyFactors_[fi] == 1 ){
512 const LabelType c0 = argPrimal_[ gm_[fi].variableIndex(0) ];
513 const LabelType c1 = argPrimal_[ gm_[fi].variableIndex(1) ];
518 IVPairType res = submodel_->infer2Subsets(
520 gm_[fi].variableIndex(0),gm_[fi].variableIndex(1),
524 const int numCCArg = res.first;
525 const ValueType value2Coloring = res.second;
539 else if(numCCArg==-2){
541 if(param_.useBookkeeping_)
542 submodel_->updateDirtyness(dirtyFactors_,
false);
545 else if(numCCArg>=1){
551 maxColor_+=numCCArg+1;
552 value_+=value2Coloring;
553 if(param_.useBookkeeping_){
554 submodel_->updateDirtyness(dirtyFactors_,
true);
558 if(visitor(*
this)!=0){
563 submodel_->cleanInsideAndBorder();
571 inRecursive2Coloring_=
false;
572 inGreedy2Coloring_=
false;
574 const LabelType numCCsEnd=this->setStartingPointFromArgPrimal(
false);
579 template<
class GM,
class ACC>
585 template<
class GM,
class ACC>
591 std::copy(begin,begin+numVar_,argPrimal_.begin());
592 const LabelType numCC=this->setStartingPointFromArgPrimal(
true);
595 template<
class GM,
class ACC>
605 this->primalToDual();
606 value_ = evalPrimal();
611 std::vector<LabelType> toFind(numCC);
612 std::vector<bool> found(numCC,
false);
613 std::vector<IndexType> foundPosition(numCC);
619 for(IndexType c=0;c<numCC;++c){
620 toSplit_.push_back(foundPosition[c]);
626 template<
class GM,
class ACC>
633 template<
class GM,
class ACC>
640 template<
class GM,
class ACC>
651 template<
class GM,
class ACC>
655 std::vector<LabelType>& x,
660 x.resize(gm_.numberOfVariables());
661 for(
size_t j=0; j<x.size(); ++j) {
662 x[j] = argPrimal_[j];
672 template<
class GM,
class ACC>
675 for(IndexType f=0;f<numDualVar_;++f){
676 const IndexType v1=gm_[f].variableIndex(0);
677 const IndexType v2=gm_[f].variableIndex(1);
678 argDual_[f] = argPrimal_[v1]==argPrimal_[v2] ? 0 :1 ;
683 template<
class GM,
class ACC>
684 inline typename CGC<GM, ACC>::ValueType
689 for(IndexType f=0;f<numDualVar_;++f){
690 const IndexType v1=gm_[f].variableIndex(0);
691 const IndexType v2=gm_[f].variableIndex(1);
692 if(argP[v1]!=argP[v2])
699 template<
class GM,
class ACC>
703 for(IndexType f=0;f<numDualVar_;++f){
704 const IndexType v1=gm_[f].variableIndex(0);
705 const IndexType v2=gm_[f].variableIndex(1);
706 if(argPrimal_[v1]!=argPrimal_[v2])
713 template<
class GM,
class ACC>
716 ValueType value = 0.0;
717 for(IndexType f=0;f<numDualVar_;++f){
728 #endif // #ifndef OPENGM_CGC_HXX
virtual InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
const GraphicalModelType & graphicalModel() const
Parameter(const bool planar=true, const size_t maxIterations=1, const bool useBookkeeping=true, const double threshold=0.0, const bool startFromThreshold=true, const bool doCutMove=true, const bool doGlueCutMove=true)
void findFirst(const CT &toFind, const C &container, FP &position, F &found)
CGC(const GraphicalModelType &, const Parameter ¶m=Parameter())
ValueType evalPrimal() const
void merge(value_type, value_type)
Merge two sets.
visitors::VerboseVisitor< CGC< GM, ACC > > VerboseVisitorType
detail_types::UInt64Type UInt64Type
uint64
ValueType value() const
return the solution (value)
ValueType evalPrimal2(const std::vector< LabelType > &) const
PottsFunction< ValueType, IndexType, LabelType > PfType
GraphicalModelType::IndexType IndexType
void setStartingPoint(typename std::vector< LabelType >::const_iterator)
set initial labeling
visitors::EmptyVisitor< CGC< GM, ACC > > EmptyVisitorType
GM::IndexType getCCFromLabels(const GM &gm, LABELS_ITER labels)
GraphicalModelType::ValueType ValueType
Inference algorithm interface.
visitors::TimingVisitor< CGC< GM, ACC > > TimingVisitorType
InferenceTermination infer()
GraphicalModel< ValueType, Adder, PfType, typename GM::SpaceType > PottsGmType
#define OPENGM_CHECK_OP(A, OP, B, TXT)
Potts function for two variables.
Disjoint set data structure with path compression.
#define OPENGM_CHECK(B, TXT)
GraphicalModelType::LabelType LabelType
std::pair< int, ValueType > IVPairType
void startFromThreshold(const GM &gm, std::vector< typename GM::ValueType > &lambdas, std::vector< typename GM::LabelType > &resultArg, const typename GM::ValueType threshold=0.0)
ValueType bound() const
return a bound on the solution