2 #ifndef OPENGM_LAZYFLIPPER_HXX 3 #define OPENGM_LAZYFLIPPER_HXX 27 typedef std::vector<ValueType> tag_container_type;
28 typedef std::vector<size_t> index_container_type;
29 typedef index_container_type::const_iterator const_iterator;
31 Tagging(
const size_t = 0);
32 void append(
const size_t);
33 ValueType tag(
const size_t)
const;
34 void tag(
const size_t,
const typename Tagging<T>::ValueType);
36 const_iterator begin();
37 const_iterator begin()
const;
39 const_iterator end()
const;
42 tag_container_type tags_;
43 index_container_type indices_;
49 typedef std::set<size_t>::const_iterator const_iterator;
51 Adjacency(
const size_t = 0);
52 void resize(
const size_t);
53 void connect(
const size_t,
const size_t);
54 bool connected(
const size_t,
const size_t)
const;
55 const_iterator neighborsBegin(
const size_t);
56 const_iterator neighborsBegin(
const size_t)
const;
57 const_iterator neighborsEnd(
const size_t);
58 const_iterator neighborsEnd(
const size_t)
const;
61 std::vector<std::set<size_t> > neighbors_;
74 typedef size_t NodeIndex;
77 static const NodeIndex NONODE = -1;
82 NodeIndex levelAnchor(
const Level&);
83 NodeIndex push_back(
const Value&, NodeIndex);
84 size_t testInvariant();
85 std::string asString();
86 Value& value(NodeIndex);
87 Level level(NodeIndex);
88 NodeIndex parent(NodeIndex);
89 NodeIndex levelOrderSuccessor(NodeIndex);
90 size_t numberOfChildren(NodeIndex);
91 NodeIndex child(NodeIndex,
const size_t);
92 void setLevelOrderSuccessor(NodeIndex, NodeIndex);
96 Node(
const Value& value)
97 : value_(value), parent_(NONODE),
98 children_(std::vector<NodeIndex>()),
99 level_(0), levelOrderSuccessor_(NONODE)
103 std::vector<NodeIndex> children_;
105 NodeIndex levelOrderSuccessor_;
107 std::vector<Node> nodes_;
108 std::vector<NodeIndex> levelAnchors_;
117 template<
class GM,
class ACC = Minimizer>
126 template<
class _GM,
class _ACC>
137 static const SubgraphForestNode NONODE = SubgraphForest::NONODE;
144 template<
class StateIterator>
146 const size_t maxSubgraphSize,
147 StateIterator stateBegin,
148 StateIterator stateEnd,
151 : maxSubgraphSize_(maxSubgraphSize),
152 startingPoint_(stateBegin, stateEnd),
153 inferMultilabel_(inferMultilabel)
157 const size_t maxSubgraphSize = 2,
160 : maxSubgraphSize_(maxSubgraphSize),
162 inferMultilabel_(inferMultilabel)
169 : maxSubgraphSize_(p.maxSubgraphSize_),
170 startingPoint_(p.startingPoint_),
171 inferMultilabel_(p.inferMultilabel_)
183 std::string name()
const;
184 const GraphicalModelType& graphicalModel()
const;
185 const size_t maxSubgraphSize()
const;
187 void setMaxSubgraphSize(
const size_t);
190 template<
class VisitorType>
192 void setStartingPoint(
typename std::vector<LabelType>::const_iterator);
197 template<
class VisitorType>
199 template<
class VisitorType>
203 SubgraphForestNode appendVariableToPath(SubgraphForestNode);
204 SubgraphForestNode generateFirstPathOfLength(
const size_t);
205 SubgraphForestNode generateNextPathOfSameLength(SubgraphForestNode);
206 void activateInfluencedVariables(SubgraphForestNode,
const size_t);
207 void deactivateAllVariables(
const size_t);
208 SubgraphForestNode firstActivePath(
const size_t);
209 SubgraphForestNode nextActivePath(SubgraphForestNode,
const size_t);
210 ValueType energyAfterFlip(SubgraphForestNode);
211 void flip(SubgraphForestNode);
212 const bool flipMultiLabel(SubgraphForestNode);
214 const GraphicalModelType& gm_;
215 Adjacency variableAdjacency_;
217 Tagging<bool> activation_[2];
218 SubgraphForest subgraphForest_;
219 size_t maxSubgraphSize_;
220 Tribool useMultilabelInference_;
226 inline Tagging<T>::Tagging(
229 : tags_(tag_container_type(size)),
230 indices_(index_container_type())
234 inline void Tagging<T>::append(
238 tags_.resize(tags_.size() + number);
243 inline typename Tagging<T>::ValueType
257 const typename Tagging<T>::ValueType tag
262 if(tags_[index] == T()) {
263 indices_.push_back(index);
275 for(const_iterator it = indices_.begin(); it != indices_.end(); ++it) {
282 inline typename Tagging<T>::const_iterator
283 Tagging<T>::begin()
const 285 return indices_.begin();
289 inline typename Tagging<T>::const_iterator
290 Tagging<T>::end()
const 292 return indices_.end();
296 inline typename Tagging<T>::const_iterator
299 return indices_.begin();
303 inline typename Tagging<T>::const_iterator
306 return indices_.end();
311 Adjacency::Adjacency(
322 neighbors_.resize(size);
332 neighbors_[j].insert(k);
333 neighbors_[k].insert(j);
337 Adjacency::connected(
342 if(neighbors_[j].size() < neighbors_[k].size()) {
343 if(neighbors_[j].find(k) == neighbors_[j].end()) {
351 if(neighbors_[k].find(j) == neighbors_[k].end()) {
360 inline Adjacency::const_iterator
361 Adjacency::neighborsBegin(
365 return neighbors_[index].begin();
368 inline Adjacency::const_iterator
369 Adjacency::neighborsBegin(
373 return neighbors_[index].begin();
376 inline Adjacency::const_iterator
377 Adjacency::neighborsEnd(
381 return neighbors_[index].end();
384 inline Adjacency::const_iterator
385 Adjacency::neighborsEnd(
389 return neighbors_[index].end();
395 inline Forest<T>::Forest()
396 : nodes_(
std::vector<typename Forest<T>::Node>()),
397 levelAnchors_(
std::vector<typename Forest<T>::NodeIndex>())
404 return levelAnchors_.size();
411 return nodes_.size();
415 inline typename Forest<T>::NodeIndex
416 Forest<T>::levelAnchor(
417 const typename Forest<T>::Level& level
421 return levelAnchors_[level];
425 inline typename Forest<T>::Value&
427 typename Forest<T>::NodeIndex n
431 return nodes_[n].value_;
435 inline typename Forest<T>::Level
437 typename Forest<T>::NodeIndex n
441 return nodes_[n].level_;
445 inline typename Forest<T>::NodeIndex
447 typename Forest<T>::NodeIndex n
451 return nodes_[n].parent_;
455 inline typename Forest<T>::NodeIndex
456 Forest<T>::levelOrderSuccessor(
457 typename Forest<T>::NodeIndex n
461 return nodes_[n].levelOrderSuccessor_;
466 Forest<T>::numberOfChildren(
467 typename Forest<T>::NodeIndex n
471 return nodes_[n].children_.size();
475 inline typename Forest<T>::NodeIndex
477 typename Forest<T>::NodeIndex n,
481 OPENGM_ASSERT((n<nodes_.size() && j<nodes_[n].children_.size()));
482 return nodes_[n].children_[j];
486 typename Forest<T>::NodeIndex
487 Forest<T>::push_back(
489 typename Forest<T>::NodeIndex parentNodeIndex
492 OPENGM_ASSERT((parentNodeIndex == NONODE || parentNodeIndex < nodes_.size()));
494 NodeIndex nodeIndex = nodes_.size();
497 nodes_.push_back(node);
501 if(parentNodeIndex != NONODE) {
502 nodes_[nodeIndex].parent_ = parentNodeIndex;
503 nodes_[parentNodeIndex].children_.push_back(nodeIndex);
504 nodes_[nodeIndex].level_ = nodes_[parentNodeIndex].level_ + 1;
506 if(nodes_[nodeIndex].level_ >= levelAnchors_.size()) {
507 OPENGM_ASSERT(levelAnchors_.size() == nodes_[nodeIndex].level_);
508 levelAnchors_.push_back(nodeIndex);
516 Forest<T>::testInvariant()
518 if(nodes_.size() == 0) {
526 size_t numberOfRoots = 0;
527 size_t nodesVisited = 0;
529 NodeIndex p = levelAnchors_[0];
543 for(
size_t j=0; j<nodes_[parent(p)].children_.size(); ++j) {
544 if(nodes_[parent(p)].children_[j] == p) {
552 if(levelOrderSuccessor(p) != NONODE) {
553 p = levelOrderSuccessor(p);
556 if(level+1 < levelAnchors_.size()) {
559 p = levelAnchors_[level];
569 return numberOfRoots;
575 Forest<T>::asString()
577 std::ostringstream out(std::ostringstream::out);
578 for(
size_t level=0; level<levels(); ++level) {
579 NodeIndex p = levelAnchor(level);
585 out <<
value(q)+1 <<
' ';
590 p = levelOrderSuccessor(p);
598 Forest<T>::setLevelOrderSuccessor(
599 typename Forest<T>::NodeIndex nodeIndex,
600 typename Forest<T>::NodeIndex successorNodeIndex
603 OPENGM_ASSERT((nodeIndex < nodes_.size() && successorNodeIndex < nodes_.size()));
604 nodes_[nodeIndex].levelOrderSuccessor_ = successorNodeIndex;
641 template<
class GM,
class ACC>
644 const GraphicalModelType& gm,
648 variableAdjacency_(Adjacency(gm.numberOfVariables())),
650 subgraphForest_(SubgraphForest()),
654 if(gm_.numberOfVariables() == 0) {
655 throw RuntimeError(
"The graphical model has no variables.");
659 activation_[0].append(gm_.numberOfVariables());
660 activation_[1].append(gm_.numberOfVariables());
662 for(
size_t j=0; j<gm_.numberOfFactors(); ++j) {
664 for(
size_t m=0; m<factor.numberOfVariables(); ++m) {
665 for(
size_t n=m+1; n<factor.numberOfVariables(); ++n) {
666 variableAdjacency_.connect(factor.variableIndex(m), factor.variableIndex(n));
675 template<
class GM,
class ACC>
715 template<
class GM,
class ACC>
723 template<
class GM,
class ACC>
727 return "LazyFlipper";
730 template<
class GM,
class ACC>
737 template<
class GM,
class ACC>
741 return maxSubgraphSize_;
744 template<
class GM,
class ACC>
750 if(maxSubgraphSize < 1) {
759 template<
class GM,
class ACC>
760 template<
class VisitorType>
767 if(this->useMultilabelInference_ ==
true) {
770 else if(this->useMultilabelInference_ ==
false) {
775 for(
size_t i=0; i<gm_.numberOfVariables(); ++i) {
776 if(gm_.numberOfLabels(i) != 2) {
784 return this->inferMultiLabel(visitor);
787 return this->inferBinaryLabel(visitor);
792 template<
class GM,
class ACC>
796 EmptyVisitorType visitor;
797 return this->
infer(visitor);
800 template<
class GM,
class ACC>
801 template<
class VisitorType>
807 bool continueInf =
true;
811 visitor.begin(*
this);
814 if(visitor(*
this)!=0){
818 SubgraphForestNode p = generateFirstPathOfLength(length);
824 if(AccumulationType::bop(energyAfterFlip(p), movemaker_.
value())) {
826 activateInfluencedVariables(p, 0);
828 if(visitor(*
this)!=0){
833 p = generateNextPathOfSameLength(p);
835 size_t currentActivationList = 0;
836 size_t nextActivationList = 1;
838 SubgraphForestNode p2 = firstActivePath(currentActivationList);
843 while(p2 != NONODE) {
844 if(AccumulationType::bop(energyAfterFlip(p2), movemaker_.
value())) {
846 activateInfluencedVariables(p2, nextActivationList);
848 if(visitor(*
this)!=0){
853 p2 = nextActivePath(p2, currentActivationList);
855 deactivateAllVariables(currentActivationList);
856 nextActivationList = 1 - nextActivationList;
857 currentActivationList = 1 - currentActivationList;
861 if(length == maxSubgraphSize_) {
870 subgraphForest_.testInvariant();
879 template<
class GM,
class ACC>
887 template<
class GM,
class ACC>
888 template<
class VisitorType>
894 bool continueInf =
true;
898 visitor.begin(*
this);
901 if(visitor(*
this)!=0){
905 SubgraphForestNode p = generateFirstPathOfLength(length);
911 bool flipped = flipMultiLabel(p);
913 activateInfluencedVariables(p, 0);
915 if(visitor(*
this)!=0){
920 p = generateNextPathOfSameLength(p);
922 size_t currentActivationList = 0;
923 size_t nextActivationList = 1;
925 SubgraphForestNode p2 = firstActivePath(currentActivationList);
930 while(p2 != NONODE) {
931 bool flipped = flipMultiLabel(p2);
933 activateInfluencedVariables(p2, nextActivationList);
935 if(visitor(*
this)!=0){
940 p2 = nextActivePath(p2, currentActivationList);
942 deactivateAllVariables(currentActivationList);
943 nextActivationList = 1 - nextActivationList;
944 currentActivationList = 1 - currentActivationList;
948 if(length == maxSubgraphSize_) {
957 subgraphForest_.testInvariant();
966 template<
class GM,
class ACC>
970 EmptyVisitorType visitor;
971 return this->inferMultiLabel(visitor);
974 template<
class GM,
class ACC>
977 std::vector<LabelType>&
arg,
985 arg.resize(gm_.numberOfVariables());
986 for(
size_t j=0; j<gm_.numberOfVariables(); ++j) {
987 arg[j] = movemaker_.
state(j);
993 template<
class GM,
class ACC>
997 return movemaker_.
value();
1002 template<
class GM,
class ACC>
1009 std::vector<size_t> variableIndicesOnPath(subgraphForest_.level(p) + 1);
1011 SubgraphForestNode p2 = p;
1012 for(
size_t j=0; j<=subgraphForest_.level(p); ++j) {
1014 variableIndicesOnPath[subgraphForest_.level(p) - j] = subgraphForest_.value(p2);
1015 p2 = subgraphForest_.parent(p2);
1020 size_t minVI = variableIndicesOnPath[0];
1021 size_t maxVI = variableIndicesOnPath[0];
1022 for(
size_t j=1; j<variableIndicesOnPath.size(); ++j) {
1023 if(variableIndicesOnPath[j] > maxVI) {
1024 maxVI = variableIndicesOnPath[j];
1029 if(subgraphForest_.numberOfChildren(p) > 0) {
1030 size_t maxChildIndex = subgraphForest_.numberOfChildren(p) - 1;
1031 minVI = subgraphForest_.value(subgraphForest_.child(p, maxChildIndex));
1034 std::set<size_t> candidateVariableIndices;
1036 SubgraphForestNode q = p;
1037 while(q != NONODE) {
1038 for(Adjacency::const_iterator it = variableAdjacency_.neighborsBegin(subgraphForest_.value(q));
1039 it != variableAdjacency_.neighborsEnd(subgraphForest_.value(q)); ++it) {
1040 candidateVariableIndices.insert(*it);
1042 q = subgraphForest_.parent(q);
1046 for(std::set<size_t>::const_iterator it = candidateVariableIndices.begin();
1047 it != candidateVariableIndices.end(); ++it) {
1049 if(*it > minVI && std::find(variableIndicesOnPath.begin(), variableIndicesOnPath.end(), *it) == variableIndicesOnPath.end()) {
1056 return subgraphForest_.push_back(*it, p);
1060 for(
size_t j=1; j<variableIndicesOnPath.size(); ++j) {
1061 if(variableAdjacency_.connected(variableIndicesOnPath[j-1], *it)) {
1064 for(
size_t k=j; k<variableIndicesOnPath.size(); ++k) {
1065 if(*it < variableIndicesOnPath[k]) {
1075 return subgraphForest_.push_back(*it, p);
1084 template<
class GM,
class ACC>
1091 if(length > gm_.numberOfVariables()) {
1096 SubgraphForestNode p = subgraphForest_.push_back(0, NONODE);
1101 SubgraphForestNode p = subgraphForest_.levelAnchor(length-2);
1102 while(p != NONODE) {
1103 SubgraphForestNode p2 = appendVariableToPath(p);
1108 p = subgraphForest_.levelOrderSuccessor(p);
1116 template<
class GM,
class ACC>
1119 SubgraphForestNode predecessor
1122 if(subgraphForest_.level(predecessor) == 0) {
1123 if(subgraphForest_.value(predecessor) + 1 < gm_.numberOfVariables()) {
1124 SubgraphForestNode newNode =
1125 subgraphForest_.push_back(subgraphForest_.value(predecessor) + 1,
NONODE);
1126 subgraphForest_.setLevelOrderSuccessor(predecessor, newNode);
1135 for(SubgraphForestNode parent = subgraphForest_.parent(predecessor);
1136 parent !=
NONODE; parent = subgraphForest_.levelOrderSuccessor(parent) ) {
1137 SubgraphForestNode newNode = appendVariableToPath(parent);
1138 if(newNode != NONODE) {
1140 subgraphForest_.setLevelOrderSuccessor(predecessor, newNode);
1148 template<
class GM,
class ACC>
1151 SubgraphForestNode p,
1152 const size_t activationListIndex
1156 while(p != NONODE) {
1157 activation_[activationListIndex].tag(subgraphForest_.value(p),
true);
1158 for(Adjacency::const_iterator it = variableAdjacency_.neighborsBegin(subgraphForest_.value(p));
1159 it != variableAdjacency_.neighborsEnd(subgraphForest_.value(p)); ++it) {
1160 activation_[activationListIndex].tag(*it,
true);
1162 p = subgraphForest_.parent(p);
1166 template<
class GM,
class ACC>
1169 const size_t activationListIndex
1173 activation_[activationListIndex].untag();
1176 template<
class GM,
class ACC>
1179 const size_t activationListIndex
1182 if(subgraphForest_.levels() == 0) {
1187 SubgraphForestNode p = subgraphForest_.levelAnchor(0);
1188 while(p != NONODE) {
1189 if(activation_[activationListIndex].tag(subgraphForest_.value(p))) {
1192 p = subgraphForest_.levelOrderSuccessor(p);
1201 template<
class GM,
class ACC>
1204 SubgraphForestNode predecessor,
1205 const size_t activationListIndex
1209 if(subgraphForest_.levelOrderSuccessor(predecessor) ==
NONODE) {
1210 if(subgraphForest_.level(predecessor) + 1 < subgraphForest_.levels()) {
1212 predecessor = subgraphForest_.levelAnchor(subgraphForest_.level(predecessor) + 1);
1221 predecessor = subgraphForest_.levelOrderSuccessor(predecessor);
1223 SubgraphForestNode p = predecessor;
1224 while(p != NONODE) {
1226 if(activation_[activationListIndex].tag(subgraphForest_.value(p))) {
1229 p = subgraphForest_.parent(p);
1234 template<
class GM,
class ACC>
1237 SubgraphForestNode node
1240 size_t numberOfFlippedVariables = subgraphForest_.level(node) + 1;
1241 std::vector<size_t> flippedVariableIndices(numberOfFlippedVariables);
1242 std::vector<LabelType> flippedVariableStates(numberOfFlippedVariables);
1243 for(
size_t j=0; j<numberOfFlippedVariables; ++j) {
1245 flippedVariableIndices[j] = subgraphForest_.value(node);
1247 flippedVariableStates[j] = 1 - movemaker_.
state(subgraphForest_.value(node));
1248 node = subgraphForest_.parent(node);
1252 flippedVariableIndices.end(), flippedVariableStates.begin());
1256 template<
class GM,
class ACC>
1259 SubgraphForestNode node
1262 size_t numberOfFlippedVariables = subgraphForest_.level(node) + 1;
1263 std::vector<size_t> flippedVariableIndices(numberOfFlippedVariables);
1264 std::vector<LabelType> flippedVariableStates(numberOfFlippedVariables);
1265 for(
size_t j=0; j<numberOfFlippedVariables; ++j) {
1267 flippedVariableIndices[j] = subgraphForest_.value(node);
1269 flippedVariableStates[j] = 1 - movemaker_.
state(subgraphForest_.value(node));
1270 node = subgraphForest_.parent(node);
1273 movemaker_.
move(flippedVariableIndices.begin(),
1274 flippedVariableIndices.end(), flippedVariableStates.begin());
1277 template<
class GM,
class ACC>
1280 SubgraphForestNode node
1283 size_t numberOfVariables = subgraphForest_.level(node) + 1;
1284 std::vector<size_t> variableIndices(numberOfVariables);
1285 for(
size_t j=0; j<numberOfVariables; ++j) {
1287 variableIndices[j] = subgraphForest_.value(node);
1288 node = subgraphForest_.parent(node);
1292 movemaker_.template moveOptimallyWithAllLabelsChanging<AccumulationType>(variableIndices.begin(), variableIndices.end());
1293 if(AccumulationType::bop(movemaker_.
value(), energy)) {
1303 #endif // #ifndef OPENGM_LAZYFLIPPER_HXX
const size_t maxSubgraphSize() const
void infer(const typename INF::GraphicalModelType &gm, const typename INF::Parameter ¶m, std::vector< typename INF::LabelType > &conf)
Parameter(const size_t maxSubgraphSize, StateIterator stateBegin, StateIterator stateEnd, const Tribool inferMultilabel=Tribool::Maybe)
ValueType valueAfterMove(IndexIterator, IndexIterator, StateIterator)
void setMaxSubgraphSize(const size_t)
visitors::TimingVisitor< LazyFlipper< GM, ACC > > TimingVisitorType
void setStartingPoint(typename std::vector< LabelType >::const_iterator)
set initial labeling
#define OPENGM_ASSERT(expression)
LazyFlipper< _GM, ACC > type
InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
const LabelType & state(const size_t) const
void initialize(StateIterator)
GraphicalModelType::FactorType FactorType
const GraphicalModelType & graphicalModel() const
std::vector< LabelType > startingPoint_
LazyFlipper< _GM, _ACC > type
visitors::EmptyVisitor< LazyFlipper< GM, ACC > > EmptyVisitorType
GraphicalModelType::ValueType ValueType
Inference algorithm interface.
Parameter(const size_t maxSubgraphSize=2, const Tribool inferMultilabel=Tribool::Maybe)
LazyFlipper(const GraphicalModelType &gm, Parameter param=Parameter())
size_t SubgraphForestNode
Forest< IndexType > SubgraphForest
ValueType value() const
return the solution (value)
Variable with three values (true=1, false=0, maybe=-1 )
static const SubgraphForestNode NONODE
visitors::VerboseVisitor< LazyFlipper< GM, ACC > > VerboseVisitorType
GraphicalModelType::LabelType LabelType
ValueType move(IndexIterator, IndexIterator, StateIterator)
A generalization of ICM B. Andres, J. H. Kappes, U. Koethe and Hamprecht F. A., The Lazy Flipper: MA...
InferenceTermination infer()
start the algorithm