52 template<
class GM,
class ACC>
89 template<
class _GM,
class _ACC>
105 const std::string solver=
"ad3",
106 const double phi = 0.3,
107 const size_t maxBlockRadius = 50,
108 const size_t maxTreeRadius = 50,
109 const double pFastHeuristic = 0.9,
110 const size_t maxIterations = 100000,
111 const size_t stopAfterNBadIterations=10000,
112 const size_t maxBlockSize = 0,
113 const size_t maxTreeSize =0,
114 const int treeRuns =1
118 maxBlockRadius_(maxBlockRadius),
119 maxTreeRadius_(maxTreeRadius),
120 pFastHeuristic_(pFastHeuristic),
121 maxIterations_(maxIterations),
122 stopAfterNBadIterations_(stopAfterNBadIterations),
123 maxBlockSize_(maxBlockSize),
134 : solver_(p.solver_),
136 maxBlockRadius_(p.maxBlockRadius_),
137 maxTreeRadius_(p.maxTreeRadius_),
138 pFastHeuristic_(p.pFastHeuristic_),
139 maxIterations_(p.maxIterations_),
140 stopAfterNBadIterations_(p.stopAfterNBadIterations_),
141 maxBlockSize_(p.maxBlockSize_),
142 treeRuns_(p.treeRuns_)
169 std::string
name()
const;
173 template<
class VisitorType>
180 template<
class VI_ITER>
182 const IndexType nVis=std::distance(begin,end);
186 const IndexType nNVar = viAdjacency_[vi].size();
188 const IndexType vio=viAdjacency_[vi][vo];
189 if( subOptimizer_.inSubmodel(vio)==
false){
190 cleanRegion_[vio]=
false;
196 template<
class VI_ITER>
198 const IndexType nVis=std::distance(begin,end);
202 cleanRegion_[vi]=
true;
207 template<
class VI_ITER>
209 const IndexType nVis=std::distance(begin,end);
214 if(cleanRegion_[vi]==
false){
224 void getSubgraphVis(
const size_t,
const size_t, std::vector<size_t>&);
225 void getSubgraphTreeVis(
const size_t,
const size_t, std::vector<size_t>&);
226 void inline initializeProbabilities(std::vector<double>&,
const size_t maxRadius);
227 const GraphicalModelType& gm_;
228 MovemakerType movemaker_;
230 std::vector< RandomAccessSet<IndexType> > viAdjacency_;
231 std::vector<bool> usedVi_;
232 std::vector<bool> checkedVi_;
233 std::vector<UInt64Type> distance_;
237 SubOptimizer subOptimizer_;
240 std::vector<bool> cleanRegion_;
244 bool optimizeSubmodel(std::vector<size_t> & subgraphVi,
const bool);
247 template<
class GM,
class ACC>
250 const GraphicalModelType& gm,
256 viAdjacency_(gm.numberOfVariables()),
257 usedVi_(gm.numberOfVariables(),
false),
258 checkedVi_(gm.numberOfVariables(),
false),
259 distance_(gm.numberOfVariables()),
261 cleanRegion_(gm.numberOfVariables(),
false)
265 gm.variableAdjacencyList(viAdjacency_);
266 if(this->param_.maxIterations_==0)
267 param_.maxIterations_ = gm_.numberOfVariables() *
268 log(
double(gm_.numberOfVariables()))*log(
double(gm_.numberOfVariables()));
271 template<
class GM,
class ACC>
276 std::fill(usedVi_.begin(),usedVi_.end(),
false);
280 if(this->param_.maxIterations_==0)
281 param_.maxIterations_ = gm_.numberOfVariables() *
282 log(
double(gm_.numberOfVariables()))*log(
double(gm_.numberOfVariables()));
285 template<
class GM,
class ACC>
292 movemaker_.initialize(begin);
299 template<
class GM,
class ACC>
303 return this->movemaker_.value();
306 template<
class GM,
class ACC>
310 std::vector<double>& prob,
const size_t maxRadius
314 const double phi = param_.phi_;
315 prob.resize(maxRadius);
316 for(
size_t i=0;i<maxRadius-1;++i) {
317 prob[i] = phi * pow((1.0-phi), static_cast<double>(i));
319 prob[maxRadius-1]= pow((1.0-phi), static_cast<double>(maxRadius));
323 template<
class GM,
class ACC>
329 template<
class GM,
class ACC>
335 template<
class GM,
class ACC>
338 const size_t startVi,
340 std::vector<size_t>& vis
342 std::fill(usedVi_.begin(),usedVi_.end(),
false);
344 vis.push_back(startVi);
345 usedVi_[startVi]=
true;
346 std::queue<size_t> viQueue;
347 viQueue.push(startVi);
349 std::fill(distance_.begin(),distance_.begin()+gm_.numberOfVariables(),0);
351 const size_t maxSgSize = (param_.maxBlockSize_==0? gm_.numberOfVariables() :param_.maxBlockSize_);
352 while(viQueue.size()!=0 && vis.size()<=maxSgSize) {
353 size_t cvi=viQueue.front();
356 for(
size_t vni=0;vni<viAdjacency_[cvi].size();++vni) {
358 const size_t vn=viAdjacency_[cvi][vni];
359 if(usedVi_[vn]==
false) {
363 distance_[vn]=distance_[cvi]+1;
364 if(distance_[vn]<=radius){
365 if(vis.size()<maxSgSize){
379 template<
class GM,
class ACC>
382 const size_t startVi,
384 std::vector<size_t>& vis
388 std::fill(usedVi_.begin(),usedVi_.end(),
false);
389 std::fill(checkedVi_.begin(),checkedVi_.end(),
false);
391 vis.push_back(startVi);
392 usedVi_[startVi]=
true;
393 checkedVi_[startVi]=
true;
394 std::deque<IndexType> viQueue;
395 viQueue.push_back(startVi);
398 const size_t maxSgSize = (param_.maxTreeSize_==0? gm_.numberOfVariables() :param_.maxTreeSize_);
400 std::fill(distance_.begin(),distance_.begin()+gm_.numberOfVariables(),0);
403 while(viQueue.size()!=0 && vis.size()<=maxSgSize) {
412 if(checkedVi_[cvi]==
true && first ==
false){
417 size_t includeInTree=0;
419 for(
size_t vni=0;vni<viAdjacency_[cvi].size();++vni) {
420 const IndexType vn=viAdjacency_[cvi][vni];
421 if(usedVi_[vn]==
true) {
428 checkedVi_[cvi]=
true;
430 OPENGM_CHECK(includeInTree>0 || (vis.size()==1 && includeInTree==0),
"");
432 if (includeInTree<=1){
435 if(usedVi_[cvi]==
false){
440 if(vis.size()>=maxSgSize){
445 std::vector<IndexType> adjVis(viAdjacency_[cvi].size());
446 for(
size_t vni=0;vni<viAdjacency_[cvi].size();++vni) {
447 const size_t vn=viAdjacency_[cvi][vni];
450 std::random_shuffle(adjVis.begin(),adjVis.end());
453 for(
size_t vni=0;vni<viAdjacency_[cvi].size();++vni) {
456 const size_t vn=adjVis[vni];
458 if(usedVi_[vn]==
false && checkedVi_[vn]==
false) {
462 distance_[vn]=distance_[cvi]+1;
463 if(distance_[vn]<=radius)
464 viQueue.push_back(vn);
474 template<
class GM,
class ACC>
481 template<
class GM,
class ACC>
482 template<
class VisitorType>
490 const bool useTrees = param_.maxTreeRadius_ > 0;
491 const bool useBlocks = param_.maxBlockRadius_ > 0;
495 visitor.begin(*
this);
497 opengm::RandomUniform<size_t> randomVariable(0, gm_.numberOfVariables());
498 opengm::RandomUniform<double> random01(0.0, 1.0);
500 std::vector<double> probBlock,probTree;
501 opengm::RandomDiscreteWeighted<size_t, double> randomRadiusBlock,randomRadiusTree;
504 this->initializeProbabilities(probBlock,param_.maxBlockRadius_);
505 randomRadiusBlock =opengm::RandomDiscreteWeighted<size_t, double> (probBlock.begin(), probBlock.end());
508 this->initializeProbabilities(probTree,param_.maxTreeRadius_);
509 randomRadiusTree= opengm::RandomDiscreteWeighted<size_t, double> (probTree.begin(), probTree.end());
514 std::vector<size_t> subgGraphViBLock;
515 std::vector<size_t> subgGraphViTree;
522 for(
IndexType vi=0;vi<gm_.numberOfVariables();++vi){
523 subOptimizer_.setLabel(vi,movemaker_.state(vi));
528 std::vector<bool> coverdVar(gm_.numberOfVariables(),
false);
530 for(
IndexType vi=0;vi<gm_.numberOfVariables();++vi){
531 if(coverdVar[vi]==
false){
534 size_t radiusBlock = (useBlocks ? randomRadiusBlock()+1 : 0);
535 size_t radiusTree = (useTrees ? randomRadiusTree()+1 : 0);
545 if(param_.treeRuns_>0){
546 for(
size_t tr=0;tr<(
size_t)(param_.treeRuns_);++tr){
547 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
548 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
549 optimizeSubmodel(subgGraphViTree,
true);
553 size_t nTr=(param_.treeRuns_==0? 1:
std::abs(param_.treeRuns_));
556 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
557 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
559 for(
size_t tr=0;tr<nTr;++tr){
560 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
561 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
562 bool c=optimizeSubmodel(subgGraphViTree,
true);
572 this->getSubgraphVis(viStart, radiusBlock, subgGraphViBLock);
573 std::sort(subgGraphViBLock.begin(), subgGraphViBLock.end());
574 optimizeSubmodel(subgGraphViBLock,
false);
576 for(
IndexType lvi=0;lvi<subgGraphViBLock.size();++lvi){
577 coverdVar[subgGraphViBLock[lvi]]=
true;
588 for(
size_t i=0;i<0;++i) {
594 size_t viStart = randomVariable();
596 size_t radiusBlock = (useBlocks ? randomRadiusBlock()+1 : 0);
597 size_t radiusTree = (useTrees ? randomRadiusTree()+1 : 0);
607 if(param_.treeRuns_>0){
608 for(
size_t tr=0;tr<(
size_t)(param_.treeRuns_);++tr){
609 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
610 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
611 optimizeSubmodel(subgGraphViTree,
true);
615 size_t nTr=(param_.treeRuns_==0? 1:
std::abs(param_.treeRuns_));
618 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
619 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
621 for(
size_t tr=0;tr<nTr;++tr){
622 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
623 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
624 bool c=optimizeSubmodel(subgGraphViTree,
true);
634 this->getSubgraphVis(viStart, radiusBlock, subgGraphViBLock);
635 std::sort(subgGraphViBLock.begin(), subgGraphViBLock.end());
636 optimizeSubmodel(subgGraphViBLock,
false);
645 std::cout<<
"basic inference is done\n";
650 template<
class GM,
class ACC>
654 std::vector<LabelType> states;
655 if(subgGraphVi.size()>2){
656 subOptimizer_.setVariableIndices(subgGraphVi.begin(), subgGraphVi.end());
661 changes = subOptimizer_.mergeFactorsAndInferDp(states);
667 else if(param_.solver_==std::string(
"ad3")){
671 else if (param_.solver_==std::string(
"astar")){
674 else if (param_.solver_==std::string(
"cplex")){
677 typename LpCplexSubInf::Parameter subParam;
678 subParam.integerConstraint_=
true;
679 changes = subOptimizer_.
template inferSubmodel<LpCplexSubInf>(subParam ,states);
681 throw RuntimeError(
"solver cplex needs flag WITH_CPLEX defined bevore the #include of LOC sovler");
685 else if(param_.solver_[0]==
'l' && param_.solver_[1]==
'f'){
686 std::stringstream ss;
687 for(
size_t i=2;i<param_.solver_.size();++i){
688 ss<<param_.solver_[i];
692 changes = subOptimizer_.
template inferSubmodel<LfSubInf>(
typename LfSubInf::Parameter(maxSgSize) ,states,
true,
true);
695 subOptimizer_.unsetVariableIndices();
698 movemaker_.move(subgGraphVi.begin(), subgGraphVi.end(), states.begin());
699 for(
IndexType v=0;v<subgGraphVi.size();++v){
700 subOptimizer_.setLabel(subgGraphVi[v],movemaker_.state(subgGraphVi[v]));
712 template<
class GM,
class ACC>
716 std::vector<LabelType>& x,
720 x.resize(gm_.numberOfVariables());
721 for(
size_t j = 0; j < x.size(); ++j) {
722 x[j] = movemaker_.state(j);
732 #endif // #ifndef OPENGM_LOC_HXX InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
Update rules for the MessagePassing framework.
Update rules for the MessagePassing framework.
double phi_
phi of the truncated geometric distribution is used to select a certain subgraph radius with a certai...
opengm::LazyFlipper< SubGmType, AccumulationType > LfSubInf
LOC(const GraphicalModelType &, const Parameter ¶m=Parameter())
opengm::BeliefPropagationUpdateRules< SubGmType, AccumulationType > UpdateRulesTypeBp
opengm::visitors::VerboseVisitor< LOC< GM, ACC > > VerboseVisitorType
const GraphicalModelType & graphicalModel() const
A framework for message passing algorithms Cf. F. R. Kschischang, B. J. Frey and H...
opengm::TrbpUpdateRules< SubGmType, AccumulationType > UpdateRulesTypeTrbp
void setStartingPoint(typename std::vector< LabelType >::const_iterator)
set initial labeling
ValueType value() const
return the solution (value)
void setInsideClean(VI_ITER begin, VI_ITER end)
size_t stopAfterNBadIterations_
GraphicalModelType::IndexType IndexType
InferenceTermination infer()
opengm::MessagePassing< SubGmType, AccumulationType, UpdateRulesTypeTrbp, opengm::MaxDistance > TrBpSubInf
Movemaker< GraphicalModelType > MovemakerType
Optimization by Linear Programming (LP) or Integer LP using IBM ILOG CPLEX http://www.ilog.com/products/cplex/.
GraphicalModelType::ValueType ValueType
opengm::external::AD3Inf< SubGmType, AccumulationType > Ad3SubInf
Inference algorithm interface.
void setBorderDirty(VI_ITER begin, VI_ITER end)
SubOptimizer::SubGmType SubGmType
SubmodelOptimizer< GM, ACC > SubOptimizer
LOC Algorithm K. Jung, P. Kohli and D. Shah, "Local Rules for Global MAP: When Do They Work...
bool hasDirtyInsideVariables(VI_ITER begin, VI_ITER end)
opengm::MessagePassing< SubGmType, AccumulationType, UpdateRulesTypeBp, opengm::MaxDistance > BpSubInf
opengm::AStar< SubGmType, AccumulationType > AStarSubInf
#define OPENGM_CHECK_OP(A, OP, B, TXT)
double pFastHeuristic_
prob. of f
size_t maxIterations_
maximum number of iterations
opengm::visitors::EmptyVisitor< LOC< GM, ACC > > EmptyVisitorType
#define OPENGM_CHECK(B, TXT)
GraphicalModelType::LabelType LabelType
opengm::visitors::TimingVisitor< LOC< GM, ACC > > TimingVisitorType
opengm::DynamicProgramming< SubGmType, AccumulationType > DpSubInf
A generalization of ICM B. Andres, J. H. Kappes, U. Koethe and Hamprecht F. A., The Lazy Flipper: MA...
size_t maxBlockRadius_
maximum subgraph radius