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_; }
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_; }
127 void templatedVariableAdjacencyList(LIST&)
const;
129 void templatedFactorAdjacencyList(LIST&)
const;
134 template<
class S,
class I>
144 template<
class S,
class I>
156 template<
class S,
class I>
166 template<
class S,
class I>
170 const size_t variable
180 template<
class S,
class I>
195 template<
class S,
class I>
199 const size_t variable,
209 template<
class S,
class I>
216 VariableAccessor accessor(
this, factor);
223 template<
class S,
class I>
230 VariableAccessor accessor(
this, factor);
237 template<
class S,
class I>
241 const size_t variable
244 FactorAccessor accessor(
this, variable);
251 template<
class S,
class I>
255 const size_t variable
258 FactorAccessor accessor(
this, variable);
266 template<
class S,
class I>
270 const size_t variable,
290 template<
class S,
class I>
295 const size_t variable
307 template<
class S,
class I>
311 const size_t variable1,
312 const size_t variable2
317 if(variable1 != variable2) {
324 else if(*it1 == *it2) {
337 template<
class S,
class I>
346 std::queue<size_t> factorQueue;
347 std::queue<size_t> variableQueue;
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();
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();
372 if(factorFathers[f] == NO_VARIABLE) {
373 factorFathers[f] = v;
376 else if(variableFathers[v] != f) {
390 template<
class S,
class I>
409 connectedComponents.
merge(*(iter - 1), *iter);
429 template<
class S,
class I>
435 if(numVariables == 0) {
445 if(numVariables == 1) {
453 size_t detectedEnds = 0;
454 for(
size_t i = 0; i < numVariables; i++) {
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];
479 size_t successor = std::numeric_limits<size_t>::max();
486 OPENGM_ASSERT(successor != std::numeric_limits<size_t>::max());
489 size_t countTraversedVariables = 1;
490 while(successor != ends[1]) {
493 if(countSecondOrderFactors > 2) {
497 chainIDs[countTraversedVariables] = successor;
498 countTraversedVariables++;
502 for(
size_t j = 0; j < 2; j++) {
504 if(possibleSuccesor != predecessor) {
505 predecessor = successor;
506 successor = possibleSuccesor;
512 if(countTraversedVariables != numVariables - 1) {
527 template<
class S,
class I>
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;
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>
727 template<
class S,
class I>
742 template<
class S,
class I>
746 size_t countNthOrderFactors = 0;
749 countNthOrderFactors++;
752 return countNthOrderFactors;
760 template<
class S,
class I>
769 countNthOrderFactors--;
770 factorIDs[countNthOrderFactors] = *iter;
774 return factorIDs.
size();
781 template<
class S,
class I>
789 if(*iter != variable) {
800 template<
class S,
class I>
804 const size_t factor1,
810 if(factor1 != factor2) {
817 else if(*it1 == *it2) {
830 template<
class S,
class I>
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>
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>
933 out[f].insert(fOfVar);
945 template<
class S,
class I>
946 template <
class LIST>
953 const size_t infinity = std::numeric_limits<size_t>::max();
955 bool useAllVariables = (allowedVariables.size() == 0) || (allowedVariables.size() ==
numberOfVariables());
957 if(useAllVariables) {
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);
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);
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) {
1084 if((*variableIter != variable1) || (*variableIter != variable2)) {
1086 oneHopVariables.push_back(*variableIter);
1092 if(oneHopVariables.size() == 0) {
1101 #endif // #ifndef OPENGM_FACTORGRAPH_HXX IndexType numberOfFactors() const
AccessorIterator< FactorAccessor, true > ConstFactorIterator
IndexType variableOfFactor(const IndexType, const IndexType) const
return the k-th variable of the j-th factor
ConstVariableIterator variablesOfFactorEnd(const size_t) const
constant iterator to the end of the squence of variables connected to a factor
bool variableFactorConnection(const size_t, const size_t) const
return true if a factor is connected to a variable
bool factorVariableConnection(const size_t, const size_t) const
return true if a variable is connected to a factor
void merge(value_type, value_type)
Merge two sets.
void variableAdjacencyMatrix(marray::Matrix< bool > &) const
outputs the factor graph as a variable adjacency matrix
Interface that makes an object of type S (the template parameter) look like a (non-editable) factor g...
bool isConnected(marray::Vector< size_t > &representatives) const
return true if the factor graph (!) is connected
bool twoHopConnected(const size_t, const size_t, LIST &) const
checks if variabel1 is connected to variable2 via two hops
size_t numberOfFactors() const
total number of factor nodes in the factor graph
void variableAdjacencyList(std::vector< std::set< IndexType > > &) const
outputs the factor graph as variable adjacency lists
bool isAcyclic() const
return true if the factor graph (!) is acyclic
bool operator==(const IndicatorVariable< INDEX1_TYPE, LABEL1_TYPE > &indicatorVar1, const IndicatorVariable< INDEX2_TYPE, LABEL2_TYPE > &indicatorVar2)
#define OPENGM_ASSERT(expression)
size_t variableOfFactor(const size_t, const size_t) const
j-th variable node connected to a factor node
size_t maxFactorOrder() const
return maximum factor order
void representatives(Iterator) const
Output all elements which are set representatives.
IndexType factorOfVariable(const IndexType, const IndexType) const
return the k-th factor connected to the j-th variable
size_t numberOfNthOrderFactorsOfVariable(const size_t, const size_t) const
return number of factors with order n which are connected to variable
bool isGrid(marray::Matrix< size_t > &) const
return true if the factor graph (!) is a grid
size_t factorOfVariable(const size_t, const size_t) const
j-th factor node connected to a variable node
ConstFactorIterator factorsOfVariableBegin(const size_t) const
constant iterator to the beginning of the squence of factors connected to a variable ...
ConstFactorIterator factorsOfVariableEnd(const size_t) const
constant iterator to the end of the squence of factors connected to a variable
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...
value_type numberOfSets() const
AccessorIterator< VariableAccessor, true > ConstVariableIterator
void transpose(const MatrixWrapper< T > &input, MatrixWrapper< T > &result)
void factorAdjacencyList(std::vector< std::set< IndexType > > &) const
bool isChain(marray::Vector< size_t > &) const
return true if the factor graph (!) is a chain
size_t numberOfVariables() const
total number of variable nodes in the factor graph
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 ...
IndexType numberOfVariables() const
bool factorFactorConnection(const size_t, const size_t) const
return true if a factor is connected to a factor
bool variableVariableConnection(const size_t, const size_t) const
return true if a variable is connected to a variable
Disjoint set data structure with path compression.
ConstVariableIterator variablesOfFactorBegin(const size_t) const
constant iterator to the beginning of the squence of variables connected to a factor ...
const size_t size() const
Get the number of data items.