00001 #pragma once
00002 #ifndef OPENGM_FACTORGRAPH_HXX
00003 #define OPENGM_FACTORGRAPH_HXX
00004
00005 #include <algorithm>
00006 #include <limits>
00007
00008 #include "opengm/utilities/accessor_iterator.hxx"
00009 #include "opengm/datastructures/randomaccessset.hxx"
00010 #include "opengm/datastructures/partition.hxx"
00011
00012 #include <typeinfo>
00013 namespace opengm {
00014
00017 template<class S,class I>
00018 class FactorGraph {
00019 private:
00020 class VariableAccessor;
00021 class FactorAccessor;
00022 typedef I IndexType;
00023 public:
00024 typedef S SpecialType;
00025 typedef AccessorIterator<VariableAccessor, true> ConstVariableIterator;
00026 typedef AccessorIterator<FactorAccessor, true> ConstFactorIterator;
00027
00028
00029 size_t numberOfVariables() const;
00030 size_t numberOfVariables(const size_t) const;
00031 size_t numberOfFactors() const;
00032 size_t numberOfFactors(const size_t) const;
00033 size_t variableOfFactor(const size_t, const size_t) const;
00034 size_t factorOfVariable(const size_t, const size_t) const;
00035
00036
00037 ConstVariableIterator variablesOfFactorBegin(const size_t) const;
00038 ConstVariableIterator variablesOfFactorEnd(const size_t) const;
00039 ConstFactorIterator factorsOfVariableBegin(const size_t) const;
00040 ConstFactorIterator factorsOfVariableEnd(const size_t) const;
00041 bool variableFactorConnection(const size_t, const size_t) const;
00042 bool factorVariableConnection(const size_t, const size_t) const;
00043 bool variableVariableConnection(const size_t, const size_t) const;
00044 bool factorFactorConnection(const size_t, const size_t) const;
00045 bool isAcyclic() const;
00046 bool isConnected(marray::Vector<size_t>& representatives) const;
00047 bool isChain(marray::Vector<size_t>&) const;
00048 bool isGrid(marray::Matrix<size_t>&) const;
00049
00050 size_t maxFactorOrder() const;
00051 bool maxFactorOrder(const size_t maxOrder) const;
00052 size_t numberOfNthOrderFactorsOfVariable(const size_t, const size_t) const;
00053 size_t numberOfNthOrderFactorsOfVariable(const size_t, const size_t, marray::Vector<size_t>&) const;
00054 size_t secondVariableOfSecondOrderFactor(const size_t, const size_t) const;
00055
00056
00057 void variableAdjacencyMatrix(marray::Matrix<bool>&) const;
00058 void variableAdjacencyList(std::vector<std::set<IndexType> >&) const;
00059 void variableAdjacencyList(std::vector<RandomAccessSet<IndexType> >&) const;
00060 void factorAdjacencyList(std::vector<std::set<IndexType> >&) const;
00061 void factorAdjacencyList(std::vector<RandomAccessSet<IndexType> >&) const;
00062
00063 protected:
00064
00065 operator S&()
00066 { return static_cast<S&>(*this); }
00067 operator S const&() const
00068 { return static_cast<const S&>(*this); }
00069
00070 template <class LIST>
00071 bool shortestPath(const size_t, const size_t, LIST&, const LIST& = LIST()) const;
00072 template <class LIST>
00073 bool twoHopConnected(const size_t, const size_t, LIST&) const;
00074
00075 private:
00076 class VariableAccessor {
00077 public:
00078 typedef size_t value_type;
00079
00080 VariableAccessor(const FactorGraph<S,I>* factorGraph = NULL, const size_t factor = 0)
00081 : factorGraph_(factorGraph), factor_(factor)
00082 {}
00083 VariableAccessor(const FactorGraph<S,I>& factorGraph, const size_t factor = 0)
00084 : factorGraph_(&factorGraph), factor_(factor)
00085 {}
00086 size_t size() const
00087 { OPENGM_ASSERT(factorGraph_ != NULL);
00088 return factorGraph_->numberOfVariables(factor_); }
00089 const size_t operator[](const size_t number) const
00090 { OPENGM_ASSERT(factorGraph_ != NULL);
00091 return factorGraph_->variableOfFactor(factor_, number); }
00092 bool operator==(const VariableAccessor& a) const
00093 { OPENGM_ASSERT(factorGraph_ != NULL);
00094 return factor_ == a.factor_ && factorGraph_ == a.factorGraph_; }
00095
00096 private:
00097 const FactorGraph<S,I>* factorGraph_;
00098 size_t factor_;
00099 };
00100
00101 class FactorAccessor {
00102 public:
00103 typedef I value_type;
00104
00105 FactorAccessor(const FactorGraph<S,I>* factorGraph = NULL, const size_t variable = 0)
00106 : factorGraph_(factorGraph), variable_(variable)
00107 {}
00108 FactorAccessor(const FactorGraph<S,I>& factorGraph, const size_t variable = 0)
00109 : factorGraph_(&factorGraph), variable_(variable)
00110 {}
00111 size_t size() const
00112 { OPENGM_ASSERT(factorGraph_ != NULL);
00113 return factorGraph_->numberOfFactors(variable_); }
00114 const size_t operator[](const size_t number) const
00115 { OPENGM_ASSERT(factorGraph_ != NULL);
00116 return factorGraph_->factorOfVariable(variable_, number); }
00117 bool operator==(const FactorAccessor& a) const
00118 { OPENGM_ASSERT(factorGraph_ != NULL);
00119 return variable_ == a.variable_ && factorGraph_ == a.factorGraph_; }
00120
00121 private:
00122 const FactorGraph<S,I>* factorGraph_;
00123 size_t variable_;
00124 };
00125
00126 template<class LIST>
00127 void templatedVariableAdjacencyList(LIST&) const;
00128 template<class LIST>
00129 void templatedFactorAdjacencyList(LIST&) const;
00130 };
00131
00134 template<class S,class I>
00135 inline size_t
00136 FactorGraph<S,I>::numberOfVariables() const
00137 {
00138 return static_cast<const SpecialType&>(*this).numberOfVariables();
00139 }
00140
00144 template<class S,class I>
00145 inline size_t
00146 FactorGraph<S,I>::numberOfVariables
00147 (
00148 const size_t factor
00149 ) const
00150 {
00151 return static_cast<const SpecialType&>(*this).numberOfVariables(factor);
00152 }
00153
00156 template<class S,class I>
00157 inline size_t
00158 FactorGraph<S,I>::numberOfFactors() const
00159 {
00160 return static_cast<const SpecialType&>(*this).numberOfFactors();
00161 }
00162
00166 template<class S,class I>
00167 inline size_t
00168 FactorGraph<S,I>::numberOfFactors
00169 (
00170 const size_t variable
00171 ) const
00172 {
00173 return static_cast<const SpecialType&>(*this).numberOfFactors(variable);
00174 }
00175
00180 template<class S,class I>
00181 inline size_t
00182 FactorGraph<S,I>::variableOfFactor
00183 (
00184 const size_t factor,
00185 const size_t j
00186 ) const
00187 {
00188 return static_cast<const SpecialType&>(*this).variableOfFactor(factor, j);
00189 }
00190
00195 template<class S,class I>
00196 inline size_t
00197 FactorGraph<S,I>::factorOfVariable
00198 (
00199 const size_t variable,
00200 const size_t j
00201 ) const
00202 {
00203 return static_cast<const SpecialType&>(*this).factorOfVariable(variable, j);
00204 }
00205
00209 template<class S,class I>
00210 inline typename FactorGraph<S,I>::ConstVariableIterator
00211 FactorGraph<S,I>::variablesOfFactorBegin
00212 (
00213 const size_t factor
00214 ) const
00215 {
00216 VariableAccessor accessor(this, factor);
00217 return ConstVariableIterator(accessor);
00218 }
00219
00223 template<class S,class I>
00224 inline typename FactorGraph<S,I>::ConstVariableIterator
00225 FactorGraph<S,I>::variablesOfFactorEnd
00226 (
00227 const size_t factor
00228 ) const
00229 {
00230 VariableAccessor accessor(this, factor);
00231 return ConstVariableIterator(accessor, numberOfVariables(factor));
00232 }
00233
00237 template<class S,class I>
00238 inline typename FactorGraph<S,I>::ConstFactorIterator
00239 FactorGraph<S,I>::factorsOfVariableBegin
00240 (
00241 const size_t variable
00242 ) const
00243 {
00244 FactorAccessor accessor(this, variable);
00245 return ConstFactorIterator(accessor);
00246 }
00247
00251 template<class S,class I>
00252 inline typename FactorGraph<S,I>::ConstFactorIterator
00253 FactorGraph<S,I>::factorsOfVariableEnd
00254 (
00255 const size_t variable
00256 ) const
00257 {
00258 FactorAccessor accessor(this, variable);
00259 return ConstFactorIterator(accessor, numberOfFactors(variable));
00260 }
00261
00266 template<class S,class I>
00267 inline bool
00268 FactorGraph<S,I>::variableFactorConnection
00269 (
00270 const size_t variable,
00271 const size_t factor
00272 ) const
00273 {
00274 OPENGM_ASSERT(factor < numberOfFactors());
00275 OPENGM_ASSERT(variable < numberOfVariables());
00276 if(!NO_DEBUG) {
00277 for(size_t j=1; j<numberOfVariables(factor); ++j) {
00278 OPENGM_ASSERT(variableOfFactor(factor, j-1) < variableOfFactor(factor, j));
00279 }
00280 }
00281 return std::binary_search(variablesOfFactorBegin(factor),
00282 variablesOfFactorEnd(factor), variable);
00283 return false;
00284 }
00285
00290 template<class S,class I>
00291 inline bool
00292 FactorGraph<S,I>::factorVariableConnection
00293 (
00294 const size_t factor,
00295 const size_t variable
00296 ) const
00297 {
00298 OPENGM_ASSERT(factor < numberOfFactors());
00299 OPENGM_ASSERT(variable < numberOfVariables());
00300 return variableFactorConnection(variable, factor);
00301 }
00302
00307 template<class S,class I>
00308 inline bool
00309 FactorGraph<S,I>::variableVariableConnection
00310 (
00311 const size_t variable1,
00312 const size_t variable2
00313 ) const
00314 {
00315 OPENGM_ASSERT(variable1 < numberOfVariables());
00316 OPENGM_ASSERT(variable2 < numberOfVariables());
00317 if(variable1 != variable2) {
00318 ConstFactorIterator it1 = factorsOfVariableBegin(variable1);
00319 ConstFactorIterator it2 = factorsOfVariableBegin(variable2);
00320 while(it1 != factorsOfVariableEnd(variable1) && it2 != factorsOfVariableEnd(variable2)) {
00321 if(*it1 < *it2) {
00322 ++it1;
00323 }
00324 else if(*it1 == *it2) {
00325 return true;
00326 }
00327 else {
00328 ++it2;
00329 }
00330 }
00331 }
00332 return false;
00333 }
00334
00337 template<class S,class I>
00338 bool
00339 FactorGraph<S,I>::isAcyclic() const
00340 {
00341 const size_t NO_FACTOR = numberOfFactors();
00342 const size_t NO_VARIABLE = numberOfVariables();
00343 const size_t ROOT_FACTOR = numberOfVariables() + 1;
00344 std::vector<size_t> factorFathers(numberOfFactors(), NO_VARIABLE);
00345 std::vector<size_t> variableFathers(numberOfVariables(), NO_FACTOR);
00346 std::queue<size_t> factorQueue;
00347 std::queue<size_t> variableQueue;
00348 for(size_t F = 0; F < numberOfFactors(); ++F) {
00349 if(factorFathers[F] == NO_VARIABLE) {
00350 factorFathers[F] = ROOT_FACTOR;
00351 factorQueue.push(F);
00352 while(!factorQueue.empty()) {
00353 while(!factorQueue.empty()) {
00354 const size_t f = factorQueue.front();
00355 factorQueue.pop();
00356 for(size_t j = 0; j < numberOfVariables(f); ++j) {
00357 const size_t v = variableOfFactor(f, j);
00358 if(variableFathers[v] == NO_FACTOR) {
00359 variableFathers[v] = f;
00360 variableQueue.push(v);
00361 }
00362 else if(factorFathers[f] != v) {
00363 return false;
00364 }
00365 }
00366 }
00367 while(!variableQueue.empty()) {
00368 const size_t v = variableQueue.front();
00369 variableQueue.pop();
00370 for(size_t j = 0; j < numberOfFactors(v); ++j) {
00371 const size_t f = factorOfVariable(v, j);
00372 if(factorFathers[f] == NO_VARIABLE) {
00373 factorFathers[f] = v;
00374 factorQueue.push(f);
00375 }
00376 else if(variableFathers[v] != f) {
00377 return false;
00378 }
00379 }
00380 }
00381 }
00382 }
00383 }
00384 return true;
00385 }
00386
00390 template<class S,class I>
00391 bool
00392 FactorGraph<S,I>::isConnected(marray::Vector<size_t>& representatives) const
00393 {
00394
00395 if(numberOfVariables() == 0) {
00396 return false;
00397 }
00398
00399
00400 Partition<size_t> connectedComponents(numberOfVariables());
00401
00402 for(size_t i = 0; i < numberOfFactors(); i++) {
00403
00404 const ConstVariableIterator variablesBegin = variablesOfFactorBegin(i);
00405 const ConstVariableIterator variablesEnd = variablesOfFactorEnd(i);
00406 OPENGM_ASSERT(variablesBegin != variablesEnd);
00407
00408 for(ConstVariableIterator iter = variablesBegin + 1; iter != variablesEnd; iter++) {
00409 connectedComponents.merge(*(iter - 1), *iter);
00410 }
00411 }
00412
00413
00414 OPENGM_ASSERT(connectedComponents.numberOfSets() > 0);
00415
00416 representatives = marray::Vector<size_t>(connectedComponents.numberOfSets());
00417 connectedComponents.representatives(representatives.begin());
00418
00419 if(connectedComponents.numberOfSets() == 1) {
00420 return true;
00421 } else {
00422 return false;
00423 }
00424 }
00425
00429 template<class S,class I>
00430 inline bool
00431 FactorGraph<S,I>::isChain(marray::Vector<size_t>& chainIDs) const {
00432 const size_t numVariables = numberOfVariables();
00433
00434
00435 if(numVariables == 0) {
00436 return false;
00437 }
00438
00439
00440 if(!maxFactorOrder(2)) {
00441 return false;
00442 }
00443
00444
00445 if(numVariables == 1) {
00446 chainIDs = marray::Vector<size_t>(numVariables);
00447 chainIDs[0] = 0;
00448 return true;
00449 }
00450
00451
00452 marray::Vector<size_t> ends(2);
00453 size_t detectedEnds = 0;
00454 for(size_t i = 0; i < numVariables; i++) {
00455 size_t countSecondOrderFactors = numberOfNthOrderFactorsOfVariable(i, 2);
00456 if(countSecondOrderFactors == 1) {
00457 if(detectedEnds > 1) {
00458 return false;
00459 }
00460 ends[detectedEnds] = i;
00461 detectedEnds++;
00462 }
00463 }
00464
00465
00466 if(detectedEnds != 2) {
00467 return false;
00468 }
00469
00470 chainIDs = marray::Vector<size_t>(numVariables);
00471
00472 chainIDs[0] = ends[0];
00473 chainIDs[numVariables - 1] = ends[1];
00474
00475
00476
00477 size_t predecessor = ends[0];
00478 OPENGM_ASSERT(numberOfVariables() < std::numeric_limits<size_t>::max());
00479 size_t successor = std::numeric_limits<size_t>::max();
00480 for(ConstFactorIterator iter = factorsOfVariableBegin(ends[0]); iter != factorsOfVariableEnd(ends[0]); iter++) {
00481 if(numberOfVariables(*iter) == 2) {
00482 successor = secondVariableOfSecondOrderFactor(ends[0], *iter);
00483 }
00484 }
00485
00486 OPENGM_ASSERT(successor != std::numeric_limits<size_t>::max());
00487
00488
00489 size_t countTraversedVariables = 1;
00490 while(successor != ends[1]) {
00491 marray::Vector<size_t> secondOrderFactorIds;
00492 size_t countSecondOrderFactors = numberOfNthOrderFactorsOfVariable(successor, 2, secondOrderFactorIds);
00493 if(countSecondOrderFactors > 2) {
00494 return false;
00495 }
00496
00497 chainIDs[countTraversedVariables] = successor;
00498 countTraversedVariables++;
00499
00500
00501 OPENGM_ASSERT(secondOrderFactorIds.size() == 2);
00502 for(size_t j = 0; j < 2; j++) {
00503 size_t possibleSuccesor = secondVariableOfSecondOrderFactor(successor, secondOrderFactorIds[j]);
00504 if(possibleSuccesor != predecessor) {
00505 predecessor = successor;
00506 successor = possibleSuccesor;
00507 break;
00508 }
00509 }
00510 }
00511
00512 if(countTraversedVariables != numVariables - 1) {
00513
00514 return false;
00515 }
00516 OPENGM_ASSERT(countTraversedVariables == numVariables - 1);
00517
00518
00519 OPENGM_ASSERT(chainIDs[numVariables - 1] == ends[1]);
00520
00521 return true;
00522 }
00523
00527 template<class S,class I>
00528 inline bool
00529 FactorGraph<S,I>::isGrid(marray::Matrix<size_t>& gridIDs) const {
00530
00531
00532 if(numberOfVariables() == 0) {
00533 return false;
00534 }
00535
00536
00537 if(!maxFactorOrder(2)) {
00538 return false;
00539 }
00540
00541
00542 if(numberOfVariables() == 1) {
00543 gridIDs = marray::Matrix<size_t>(1,1);
00544 gridIDs(0, 0) = 0;
00545 return true;
00546 }
00547
00548
00549 marray::Vector<size_t> chainIDs;
00550 bool graphIsChain = isChain(chainIDs);
00551 if(graphIsChain) {
00552 gridIDs = marray::Matrix<size_t>(1, chainIDs.size());
00553 for(size_t i = 0; i < chainIDs.size(); i++) {
00554 gridIDs(0, i) = chainIDs[i];
00555 }
00556 return true;
00557 }
00558
00559
00560
00561 marray::Vector<size_t> cornerIDs(4);
00562 size_t numCornersFound = 0;
00563 std::list<size_t> outerHullVariableIDs;
00564
00565 for(size_t i = 0; i < numberOfVariables(); i++) {
00566 size_t countSecondOrderFactors = numberOfNthOrderFactorsOfVariable(i, 2);
00567 if(countSecondOrderFactors == 2) {
00568
00569 if(numCornersFound > 3) {
00570 return false;
00571 }
00572 cornerIDs(numCornersFound) = i;
00573 numCornersFound++;
00574
00575 outerHullVariableIDs.push_back(i);
00576 } else if(countSecondOrderFactors == 3) {
00577 outerHullVariableIDs.push_back(i);
00578 } else if(countSecondOrderFactors > 4) {
00579
00580 return false;
00581 }
00582 }
00583
00584 if(numCornersFound < 4) {
00585 return false;
00586 }
00587
00588 OPENGM_ASSERT(numCornersFound == 4);
00589
00590
00591 std::vector<std::list<size_t> > shortestPaths(3);
00592 if(!shortestPath(cornerIDs(0), cornerIDs(1), shortestPaths[0], outerHullVariableIDs)) {
00593 return false;
00594 }
00595
00596 if(!shortestPath(cornerIDs(0), cornerIDs(2), shortestPaths[1], outerHullVariableIDs)) {
00597 return false;
00598 }
00599
00600 if(!shortestPath(cornerIDs(0), cornerIDs(3), shortestPaths[2], outerHullVariableIDs)) {
00601 return false;
00602 }
00603
00604
00605 size_t diagonalCorner = 1;
00606 for(size_t i = 1; i < 4; i++) {
00607 if(shortestPaths[i - 1].size() > shortestPaths[diagonalCorner].size()) {
00608 diagonalCorner = i;
00609 }
00610 }
00611
00612
00613 std::vector<std::list<size_t> > shortestAdjacentCornerPaths(2);
00614 size_t shortestAdjacentCornerPathsComputed = 0;
00615 for(size_t i = 1; i < 4; i++) {
00616 if(i != diagonalCorner) {
00617 if(!shortestPath(cornerIDs(i), cornerIDs(diagonalCorner), shortestAdjacentCornerPaths[shortestAdjacentCornerPathsComputed], outerHullVariableIDs)) {
00618 return false;
00619 }
00620 shortestAdjacentCornerPathsComputed++;
00621 }
00622 }
00623 OPENGM_ASSERT(shortestAdjacentCornerPathsComputed == 2);
00624
00625
00626 std::vector<size_t> dimension(2);
00627 size_t dimensionIndex = 0;
00628 for(size_t i = 1; i < 4; i++) {
00629 if(i != diagonalCorner) {
00630 dimension[dimensionIndex] = shortestPaths[i - 1].size();
00631 dimensionIndex++;
00632 }
00633 }
00634 OPENGM_ASSERT(dimensionIndex == 2);
00635
00636
00637 if(dimension[0] != shortestAdjacentCornerPaths[1].size()) {
00638 return false;
00639 }
00640 if(dimension[1] != shortestAdjacentCornerPaths[0].size()) {
00641 return false;
00642 }
00643
00644
00645 gridIDs = marray::Matrix<size_t>(dimension[0], dimension[1]);
00646
00647
00648
00649 bool transpose = false;
00650 for(size_t i = 1; i < 4; i++) {
00651 if(i != diagonalCorner) {
00652 size_t indexHelper = 0;
00653 if(transpose == false) {
00654 for(typename std::list<size_t>::iterator iter = shortestPaths[i - 1].begin(); iter != shortestPaths[i - 1].end(); iter++) {
00655 gridIDs(indexHelper, 0) = *iter;
00656 indexHelper++;
00657 }
00658 transpose = true;
00659 } else {
00660 for(typename std::list<size_t>::iterator iter = shortestPaths[i - 1].begin(); iter != shortestPaths[i - 1].end(); iter++) {
00661 gridIDs(0, indexHelper) = *iter;
00662 indexHelper++;
00663 }
00664 }
00665
00666 }
00667 }
00668
00669
00670 transpose = false;
00671 for(size_t i = 0; i <= 1; i++) {
00672 size_t indexHelper = 0;
00673 if(transpose == false) {
00674 for(typename std::list<size_t>::iterator iter = shortestAdjacentCornerPaths[i].begin(); iter != shortestAdjacentCornerPaths[i].end(); iter++) {
00675 gridIDs(dimension[0] - 1, indexHelper) = *iter;
00676 indexHelper++;
00677 }
00678 transpose = true;
00679 } else {
00680 for(typename std::list<size_t>::iterator iter = shortestAdjacentCornerPaths[i].begin(); iter != shortestAdjacentCornerPaths[i].end(); iter++) {
00681 gridIDs(indexHelper, dimension[1] - 1) = *iter;
00682 indexHelper++;
00683 }
00684 }
00685 }
00686
00687
00688 for(size_t i = 1; i < dimension[0] - 1; i++) {
00689 for(size_t j = 1; j < dimension[1] - 1; j++) {
00690 std::vector<size_t> oneHopVariables;
00691 if(twoHopConnected(gridIDs(i - 1, j), gridIDs(i, j - 1), oneHopVariables)) {
00692 if(oneHopVariables.size() < 2) {
00693 return false;
00694 }
00695 OPENGM_ASSERT(oneHopVariables.size() == 2);
00696 if(oneHopVariables[0] != gridIDs(i - 1, j - 1)) {
00697 gridIDs(i, j) = oneHopVariables[0];
00698 } else {
00699 gridIDs(i, j) = oneHopVariables[1];
00700 }
00701 } else {
00702 return false;
00703 }
00704 }
00705 }
00706
00707 return true;
00708 }
00709
00712 template<class S,class I>
00713 inline size_t
00714 FactorGraph<S,I>::maxFactorOrder() const {
00715 size_t maxFactorOrder = 0;
00716 for(size_t i = 0; i < numberOfFactors(); i++) {
00717 if(numberOfVariables(i) > maxFactorOrder) {
00718 maxFactorOrder = numberOfVariables(i);
00719 }
00720 }
00721 return maxFactorOrder;
00722 }
00723
00727 template<class S,class I>
00728 inline bool
00729 FactorGraph<S,I>::maxFactorOrder(const size_t maxOrder) const {
00730 for(size_t i = 0; i < numberOfFactors(); i++) {
00731 if(numberOfVariables(i) > maxOrder) {
00732 return false;
00733 }
00734 }
00735 return true;
00736 }
00737
00742 template<class S,class I>
00743 inline size_t
00744 FactorGraph<S,I>::numberOfNthOrderFactorsOfVariable(const size_t variable, const size_t n) const {
00745 OPENGM_ASSERT(variable < numberOfVariables());
00746 size_t countNthOrderFactors = 0;
00747 for(ConstFactorIterator iter = factorsOfVariableBegin(variable); iter != factorsOfVariableEnd(variable); iter++) {
00748 if(numberOfVariables(*iter) == n) {
00749 countNthOrderFactors++;
00750 }
00751 }
00752 return countNthOrderFactors;
00753 }
00754
00760 template<class S,class I>
00761 inline size_t
00762 FactorGraph<S,I>::numberOfNthOrderFactorsOfVariable(const size_t variable, const size_t n, marray::Vector<size_t>& factorIDs) const {
00763 OPENGM_ASSERT(variable < numberOfVariables());
00764
00765 size_t countNthOrderFactors = numberOfNthOrderFactorsOfVariable(variable, n);
00766 factorIDs = marray::Vector<size_t>(countNthOrderFactors);
00767 for(ConstFactorIterator iter = factorsOfVariableBegin(variable); iter != factorsOfVariableEnd(variable); iter++) {
00768 if(numberOfVariables(*iter) == n) {
00769 countNthOrderFactors--;
00770 factorIDs[countNthOrderFactors] = *iter;
00771 }
00772 }
00773 OPENGM_ASSERT(countNthOrderFactors == 0);
00774 return factorIDs.size();
00775 }
00776
00781 template<class S,class I>
00782 inline size_t
00783 FactorGraph<S,I>::secondVariableOfSecondOrderFactor(const size_t variable, const size_t factor) const {
00784 OPENGM_ASSERT(variable < numberOfVariables());
00785 OPENGM_ASSERT(factor < numberOfFactors());
00786 OPENGM_ASSERT(numberOfVariables(factor) == 2);
00787 OPENGM_ASSERT(variableFactorConnection(variable, factor));
00788 for(ConstVariableIterator iter = variablesOfFactorBegin(factor); iter != variablesOfFactorEnd(factor); iter++) {
00789 if(*iter != variable) {
00790 return *iter;
00791 }
00792 }
00793 return variable;
00794 }
00795
00800 template<class S,class I>
00801 inline bool
00802 FactorGraph<S,I>::factorFactorConnection
00803 (
00804 const size_t factor1,
00805 const size_t factor2
00806 ) const
00807 {
00808 OPENGM_ASSERT(factor1 < numberOfFactors());
00809 OPENGM_ASSERT(factor2 < numberOfFactors());
00810 if(factor1 != factor2) {
00811 ConstVariableIterator it1 = variablesOfFactorBegin(factor1);
00812 ConstVariableIterator it2 = variablesOfFactorBegin(factor2);
00813 while(it1 != variablesOfFactorEnd(factor1) && it2 != variablesOfFactorEnd(factor2)) {
00814 if(*it1 < *it2) {
00815 ++it1;
00816 }
00817 else if(*it1 == *it2) {
00818 return true;
00819 }
00820 else {
00821 ++it2;
00822 }
00823 }
00824 }
00825 return false;
00826 }
00827
00830 template<class S,class I>
00831 inline void
00832 FactorGraph<S,I>::variableAdjacencyMatrix
00833 (
00834 marray::Matrix<bool>& out
00835 ) const
00836 {
00837 out = marray::Matrix<bool>(numberOfVariables(), numberOfVariables(), false);
00838 for(size_t factor=0; factor<numberOfFactors(); ++factor) {
00839 for(size_t j=0; j<numberOfVariables(factor); ++j) {
00840 for(size_t k=j+1; k<numberOfVariables(factor); ++k) {
00841 const size_t variable1 = variableOfFactor(factor, j);
00842 const size_t variable2 = variableOfFactor(factor, k);
00843 out(variable1, variable2) = true;
00844 out(variable2, variable1) = true;
00845 }
00846 }
00847 }
00848 }
00849
00852 template<class S,class I>
00853 inline void
00854 FactorGraph<S,I>::variableAdjacencyList
00855 (
00856 std::vector<RandomAccessSet<IndexType> >& out
00857 ) const
00858 {
00859 templatedVariableAdjacencyList(out);
00860 }
00861
00864 template<class S,class I>
00865 inline void
00866 FactorGraph<S,I>::variableAdjacencyList
00867 (
00868 std::vector<std::set<IndexType> >& out
00869 ) const
00870 {
00871 templatedVariableAdjacencyList(out);
00872 }
00873
00876 template<class S,class I>
00877 template<class LIST>
00878 inline void
00879 FactorGraph<S,I>::templatedVariableAdjacencyList
00880 (
00881 LIST& out
00882 ) const
00883 {
00884 out.clear();
00885 out.resize(numberOfVariables());
00886 for(size_t factor=0; factor<numberOfFactors(); ++factor) {
00887 for(size_t j=0; j<numberOfVariables(factor); ++j) {
00888 for(size_t k=j+1; k<numberOfVariables(factor); ++k) {
00889 const size_t variable1 = variableOfFactor(factor, j);
00890 const size_t variable2 = variableOfFactor(factor, k);
00891 out[variable1].insert(variable2);
00892 out[variable2].insert(variable1);
00893 }
00894 }
00895 }
00896 }
00897
00898 template<class S,class I>
00899 inline void
00900 FactorGraph<S,I>::factorAdjacencyList
00901 (
00902 std::vector<std::set<IndexType> >& out
00903 ) const
00904 {
00905 templatedFactorAdjacencyList(out);
00906 }
00907
00908 template<class S,class I>
00909 inline void
00910 FactorGraph<S,I>::factorAdjacencyList
00911 (
00912 std::vector< RandomAccessSet<IndexType> >& out
00913 ) const
00914 {
00915 templatedFactorAdjacencyList(out);
00916 }
00917
00918 template<class S,class I>
00919 template<class LIST>
00920 inline void
00921 FactorGraph<S,I>::templatedFactorAdjacencyList
00922 (
00923 LIST& out
00924 ) const
00925 {
00926 out.clear();
00927 out.resize(numberOfFactors());
00928 for(size_t f=0; f<numberOfFactors(); ++f) {
00929 for(size_t v=0 ;v<numberOfVariables(f); ++v) {
00930 for(size_t ff=0;ff<numberOfFactors(v);++ff) {
00931 const size_t fOfVar=factorOfVariable(v,ff);
00932 if(f!=fOfVar) {
00933 out[f].insert(fOfVar);
00934 }
00935 }
00936 }
00937 }
00938 }
00939
00945 template<class S,class I>
00946 template <class LIST>
00947 inline bool
00948 FactorGraph<S,I>::shortestPath(const size_t s, const size_t t, LIST& path, const LIST& allowedVariables) const {
00949 OPENGM_ASSERT(s < numberOfVariables());
00950 OPENGM_ASSERT(t < numberOfVariables());
00951 OPENGM_ASSERT(allowedVariables.size() <= numberOfVariables());
00952 OPENGM_ASSERT(numberOfVariables() != std::numeric_limits<size_t>::max());
00953 const size_t infinity = std::numeric_limits<size_t>::max();
00954
00955 bool useAllVariables = (allowedVariables.size() == 0) || (allowedVariables.size() == numberOfVariables());
00956
00957 if(useAllVariables) {
00958 std::vector<size_t> distances(numberOfVariables(), infinity);
00959 std::vector<size_t> previous(numberOfVariables(), infinity);
00960 distances[s] = 0;
00961 LIST Q;
00962 for(size_t i = 0; i < numberOfVariables(); i++) {
00963 Q.push_back(i);
00964 }
00965 while(Q.size() !=0) {
00966 typename LIST::iterator currentIter = Q.begin();
00967 for(typename LIST::iterator iter = Q.begin(); iter != Q.end(); iter++) {
00968 if(distances[*iter] < distances[*currentIter]) {
00969 currentIter = iter;
00970 }
00971 }
00972 if(distances[*currentIter] == infinity) {
00973
00974 return false;
00975 }
00976 if(*currentIter == t) {
00977
00978 break;
00979 }
00980 size_t currentID = *currentIter;
00981 Q.erase(currentIter);
00982
00983 for(ConstFactorIterator factorIter = factorsOfVariableBegin(currentID); factorIter != factorsOfVariableEnd(currentID); factorIter++) {
00984 for(ConstVariableIterator variableIter = variablesOfFactorBegin(*factorIter); variableIter != variablesOfFactorEnd(*factorIter); variableIter++) {
00985 if(std::find(Q.begin(), Q.end(), *variableIter) != Q.end()) {
00986 size_t newDistance = distances[currentID] + 1;
00987 if(newDistance < distances[*variableIter]) {
00988 distances[*variableIter] = newDistance;
00989 previous[*variableIter] = currentID;
00990 }
00991 }
00992 }
00993 }
00994 }
00995 OPENGM_ASSERT(previous[t] != infinity);
00996
00997 size_t u = t;
00998 while(previous[u] != infinity) {
00999 path.push_front(u);
01000 u = previous[u];
01001 }
01002 path.push_front(s);
01003 return true;
01004 } else {
01005 OPENGM_ASSERT(std::find(allowedVariables.begin(), allowedVariables.end(), s) != allowedVariables.end());
01006 OPENGM_ASSERT(std::find(allowedVariables.begin(), allowedVariables.end(), t) != allowedVariables.end());
01007 std::vector<size_t> distances(allowedVariables.size(), infinity);
01008 std::vector<size_t> previous(allowedVariables.size(), infinity);
01009 std::map<size_t, size_t> local2actualIDs;
01010 std::map<size_t, size_t> actual2localIDs;
01011 LIST Q;
01012 size_t counter = 0;
01013 for(typename LIST::const_iterator iter = allowedVariables.begin(); iter != allowedVariables.end(); iter++) {
01014 Q.push_back(counter);
01015 local2actualIDs.insert(std::pair<size_t, size_t>(counter, *iter));
01016 actual2localIDs.insert(std::pair<size_t, size_t>(*iter, counter));
01017 counter++;
01018 }
01019 distances[actual2localIDs.find(s)->second] = 0;
01020 while(Q.size() !=0) {
01021 typename LIST::iterator currentIter = Q.begin();
01022 for(typename LIST::iterator iter = Q.begin(); iter != Q.end(); iter++) {
01023 if(distances[*iter] < distances[*currentIter]) {
01024 currentIter = iter;
01025 }
01026 }
01027 if(distances[*currentIter] == infinity) {
01028
01029 return false;
01030 }
01031
01032 size_t actualID = local2actualIDs.find(*currentIter)->second;
01033 if(actualID == t) {
01034
01035 break;
01036 }
01037 size_t currentLocalID = *currentIter;
01038 Q.erase(currentIter);
01039
01040 for(ConstFactorIterator factorIter = factorsOfVariableBegin(actualID); factorIter != factorsOfVariableEnd(actualID); factorIter++) {
01041 for(ConstVariableIterator variableIter = variablesOfFactorBegin(*factorIter); variableIter != variablesOfFactorEnd(*factorIter); variableIter++) {
01042 const std::map<size_t, size_t>::const_iterator actual2localIDsCurrentPosition = actual2localIDs.find(*variableIter);
01043 if(actual2localIDsCurrentPosition != actual2localIDs.end()) {
01044 size_t localID = actual2localIDsCurrentPosition->second;
01045 if(std::find(Q.begin(), Q.end(), localID) != Q.end()) {
01046 size_t newDistance = distances[currentLocalID] + 1;
01047 if(newDistance < distances[localID]) {
01048 distances[localID] = newDistance;
01049 previous[localID] = currentLocalID;
01050 }
01051 }
01052 }
01053 }
01054 }
01055 }
01056 OPENGM_ASSERT(actual2localIDs.find(t)->second != infinity);
01057
01058 size_t u = actual2localIDs.find(t)->second;
01059 while(previous[u] != infinity) {
01060
01061 path.push_front(local2actualIDs.find(u)->second);
01062 u = previous[u];
01063 }
01064 path.push_front(s);
01065 return true;
01066 }
01067 return false;
01068 }
01069
01074 template<class S,class I>
01075 template <class LIST>
01076 inline bool
01077 FactorGraph<S,I>::twoHopConnected(const size_t variable1, const size_t variable2, LIST& oneHopVariables) const {
01078 OPENGM_ASSERT(variable1 < numberOfVariables());
01079 OPENGM_ASSERT(variable2 < numberOfVariables());
01080 oneHopVariables.clear();
01081 if(variable1 != variable2) {
01082 for(ConstFactorIterator factorIter = factorsOfVariableBegin(variable1); factorIter != factorsOfVariableEnd(variable1); factorIter++) {
01083 for(ConstVariableIterator variableIter = variablesOfFactorBegin(*factorIter); variableIter != variablesOfFactorEnd(*factorIter); variableIter++) {
01084 if((*variableIter != variable1) || (*variableIter != variable2)) {
01085 if(variableVariableConnection(*variableIter, variable2)) {
01086 oneHopVariables.push_back(*variableIter);
01087 }
01088 }
01089 }
01090 }
01091 }
01092 if(oneHopVariables.size() == 0) {
01093 return false;
01094 } else {
01095 return true;
01096 }
01097 }
01098
01099 }
01100
01101 #endif // #ifndef OPENGM_FACTORGRAPH_HXX