52 template<
class GM,
class ACC>
95 const std::string solver=
"ad3",
96 const double phi = 0.3,
97 const size_t maxBlockRadius = 50,
98 const size_t maxTreeRadius = 50,
99 const double pFastHeuristic = 0.9,
100 const size_t maxIterations = 100000,
101 const size_t stopAfterNBadIterations=10000,
102 const size_t maxBlockSize = 0,
103 const size_t maxTreeSize =0,
104 const int treeRuns =1
140 std::string
name()
const;
144 template<
class VisitorType>
151 template<
class VI_ITER>
153 const IndexType nVis=std::distance(begin,end);
157 const IndexType nNVar = viAdjacency_[vi].size();
159 const IndexType vio=viAdjacency_[vi][vo];
160 if( subOptimizer_.inSubmodel(vio)==
false){
161 cleanRegion_[vio]=
false;
167 template<
class VI_ITER>
169 const IndexType nVis=std::distance(begin,end);
173 cleanRegion_[vi]=
true;
178 template<
class VI_ITER>
180 const IndexType nVis=std::distance(begin,end);
185 if(cleanRegion_[vi]==
false){
195 void getSubgraphVis(
const size_t,
const size_t, std::vector<size_t>&);
196 void getSubgraphTreeVis(
const size_t,
const size_t, std::vector<size_t>&);
197 void inline initializeProbabilities(std::vector<double>&,
const size_t maxRadius);
198 const GraphicalModelType& gm_;
199 MovemakerType movemaker_;
201 std::vector< RandomAccessSet<IndexType> > viAdjacency_;
202 std::vector<bool> usedVi_;
203 std::vector<bool> checkedVi_;
204 std::vector<UInt64Type> distance_;
208 SubOptimizer subOptimizer_;
211 std::vector<bool> cleanRegion_;
215 bool optimizeSubmodel(std::vector<size_t> & subgraphVi,
const bool);
218 template<
class GM,
class ACC>
221 const GraphicalModelType& gm,
227 viAdjacency_(gm.numberOfVariables()),
228 usedVi_(gm.numberOfVariables(),
false),
229 checkedVi_(gm.numberOfVariables(),
false),
230 distance_(gm.numberOfVariables()),
232 cleanRegion_(gm.numberOfVariables(),
false)
236 gm.variableAdjacencyList(viAdjacency_);
237 if(this->param_.maxIterations_==0)
238 param_.maxIterations_ = gm_.numberOfVariables() *
239 log(
double(gm_.numberOfVariables()))*log(
double(gm_.numberOfVariables()));
242 template<
class GM,
class ACC>
247 std::fill(usedVi_.begin(),usedVi_.end(),
false);
251 if(this->param_.maxIterations_==0)
252 param_.maxIterations_ = gm_.numberOfVariables() *
253 log(
double(gm_.numberOfVariables()))*log(
double(gm_.numberOfVariables()));
256 template<
class GM,
class ACC>
263 movemaker_.initialize(begin);
270 template<
class GM,
class ACC>
274 return this->movemaker_.value();
277 template<
class GM,
class ACC>
281 std::vector<double>& prob,
const size_t maxRadius
285 const double phi = param_.phi_;
286 prob.resize(maxRadius);
287 for(
size_t i=0;i<maxRadius-1;++i) {
288 prob[i] = phi * pow((1.0-phi), static_cast<double>(i));
290 prob[maxRadius-1]= pow((1.0-phi), static_cast<double>(maxRadius));
294 template<
class GM,
class ACC>
300 template<
class GM,
class ACC>
306 template<
class GM,
class ACC>
309 const size_t startVi,
311 std::vector<size_t>& vis
313 std::fill(usedVi_.begin(),usedVi_.end(),
false);
315 vis.push_back(startVi);
316 usedVi_[startVi]=
true;
317 std::queue<size_t> viQueue;
318 viQueue.push(startVi);
320 std::fill(distance_.begin(),distance_.begin()+gm_.numberOfVariables(),0);
322 const size_t maxSgSize = (param_.maxBlockSize_==0? gm_.numberOfVariables() :param_.maxBlockSize_);
323 while(viQueue.size()!=0 && vis.size()<=maxSgSize) {
324 size_t cvi=viQueue.front();
327 for(
size_t vni=0;vni<viAdjacency_[cvi].size();++vni) {
329 const size_t vn=viAdjacency_[cvi][vni];
330 if(usedVi_[vn]==
false) {
334 distance_[vn]=distance_[cvi]+1;
335 if(distance_[vn]<=radius){
336 if(vis.size()<maxSgSize){
350 template<
class GM,
class ACC>
351 void LOC<GM, ACC>::getSubgraphTreeVis
353 const size_t startVi,
355 std::vector<size_t>& vis
359 std::fill(usedVi_.begin(),usedVi_.end(),
false);
360 std::fill(checkedVi_.begin(),checkedVi_.end(),
false);
362 vis.push_back(startVi);
363 usedVi_[startVi]=
true;
364 checkedVi_[startVi]=
true;
365 std::deque<IndexType> viQueue;
366 viQueue.push_back(startVi);
369 const size_t maxSgSize = (param_.maxTreeSize_==0? gm_.numberOfVariables() :param_.maxTreeSize_);
371 std::fill(distance_.begin(),distance_.begin()+gm_.numberOfVariables(),0);
374 while(viQueue.size()!=0 && vis.size()<=maxSgSize) {
375 IndexType cvi=viQueue.front();
383 if(checkedVi_[cvi]==
true && first ==
false){
388 size_t includeInTree=0;
390 for(
size_t vni=0;vni<viAdjacency_[cvi].size();++vni) {
391 const IndexType vn=viAdjacency_[cvi][vni];
392 if(usedVi_[vn]==
true) {
399 checkedVi_[cvi]=
true;
401 OPENGM_CHECK(includeInTree>0 || (vis.size()==1 && includeInTree==0),
"");
403 if (includeInTree<=1){
406 if(usedVi_[cvi]==
false){
411 if(vis.size()>=maxSgSize){
416 std::vector<IndexType> adjVis(viAdjacency_[cvi].size());
417 for(
size_t vni=0;vni<viAdjacency_[cvi].size();++vni) {
418 const size_t vn=viAdjacency_[cvi][vni];
421 std::random_shuffle(adjVis.begin(),adjVis.end());
424 for(
size_t vni=0;vni<viAdjacency_[cvi].size();++vni) {
427 const size_t vn=adjVis[vni];
429 if(usedVi_[vn]==
false && checkedVi_[vn]==
false) {
433 distance_[vn]=distance_[cvi]+1;
434 if(distance_[vn]<=radius)
435 viQueue.push_back(vn);
445 template<
class GM,
class ACC>
452 template<
class GM,
class ACC>
453 template<
class VisitorType>
461 const bool useTrees = param_.maxTreeRadius_ > 0;
462 const bool useBlocks = param_.maxBlockRadius_ > 0;
466 visitor.begin(*
this);
468 opengm::RandomUniform<size_t> randomVariable(0, gm_.numberOfVariables());
469 opengm::RandomUniform<double> random01(0.0, 1.0);
471 std::vector<double> probBlock,probTree;
472 opengm::RandomDiscreteWeighted<size_t, double> randomRadiusBlock,randomRadiusTree;
475 this->initializeProbabilities(probBlock,param_.maxBlockRadius_);
476 randomRadiusBlock =opengm::RandomDiscreteWeighted<size_t, double> (probBlock.begin(), probBlock.end());
479 this->initializeProbabilities(probTree,param_.maxTreeRadius_);
480 randomRadiusTree= opengm::RandomDiscreteWeighted<size_t, double> (probTree.begin(), probTree.end());
485 std::vector<size_t> subgGraphViBLock;
486 std::vector<size_t> subgGraphViTree;
493 for(
IndexType vi=0;vi<gm_.numberOfVariables();++vi){
494 subOptimizer_.setLabel(vi,movemaker_.state(vi));
499 std::vector<bool> coverdVar(gm_.numberOfVariables(),
false);
501 for(
IndexType vi=0;vi<gm_.numberOfVariables();++vi){
502 if(coverdVar[vi]==
false){
505 size_t radiusBlock = (useBlocks ? randomRadiusBlock()+1 : 0);
506 size_t radiusTree = (useTrees ? randomRadiusTree()+1 : 0);
516 if(param_.treeRuns_>0){
517 for(
size_t tr=0;tr<(
size_t)(param_.treeRuns_);++tr){
518 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
519 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
520 optimizeSubmodel(subgGraphViTree,
true);
524 size_t nTr=(param_.treeRuns_==0? 1:
std::abs(param_.treeRuns_));
527 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
528 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
530 for(
size_t tr=0;tr<nTr;++tr){
531 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
532 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
533 bool c=optimizeSubmodel(subgGraphViTree,
true);
543 this->getSubgraphVis(viStart, radiusBlock, subgGraphViBLock);
544 std::sort(subgGraphViBLock.begin(), subgGraphViBLock.end());
545 optimizeSubmodel(subgGraphViBLock,
false);
547 for(
IndexType lvi=0;lvi<subgGraphViBLock.size();++lvi){
548 coverdVar[subgGraphViBLock[lvi]]=
true;
559 for(
size_t i=0;i<0;++i) {
565 size_t viStart = randomVariable();
567 size_t radiusBlock = (useBlocks ? randomRadiusBlock()+1 : 0);
568 size_t radiusTree = (useTrees ? randomRadiusTree()+1 : 0);
578 if(param_.treeRuns_>0){
579 for(
size_t tr=0;tr<(
size_t)(param_.treeRuns_);++tr){
580 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
581 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
582 optimizeSubmodel(subgGraphViTree,
true);
586 size_t nTr=(param_.treeRuns_==0? 1:
std::abs(param_.treeRuns_));
589 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
590 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
592 for(
size_t tr=0;tr<nTr;++tr){
593 this->getSubgraphTreeVis(viStart, radiusTree, subgGraphViTree);
594 std::sort(subgGraphViTree.begin(), subgGraphViTree.end());
595 bool c=optimizeSubmodel(subgGraphViTree,
true);
605 this->getSubgraphVis(viStart, radiusBlock, subgGraphViBLock);
606 std::sort(subgGraphViBLock.begin(), subgGraphViBLock.end());
607 optimizeSubmodel(subgGraphViBLock,
false);
616 std::cout<<
"basic inference is done\n";
621 template<
class GM,
class ACC>
625 std::vector<LabelType> states;
626 if(subgGraphVi.size()>2){
627 subOptimizer_.setVariableIndices(subgGraphVi.begin(), subgGraphVi.end());
632 changes = subOptimizer_.mergeFactorsAndInferDp(states);
638 else if(param_.solver_==std::string(
"ad3")){
639 changes = subOptimizer_.
template inferSubmodelInplace<Ad3SubInf>(
typename Ad3SubInf::Parameter(Ad3SubInf::AD3_ILP) ,states);
642 else if (param_.solver_==std::string(
"astar")){
645 else if (param_.solver_==std::string(
"cplex")){
648 typename LpCplexSubInf::Parameter subParam;
649 subParam.integerConstraint_=
true;
650 changes = subOptimizer_.
template inferSubmodel<LpCplexSubInf>(subParam ,states);
652 throw RuntimeError(
"solver cplex needs flag WITH_CPLEX defined bevore the #include of LOC sovler");
656 else if(param_.solver_[0]==
'l' && param_.solver_[1]==
'f'){
657 std::stringstream ss;
658 for(
size_t i=2;i<param_.solver_.size();++i){
659 ss<<param_.solver_[i];
663 changes = subOptimizer_.
template inferSubmodel<LfSubInf>(
typename LfSubInf::Parameter(maxSgSize) ,states,
true,
true);
666 subOptimizer_.unsetVariableIndices();
669 movemaker_.move(subgGraphVi.begin(), subgGraphVi.end(), states.begin());
670 for(IndexType v=0;v<subgGraphVi.size();++v){
671 subOptimizer_.setLabel(subgGraphVi[v],movemaker_.state(subgGraphVi[v]));
683 template<
class GM,
class ACC>
687 std::vector<LabelType>& x,
691 x.resize(gm_.numberOfVariables());
692 for(
size_t j = 0; j < x.size(); ++j) {
693 x[j] = movemaker_.state(j);
703 #endif // #ifndef OPENGM_LOC_HXX
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
InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
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
Parameter(const std::string solver="ad3", const double phi=0.3, const size_t maxBlockRadius=50, const size_t maxTreeRadius=50, const double pFastHeuristic=0.9, const size_t maxIterations=100000, const size_t stopAfterNBadIterations=10000, const size_t maxBlockSize=0, const size_t maxTreeSize=0, const int treeRuns=1)
constuctor
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
ValueType value() const
return the solution (value)
#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