2 #ifndef OPENGM_FACTORGRAPH_HXX
3 #define OPENGM_FACTORGRAPH_HXX
17 template<
class S,
class I>
20 class VariableAccessor;
66 {
return static_cast<S&
>(*this); }
67 operator S
const&()
const
68 {
return static_cast<const S&
>(*this); }
71 bool shortestPath(
const size_t,
const size_t, LIST&,
const LIST& = LIST())
const;
76 class VariableAccessor {
78 typedef size_t value_type;
80 VariableAccessor(
const FactorGraph<S,I>* factorGraph = NULL,
const size_t factor = 0)
81 : factorGraph_(factorGraph), factor_(factor)
83 VariableAccessor(
const FactorGraph<S,I>& factorGraph,
const size_t factor = 0)
84 : factorGraph_(&factorGraph), factor_(factor)
88 return factorGraph_->numberOfVariables(factor_); }
89 const size_t operator[](
const size_t number)
const
91 return factorGraph_->variableOfFactor(factor_, number); }
92 bool operator==(
const VariableAccessor& a)
const
94 return factor_ == a.factor_ && factorGraph_ == a.factorGraph_; }
97 const FactorGraph<S,I>* factorGraph_;
101 class FactorAccessor {
103 typedef I value_type;
105 FactorAccessor(
const FactorGraph<S,I>* factorGraph = NULL,
const size_t variable = 0)
106 : factorGraph_(factorGraph), variable_(variable)
108 FactorAccessor(
const FactorGraph<S,I>& factorGraph,
const size_t variable = 0)
109 : factorGraph_(&factorGraph), variable_(variable)
113 return factorGraph_->numberOfFactors(variable_); }
114 const size_t operator[](
const size_t number)
const
116 return factorGraph_->factorOfVariable(variable_, number); }
117 bool operator==(
const FactorAccessor& a)
const
119 return variable_ == a.variable_ && factorGraph_ == a.factorGraph_; }
122 const FactorGraph<S,I>* factorGraph_;
127 void templatedVariableAdjacencyList(LIST&)
const;
129 void templatedFactorAdjacencyList(LIST&)
const;
134 template<
class S,
class I>
138 return static_cast<const SpecialType&
>(*this).numberOfVariables();
144 template<
class S,
class I>
151 return static_cast<const SpecialType&
>(*this).numberOfVariables(factor);
156 template<
class S,
class I>
160 return static_cast<const SpecialType&
>(*this).numberOfFactors();
166 template<
class S,
class I>
170 const size_t variable
173 return static_cast<const SpecialType&
>(*this).numberOfFactors(variable);
180 template<
class S,
class I>
188 return static_cast<const SpecialType&
>(*this).variableOfFactor(factor, j);
195 template<
class S,
class I>
199 const size_t variable,
203 return static_cast<const SpecialType&
>(*this).factorOfVariable(variable, j);
209 template<
class S,
class I>
216 VariableAccessor accessor(
this, factor);
217 return ConstVariableIterator(accessor);
223 template<
class S,
class I>
230 VariableAccessor accessor(
this, factor);
231 return ConstVariableIterator(accessor, numberOfVariables(factor));
237 template<
class S,
class I>
241 const size_t variable
244 FactorAccessor accessor(
this, variable);
245 return ConstFactorIterator(accessor);
251 template<
class S,
class I>
255 const size_t variable
258 FactorAccessor accessor(
this, variable);
259 return ConstFactorIterator(accessor, numberOfFactors(variable));
266 template<
class S,
class I>
270 const size_t variable,
277 for(
size_t j=1; j<numberOfVariables(factor); ++j) {
278 OPENGM_ASSERT(variableOfFactor(factor, j-1) < variableOfFactor(factor, j));
281 return std::binary_search(variablesOfFactorBegin(factor),
282 variablesOfFactorEnd(factor), variable);
290 template<
class S,
class I>
295 const size_t variable
300 return variableFactorConnection(variable, factor);
307 template<
class S,
class I>
311 const size_t variable1,
312 const size_t variable2
317 if(variable1 != variable2) {
318 ConstFactorIterator it1 = factorsOfVariableBegin(variable1);
319 ConstFactorIterator it2 = factorsOfVariableBegin(variable2);
320 while(it1 != factorsOfVariableEnd(variable1) && it2 != factorsOfVariableEnd(variable2)) {
324 else if(*it1 == *it2) {
337 template<
class S,
class I>
341 const size_t NO_FACTOR = numberOfFactors();
342 const size_t NO_VARIABLE = numberOfVariables();
343 const size_t ROOT_FACTOR = numberOfVariables() + 1;
344 std::vector<size_t> factorFathers(numberOfFactors(), NO_VARIABLE);
345 std::vector<size_t> variableFathers(numberOfVariables(), NO_FACTOR);
346 std::queue<size_t> factorQueue;
347 std::queue<size_t> variableQueue;
348 for(
size_t F = 0; F < numberOfFactors(); ++F) {
349 if(factorFathers[F] == NO_VARIABLE) {
350 factorFathers[F] = ROOT_FACTOR;
352 while(!factorQueue.empty()) {
353 while(!factorQueue.empty()) {
354 const size_t f = factorQueue.front();
356 for(
size_t j = 0; j < numberOfVariables(f); ++j) {
357 const size_t v = variableOfFactor(f, j);
358 if(variableFathers[v] == NO_FACTOR) {
359 variableFathers[v] = f;
360 variableQueue.push(v);
362 else if(factorFathers[f] != v) {
367 while(!variableQueue.empty()) {
368 const size_t v = variableQueue.front();
370 for(
size_t j = 0; j < numberOfFactors(v); ++j) {
371 const size_t f = factorOfVariable(v, j);
372 if(factorFathers[f] == NO_VARIABLE) {
373 factorFathers[f] = v;
376 else if(variableFathers[v] != f) {
390 template<
class S,
class I>
395 if(numberOfVariables() == 0) {
402 for(
size_t i = 0; i < numberOfFactors(); i++) {
404 const ConstVariableIterator variablesBegin = variablesOfFactorBegin(i);
405 const ConstVariableIterator variablesEnd = variablesOfFactorEnd(i);
408 for(ConstVariableIterator iter = variablesBegin + 1; iter != variablesEnd; iter++) {
409 connectedComponents.
merge(*(iter - 1), *iter);
429 template<
class S,
class I>
432 const size_t numVariables = numberOfVariables();
435 if(numVariables == 0) {
440 if(!maxFactorOrder(2)) {
445 if(numVariables == 1) {
453 size_t detectedEnds = 0;
454 for(
size_t i = 0; i < numVariables; i++) {
455 size_t countSecondOrderFactors = numberOfNthOrderFactorsOfVariable(i, 2);
456 if(countSecondOrderFactors == 1) {
457 if(detectedEnds > 1) {
460 ends[detectedEnds] = i;
466 if(detectedEnds != 2) {
472 chainIDs[0] = ends[0];
473 chainIDs[numVariables - 1] = ends[1];
477 size_t predecessor = ends[0];
478 OPENGM_ASSERT(numberOfVariables() < std::numeric_limits<size_t>::max());
479 size_t successor = std::numeric_limits<size_t>::max();
480 for(ConstFactorIterator iter = factorsOfVariableBegin(ends[0]); iter != factorsOfVariableEnd(ends[0]); iter++) {
481 if(numberOfVariables(*iter) == 2) {
482 successor = secondVariableOfSecondOrderFactor(ends[0], *iter);
486 OPENGM_ASSERT(successor != std::numeric_limits<size_t>::max());
489 size_t countTraversedVariables = 1;
490 while(successor != ends[1]) {
492 size_t countSecondOrderFactors = numberOfNthOrderFactorsOfVariable(successor, 2, secondOrderFactorIds);
493 if(countSecondOrderFactors > 2) {
497 chainIDs[countTraversedVariables] = successor;
498 countTraversedVariables++;
502 for(
size_t j = 0; j < 2; j++) {
503 size_t possibleSuccesor = secondVariableOfSecondOrderFactor(successor, secondOrderFactorIds[j]);
504 if(possibleSuccesor != predecessor) {
505 predecessor = successor;
506 successor = possibleSuccesor;
512 if(countTraversedVariables != numVariables - 1) {
527 template<
class S,
class I>
532 if(numberOfVariables() == 0) {
537 if(!maxFactorOrder(2)) {
542 if(numberOfVariables() == 1) {
550 bool graphIsChain = isChain(chainIDs);
553 for(
size_t i = 0; i < chainIDs.
size(); i++) {
554 gridIDs(0, i) = chainIDs[i];
562 size_t numCornersFound = 0;
563 std::list<size_t> outerHullVariableIDs;
565 for(
size_t i = 0; i < numberOfVariables(); i++) {
566 size_t countSecondOrderFactors = numberOfNthOrderFactorsOfVariable(i, 2);
567 if(countSecondOrderFactors == 2) {
569 if(numCornersFound > 3) {
572 cornerIDs(numCornersFound) = i;
575 outerHullVariableIDs.push_back(i);
576 }
else if(countSecondOrderFactors == 3) {
577 outerHullVariableIDs.push_back(i);
578 }
else if(countSecondOrderFactors > 4) {
584 if(numCornersFound < 4) {
591 std::vector<std::list<size_t> > shortestPaths(3);
592 if(!shortestPath(cornerIDs(0), cornerIDs(1), shortestPaths[0], outerHullVariableIDs)) {
596 if(!shortestPath(cornerIDs(0), cornerIDs(2), shortestPaths[1], outerHullVariableIDs)) {
600 if(!shortestPath(cornerIDs(0), cornerIDs(3), shortestPaths[2], outerHullVariableIDs)) {
605 size_t diagonalCorner = 1;
606 for(
size_t i = 1; i < 4; i++) {
607 if(shortestPaths[i - 1].size() > shortestPaths[diagonalCorner].size()) {
613 std::vector<std::list<size_t> > shortestAdjacentCornerPaths(2);
614 size_t shortestAdjacentCornerPathsComputed = 0;
615 for(
size_t i = 1; i < 4; i++) {
616 if(i != diagonalCorner) {
617 if(!shortestPath(cornerIDs(i), cornerIDs(diagonalCorner), shortestAdjacentCornerPaths[shortestAdjacentCornerPathsComputed], outerHullVariableIDs)) {
620 shortestAdjacentCornerPathsComputed++;
626 std::vector<size_t> dimension(2);
627 size_t dimensionIndex = 0;
628 for(
size_t i = 1; i < 4; i++) {
629 if(i != diagonalCorner) {
630 dimension[dimensionIndex] = shortestPaths[i - 1].size();
637 if(dimension[0] != shortestAdjacentCornerPaths[1].size()) {
640 if(dimension[1] != shortestAdjacentCornerPaths[0].size()) {
650 for(
size_t i = 1; i < 4; i++) {
651 if(i != diagonalCorner) {
652 size_t indexHelper = 0;
653 if(transpose ==
false) {
654 for(
typename std::list<size_t>::iterator iter = shortestPaths[i - 1].begin(); iter != shortestPaths[i - 1].end(); iter++) {
655 gridIDs(indexHelper, 0) = *iter;
660 for(
typename std::list<size_t>::iterator iter = shortestPaths[i - 1].begin(); iter != shortestPaths[i - 1].end(); iter++) {
661 gridIDs(0, indexHelper) = *iter;
671 for(
size_t i = 0; i <= 1; i++) {
672 size_t indexHelper = 0;
673 if(transpose ==
false) {
674 for(
typename std::list<size_t>::iterator iter = shortestAdjacentCornerPaths[i].begin(); iter != shortestAdjacentCornerPaths[i].end(); iter++) {
675 gridIDs(dimension[0] - 1, indexHelper) = *iter;
680 for(
typename std::list<size_t>::iterator iter = shortestAdjacentCornerPaths[i].begin(); iter != shortestAdjacentCornerPaths[i].end(); iter++) {
681 gridIDs(indexHelper, dimension[1] - 1) = *iter;
688 for(
size_t i = 1; i < dimension[0] - 1; i++) {
689 for(
size_t j = 1; j < dimension[1] - 1; j++) {
690 std::vector<size_t> oneHopVariables;
691 if(twoHopConnected(gridIDs(i - 1, j), gridIDs(i, j - 1), oneHopVariables)) {
692 if(oneHopVariables.size() < 2) {
696 if(oneHopVariables[0] != gridIDs(i - 1, j - 1)) {
697 gridIDs(i, j) = oneHopVariables[0];
699 gridIDs(i, j) = oneHopVariables[1];
712 template<
class S,
class I>
715 size_t maxFactorOrder = 0;
716 for(
size_t i = 0; i < numberOfFactors(); i++) {
717 if(numberOfVariables(i) > maxFactorOrder) {
718 maxFactorOrder = numberOfVariables(i);
721 return maxFactorOrder;
727 template<
class S,
class I>
730 for(
size_t i = 0; i < numberOfFactors(); i++) {
731 if(numberOfVariables(i) > maxOrder) {
742 template<
class S,
class I>
746 size_t countNthOrderFactors = 0;
747 for(ConstFactorIterator iter = factorsOfVariableBegin(variable); iter != factorsOfVariableEnd(variable); iter++) {
748 if(numberOfVariables(*iter) == n) {
749 countNthOrderFactors++;
752 return countNthOrderFactors;
760 template<
class S,
class I>
765 size_t countNthOrderFactors = numberOfNthOrderFactorsOfVariable(variable, n);
767 for(ConstFactorIterator iter = factorsOfVariableBegin(variable); iter != factorsOfVariableEnd(variable); iter++) {
768 if(numberOfVariables(*iter) == n) {
769 countNthOrderFactors--;
770 factorIDs[countNthOrderFactors] = *iter;
774 return factorIDs.
size();
781 template<
class S,
class I>
788 for(ConstVariableIterator iter = variablesOfFactorBegin(factor); iter != variablesOfFactorEnd(factor); iter++) {
789 if(*iter != variable) {
800 template<
class S,
class I>
804 const size_t factor1,
810 if(factor1 != factor2) {
811 ConstVariableIterator it1 = variablesOfFactorBegin(factor1);
812 ConstVariableIterator it2 = variablesOfFactorBegin(factor2);
813 while(it1 != variablesOfFactorEnd(factor1) && it2 != variablesOfFactorEnd(factor2)) {
817 else if(*it1 == *it2) {
830 template<
class S,
class I>
838 for(
size_t factor=0; factor<numberOfFactors(); ++factor) {
839 for(
size_t j=0; j<numberOfVariables(factor); ++j) {
840 for(
size_t k=j+1; k<numberOfVariables(factor); ++k) {
841 const size_t variable1 = variableOfFactor(factor, j);
842 const size_t variable2 = variableOfFactor(factor, k);
843 out(variable1, variable2) =
true;
844 out(variable2, variable1) =
true;
852 template<
class S,
class I>
859 templatedVariableAdjacencyList(out);
864 template<
class S,
class I>
868 std::vector<std::set<IndexType> >& out
871 templatedVariableAdjacencyList(out);
876 template<
class S,
class I>
885 out.resize(numberOfVariables());
886 for(
size_t factor=0; factor<numberOfFactors(); ++factor) {
887 for(
size_t j=0; j<numberOfVariables(factor); ++j) {
888 for(
size_t k=j+1; k<numberOfVariables(factor); ++k) {
889 const size_t variable1 = variableOfFactor(factor, j);
890 const size_t variable2 = variableOfFactor(factor, k);
891 out[variable1].insert(variable2);
892 out[variable2].insert(variable1);
898 template<
class S,
class I>
902 std::vector<std::set<IndexType> >& out
905 templatedFactorAdjacencyList(out);
908 template<
class S,
class I>
915 templatedFactorAdjacencyList(out);
918 template<
class S,
class I>
927 out.resize(numberOfFactors());
928 for(
size_t f=0; f<numberOfFactors(); ++f) {
929 for(
size_t v=0 ;v<numberOfVariables(f); ++v) {
930 for(
size_t ff=0;ff<numberOfFactors(v);++ff) {
931 const size_t fOfVar=factorOfVariable(v,ff);
933 out[f].insert(fOfVar);
945 template<
class S,
class I>
946 template <
class LIST>
951 OPENGM_ASSERT(allowedVariables.size() <= numberOfVariables());
952 OPENGM_ASSERT(numberOfVariables() != std::numeric_limits<size_t>::max());
953 const size_t infinity = std::numeric_limits<size_t>::max();
955 bool useAllVariables = (allowedVariables.size() == 0) || (allowedVariables.size() == numberOfVariables());
957 if(useAllVariables) {
958 std::vector<size_t> distances(numberOfVariables(), infinity);
959 std::vector<size_t> previous(numberOfVariables(), infinity);
962 for(
size_t i = 0; i < numberOfVariables(); i++) {
965 while(Q.size() !=0) {
966 typename LIST::iterator currentIter = Q.begin();
967 for(
typename LIST::iterator iter = Q.begin(); iter != Q.end(); iter++) {
968 if(distances[*iter] < distances[*currentIter]) {
972 if(distances[*currentIter] == infinity) {
976 if(*currentIter == t) {
980 size_t currentID = *currentIter;
981 Q.erase(currentIter);
983 for(ConstFactorIterator factorIter = factorsOfVariableBegin(currentID); factorIter != factorsOfVariableEnd(currentID); factorIter++) {
984 for(ConstVariableIterator variableIter = variablesOfFactorBegin(*factorIter); variableIter != variablesOfFactorEnd(*factorIter); variableIter++) {
985 if(std::find(Q.begin(), Q.end(), *variableIter) != Q.end()) {
986 size_t newDistance = distances[currentID] + 1;
987 if(newDistance < distances[*variableIter]) {
988 distances[*variableIter] = newDistance;
989 previous[*variableIter] = currentID;
998 while(previous[u] != infinity) {
1005 OPENGM_ASSERT(std::find(allowedVariables.begin(), allowedVariables.end(), s) != allowedVariables.end());
1006 OPENGM_ASSERT(std::find(allowedVariables.begin(), allowedVariables.end(), t) != allowedVariables.end());
1007 std::vector<size_t> distances(allowedVariables.size(), infinity);
1008 std::vector<size_t> previous(allowedVariables.size(), infinity);
1009 std::map<size_t, size_t> local2actualIDs;
1010 std::map<size_t, size_t> actual2localIDs;
1013 for(
typename LIST::const_iterator iter = allowedVariables.begin(); iter != allowedVariables.end(); iter++) {
1014 Q.push_back(counter);
1015 local2actualIDs.insert(std::pair<size_t, size_t>(counter, *iter));
1016 actual2localIDs.insert(std::pair<size_t, size_t>(*iter, counter));
1019 distances[actual2localIDs.find(s)->second] = 0;
1020 while(Q.size() !=0) {
1021 typename LIST::iterator currentIter = Q.begin();
1022 for(
typename LIST::iterator iter = Q.begin(); iter != Q.end(); iter++) {
1023 if(distances[*iter] < distances[*currentIter]) {
1027 if(distances[*currentIter] == infinity) {
1032 size_t actualID = local2actualIDs.find(*currentIter)->second;
1037 size_t currentLocalID = *currentIter;
1038 Q.erase(currentIter);
1040 for(ConstFactorIterator factorIter = factorsOfVariableBegin(actualID); factorIter != factorsOfVariableEnd(actualID); factorIter++) {
1041 for(ConstVariableIterator variableIter = variablesOfFactorBegin(*factorIter); variableIter != variablesOfFactorEnd(*factorIter); variableIter++) {
1042 const std::map<size_t, size_t>::const_iterator actual2localIDsCurrentPosition = actual2localIDs.find(*variableIter);
1043 if(actual2localIDsCurrentPosition != actual2localIDs.end()) {
1044 size_t localID = actual2localIDsCurrentPosition->second;
1045 if(std::find(Q.begin(), Q.end(), localID) != Q.end()) {
1046 size_t newDistance = distances[currentLocalID] + 1;
1047 if(newDistance < distances[localID]) {
1048 distances[localID] = newDistance;
1049 previous[localID] = currentLocalID;
1058 size_t u = actual2localIDs.find(t)->second;
1059 while(previous[u] != infinity) {
1061 path.push_front(local2actualIDs.find(u)->second);
1074 template<
class S,
class I>
1075 template <
class LIST>
1080 oneHopVariables.clear();
1081 if(variable1 != variable2) {
1082 for(ConstFactorIterator factorIter = factorsOfVariableBegin(variable1); factorIter != factorsOfVariableEnd(variable1); factorIter++) {
1083 for(ConstVariableIterator variableIter = variablesOfFactorBegin(*factorIter); variableIter != variablesOfFactorEnd(*factorIter); variableIter++) {
1084 if((*variableIter != variable1) || (*variableIter != variable2)) {
1085 if(variableVariableConnection(*variableIter, variable2)) {
1086 oneHopVariables.push_back(*variableIter);
1092 if(oneHopVariables.size() == 0) {
1101 #endif // #ifndef OPENGM_FACTORGRAPH_HXX
AccessorIterator< FactorAccessor, true > ConstFactorIterator
size_t variableOfFactor(const size_t, const size_t) const
j-th variable node connected to a factor node
bool isGrid(marray::Matrix< size_t > &) const
return true if the factor graph (!) is a grid
size_t secondVariableOfSecondOrderFactor(const size_t, const size_t) const
return returns the id of the second variable which is connected to a given variable via a second orde...
void merge(value_type, value_type)
Merge two sets.
Interface that makes an object of type S (the template parameter) look like a (non-editable) factor g...
bool isAcyclic() const
return true if the factor graph (!) is acyclic
size_t numberOfVariables() const
total number of variable nodes in the factor graph
void factorAdjacencyList(std::vector< std::set< IndexType > > &) const
bool operator==(const IndicatorVariable< INDEX1_TYPE, LABEL1_TYPE > &indicatorVar1, const IndicatorVariable< INDEX2_TYPE, LABEL2_TYPE > &indicatorVar2)
ConstFactorIterator factorsOfVariableEnd(const size_t) const
constant iterator to the end of the squence of factors connected to a variable
#define OPENGM_ASSERT(expression)
value_type numberOfSets() const
bool shortestPath(const size_t, const size_t, LIST &, const LIST &=LIST()) const
computes the shortest path from s to t using Dijkstra's algorithm with uniform distances ...
size_t factorOfVariable(const size_t, const size_t) const
j-th factor node connected to a variable node
ConstVariableIterator variablesOfFactorEnd(const size_t) const
constant iterator to the end of the squence of variables connected to a factor
bool variableVariableConnection(const size_t, const size_t) const
return true if a variable is connected to a variable
bool isConnected(marray::Vector< size_t > &representatives) const
return true if the factor graph (!) is connected
AccessorIterator< VariableAccessor, true > ConstVariableIterator
const size_t size() const
void transpose(const MatrixWrapper< T > &input, MatrixWrapper< T > &result)
void variableAdjacencyMatrix(marray::Matrix< bool > &) const
outputs the factor graph as a variable adjacency matrix
size_t numberOfFactors() const
total number of factor nodes in the factor graph
bool twoHopConnected(const size_t, const size_t, LIST &) const
checks if variabel1 is connected to variable2 via two hops
void representatives(Iterator) const
Output all elements which are set representatives.
bool variableFactorConnection(const size_t, const size_t) const
return true if a factor is connected to a variable
Disjoint set data structure with path compression.
size_t numberOfNthOrderFactorsOfVariable(const size_t, const size_t) const
return number of factors with order n which are connected to variable
size_t maxFactorOrder() const
return maximum factor order
bool isChain(marray::Vector< size_t > &) const
return true if the factor graph (!) is a chain
bool factorFactorConnection(const size_t, const size_t) const
return true if a factor is connected to a factor
void variableAdjacencyList(std::vector< std::set< IndexType > > &) const
outputs the factor graph as variable adjacency lists
bool factorVariableConnection(const size_t, const size_t) const
return true if a variable is connected to a factor
ConstFactorIterator factorsOfVariableBegin(const size_t) const
constant iterator to the beginning of the squence of factors connected to a variable ...
ConstVariableIterator variablesOfFactorBegin(const size_t) const
constant iterator to the beginning of the squence of variables connected to a factor ...