00001 #pragma once
00002 #ifndef OPENGM_GRAPHICALMODELDECOMPOSER_HXX
00003 #define OPENGM_GRAPHICALMODELDECOMPOSER_HXX
00004
00005 #include <exception>
00006 #include <set>
00007 #include <vector>
00008 #include <list>
00009 #include <map>
00010 #include <queue>
00011 #include <limits>
00012
00013 #include "opengm/datastructures/partition.hxx"
00014 #include "opengm/graphicalmodel/decomposition/graphicalmodeldecomposition.hxx"
00015 #include "opengm/functions/scaled_view.hxx"
00016
00017 namespace opengm {
00018
00020
00021 template <class GM>
00022 class GraphicalModelDecomposer
00023 {
00024 public:
00025 typedef GM GraphicalModelType;
00026 typedef GraphicalModelDecomposition DecompositionType;
00027 typedef typename GraphicalModelType::FactorType FactorType;
00028 typedef typename GraphicalModelType::FunctionIdentifier FunctionIdentifierType;
00029 typedef typename DecompositionType::SubFactor SubFactorType;
00030 typedef typename DecompositionType::SubVariable SubVariableType;
00031 typedef typename DecompositionType::SubFactorListType SubFactorListType;
00032 typedef typename DecompositionType::SubVariableListType SubVariableListType;
00033
00034 typedef typename GraphicalModelType::ValueType ValueType;
00035 typedef typename GraphicalModelType::OperatorType OperatorType;
00036
00037
00038
00039
00040 GraphicalModelDecomposer();
00041
00042
00043 DecompositionType decomposeManual(const GraphicalModelType&, const std::vector<std::vector<size_t> >& subModelFactors) const;
00044 DecompositionType decomposeIntoTree(const GraphicalModelType&) const;
00045 DecompositionType decomposeIntoSpanningTrees(const GraphicalModelType&) const;
00046 DecompositionType decomposeIntoKFans(const GraphicalModelType&, const std::vector<std::set<size_t> >&) const;
00047 DecompositionType decomposeIntoKFans(const GraphicalModelType&, const size_t k) const;
00048 DecompositionType decomposeIntoClosedBlocks(const GraphicalModelType&, const std::vector<std::set<size_t> >&) const;
00049 DecompositionType decomposeIntoOpenBlocks(const GraphicalModelType&, const std::vector<std::set<size_t> >&) const;
00050 DecompositionType decomposeIntoClosedBlocks(const GraphicalModelType&, const size_t) const;
00051 };
00052
00053 template <class GM>
00054 inline GraphicalModelDecomposer<GM>::
00055 GraphicalModelDecomposer()
00056 {}
00057
00058 template <class GM>
00059 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00060 decomposeManual
00061 (
00062 const GraphicalModelType& gm,
00063 const std::vector<std::vector<size_t> >& subModelFactors
00064 ) const
00065 {
00066 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00067 for(size_t subModel=0; subModel<subModelFactors.size(); ++subModel) {
00068 decomposition.addSubModel();
00069 }
00070 for(size_t subModel=0; subModel<subModelFactors.size(); ++subModel) {
00071 std::vector<size_t> subVariableIds(gm.numberOfVariables(),gm.numberOfVariables());
00072 for(size_t factorId=0; factorId<subModelFactors[subModel].size(); ++factorId) {
00073 std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables());
00074 for(size_t j=0; j<gm[factorId].numberOfVariables(); ++j) {
00075 const size_t variableIndex = gm[factorId].variableIndex(j);
00076 if(subVariableIds[variableIndex] == gm.numberOfVariables()) {
00077 subVariableIds[variableIndex] = decomposition.addSubVariable(subModel,variableIndex);
00078 }
00079 subVariableIndices[j] = subVariableIds[variableIndex];
00080 }
00081 decomposition.addSubFactor( subModel, factorId, subVariableIndices );
00082 }
00083 }
00084 decomposition.reorder();
00085 return decomposition;
00086 }
00087
00088 template <class GM>
00089 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00090 decomposeIntoTree
00091 (
00092 const GraphicalModelType& gm
00093 ) const
00094 {
00095 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00096
00097 decomposition.addSubModel();
00098 Partition<size_t> partition(gm.numberOfVariables());
00099 for(size_t variableId=0; variableId<gm.numberOfVariables();++variableId) {
00100 decomposition.addSubVariable(0,variableId);
00101 }
00102 for(size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
00103 std::map<size_t, size_t> counters;
00104 std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables());
00105 for(size_t j=0; j<gm[factorId].numberOfVariables(); ++j) {
00106 const size_t variableIndex = gm[factorId].variableIndex(j);
00107 if( ++counters[partition.find(variableIndex)] > 1) {
00108 subVariableIndices[j] = decomposition.addSubVariable(0,variableIndex);
00109 }
00110 else{
00111 subVariableIndices[j] = variableIndex;
00112 }
00113 }
00114 decomposition.addSubFactor(0,factorId,subVariableIndices);
00115 for(size_t j=1; j<gm[factorId].numberOfVariables(); ++j) {
00116 partition.merge(gm[factorId].variableIndex(j-1), gm[factorId].variableIndex(j));
00117 }
00118 }
00119 decomposition.reorder();
00120 return decomposition;
00121 }
00122
00123 template <class GM>
00124 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00125 decomposeIntoSpanningTrees
00126 (
00127 const GraphicalModelType& gm
00128 ) const
00129 {
00130 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00131
00132 std::list<size_t> blackList;
00133 std::list<size_t> grayList;
00134 std::list<size_t> whiteList;
00135 for(size_t j=0; j<gm.numberOfFactors(); ++j) {
00136 whiteList.push_back(j);
00137 }
00138
00139 while(!whiteList.empty()) {
00140 size_t subModelId = decomposition.addSubModel();
00141 for(size_t variableId=0; variableId<gm.numberOfVariables();++variableId) {
00142 decomposition.addSubVariable(subModelId,variableId);
00143 }
00144
00145 Partition<size_t> partition(gm.numberOfVariables());
00146 std::list<size_t>* currentList;
00147
00148 for(size_t listSwap=0; listSwap<2; ++listSwap) {
00149 if(listSwap == 0) {
00150 currentList = &whiteList;
00151 }
00152 else {
00153 currentList = &blackList;
00154 }
00155
00156 std::list<size_t>::iterator it = currentList->begin();
00157 while(it != currentList->end()) {
00158
00159 bool insert = true;
00160 const FactorType& factor = gm[*it];
00161 std::map<size_t, size_t> counters;
00162 for(size_t j=0; j<factor.numberOfVariables(); ++j) {
00163 if( ++counters[partition.find(factor.variableIndex(j))] > 1) {
00164
00165 insert = false;
00166 break;
00167 }
00168 }
00169 if(insert) {
00170 std::vector<size_t> subVariableIndices(factor.numberOfVariables());
00171 for(size_t j=0; j<factor.numberOfVariables(); ++j) {
00172 const size_t variableId = factor.variableIndex(j);
00173 subVariableIndices[j] = variableId;
00174 }
00175 decomposition.addSubFactor(subModelId,(*it),subVariableIndices);
00176
00177 if(currentList == &whiteList) {
00178 grayList.push_back(*it);
00179 it = currentList->erase(it);
00180 }
00181 else {
00182 ++it;
00183 }
00184 for(size_t j=1; j<factor.numberOfVariables(); ++j) {
00185 partition.merge(factor.variableIndex(j-1), factor.variableIndex(j));
00186 }
00187 }
00188 else {
00189 ++it;
00190 }
00191 }
00192 }
00193 blackList.insert(blackList.end(), grayList.begin(), grayList.end());
00194 grayList.clear();
00195 }
00196 return decomposition;
00197 }
00198
00199 template <class GM>
00200 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00201 decomposeIntoKFans
00202 (
00203 const GraphicalModelType& gm,
00204 const size_t k
00205 ) const
00206 {
00207 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00208
00209 const size_t numberOfVariables = gm.numberOfVariables();
00210 const size_t numberOfSubproblems = (size_t)(ceil((double)(numberOfVariables)/(double)(k)));
00211 std::vector<std::set<size_t> > innerFanVariables(numberOfSubproblems);
00212 size_t counter = 0;
00213 for(size_t subModelId=0; subModelId<numberOfSubproblems; ++subModelId) {
00214 for(size_t i=0; i<k; ++i) {
00215 innerFanVariables[subModelId].insert(counter);
00216 counter = (counter+1) % numberOfVariables;
00217 }
00218 }
00219 return decomposeIntoKFans(gm, innerFanVariables);
00220 }
00221
00222 template <class GM>
00223 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00224 decomposeIntoKFans
00225 (
00226 const GraphicalModelType& gm,
00227 const std::vector<std::set<size_t> >& innerFanVariables
00228 ) const
00229 {
00230 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00231
00232
00233 const size_t numberOfSubproblems = innerFanVariables.size();
00234
00235 for(size_t subModelId=0;subModelId<numberOfSubproblems;++subModelId) {
00236 decomposition.addSubModel();
00237 for(size_t variableId=0; variableId<gm.numberOfVariables();++variableId) {
00238 decomposition.addSubVariable(subModelId,variableId);
00239 }
00240
00241
00242 for(size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
00243 if(gm[factorId].numberOfVariables()==0) {
00244 std::vector<size_t> subVariableIndices(0);
00245 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00246 }
00247 else if(gm[factorId].numberOfVariables()==1) {
00248 std::vector<size_t> subVariableIndices(1,gm[factorId].variableIndex(0));
00249 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00250 }
00251 else if(gm[factorId].numberOfVariables()==2) {
00252 if( (innerFanVariables[subModelId].count(gm[factorId].variableIndex(0)) > 0 ) ||
00253 (innerFanVariables[subModelId].count(gm[factorId].variableIndex(1)) > 0 )) {
00254 std::vector<size_t> subVariableIndices(2);
00255 subVariableIndices[0] = gm[factorId].variableIndex(0);
00256 subVariableIndices[1] = gm[factorId].variableIndex(1);
00257 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00258 }
00259 }
00260 else{
00261 throw RuntimeError("The k-fan decomposition currently supports only models of order <= 2.");
00262 }
00263 }
00264 }
00265 return decomposition;
00266 }
00267
00268 template <class GM>
00269 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00270 decomposeIntoOpenBlocks
00271 (
00272 const GraphicalModelType& gm,
00273 const std::vector<std::set<size_t> >& innerVariables
00274 ) const
00275 {
00276 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00277
00278 const size_t numberOfVariables = gm.numberOfVariables();
00279 const size_t numberOfSubproblems = innerVariables.size();
00280 std::vector<size_t> subVariableMap(numberOfVariables);
00281
00282 for(size_t subModelId=0;subModelId<numberOfSubproblems;++subModelId) {
00283 decomposition.addSubModel();
00284 for(typename std::vector<size_t>::iterator it = subVariableMap.begin(); it !=subVariableMap.end(); ++it)
00285 *it = std::numeric_limits<std::size_t>::max();
00286 for(typename std::set<size_t>::const_iterator it=innerVariables[subModelId].begin();it!=innerVariables[subModelId].end(); ++it)
00287 subVariableMap[*it]=decomposition.addSubVariable(subModelId,*it);
00288
00289
00290 for(size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
00291 if(gm[factorId].numberOfVariables()==0) {
00292 std::vector<size_t> subVariableIndices(0);
00293 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00294 }
00295 else{
00296 bool test = true;
00297 for(size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
00298 test = test && (subVariableMap[gm[factorId].variableIndex(i)] != std::numeric_limits<std::size_t>::max());
00299 }
00300 if(test) {
00301 std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables());
00302 for(size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
00303 subVariableIndices[i] = subVariableMap[gm[factorId].variableIndex(i)];
00304 }
00305 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00306 }
00307 }
00308 }
00309 }
00310 return decomposition;
00311 }
00312
00313 template <class GM>
00314 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00315 decomposeIntoClosedBlocks
00316 (
00317 const GraphicalModelType& gm,
00318 const size_t numBlocks
00319 ) const
00320 {
00321 std::vector<std::set<size_t> > innerVariables(numBlocks);
00322 double fractalBlocksize = (1.0*gm.numberOfVariables())/numBlocks;
00323 size_t var = 0;
00324 for(size_t i=0; i<numBlocks;++i) {
00325 while(var < fractalBlocksize*(i+1)+0.0000001 && var < gm.numberOfVariables()) {
00326 innerVariables[i].insert(var++);
00327 }
00328 if( var != gm.numberOfVariables()) {
00329 --var;
00330 }
00331 }
00332 return decomposeIntoClosedBlocks(gm,innerVariables);
00333 }
00334
00335 template <class GM>
00336 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
00337 decomposeIntoClosedBlocks
00338 (
00339 const GraphicalModelType& gm,
00340 const std::vector<std::set<size_t> >& innerVariables
00341 ) const
00342 {
00343 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
00344
00345 const size_t numberOfVariables = gm.numberOfVariables();
00346 const size_t numberOfSubproblems = innerVariables.size();
00347 std::vector<size_t> subVariableMap(numberOfVariables);
00348
00349 for(size_t subModelId=0;subModelId<numberOfSubproblems;++subModelId) {
00350 decomposition.addSubModel();
00351 for(typename std::vector<size_t>::iterator it = subVariableMap.begin(); it !=subVariableMap.end(); ++it)
00352 *it = std::numeric_limits<std::size_t>::max();
00353 for(typename std::set<size_t>::const_iterator it=innerVariables[subModelId].begin();it!=innerVariables[subModelId].end(); ++it)
00354 subVariableMap[*it]=decomposition.addSubVariable(subModelId,*it);
00355
00356
00357 for(size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
00358 if(gm[factorId].numberOfVariables()==0) {
00359 std::vector<size_t> subVariableIndices(0);
00360 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00361 }
00362 else{
00363 bool test = false;
00364 for(size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
00365 test = test || (innerVariables[subModelId].count(gm[factorId].variableIndex(i))>0);
00366 }
00367 if(test) {
00368 std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables());
00369 for(size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
00370 const size_t varId = gm[factorId].variableIndex(i);
00371 if(subVariableMap[varId] == std::numeric_limits<std::size_t>::max()) {
00372 subVariableMap[varId] = decomposition.addSubVariable(subModelId,varId);
00373 }
00374 subVariableIndices[i] = subVariableMap[gm[factorId].variableIndex(i)];
00375 }
00376 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
00377 }
00378 }
00379 }
00380 }
00381 decomposition.reorder();
00382 return decomposition;
00383 }
00384
00386
00387 }
00388
00389 #endif // #ifndef OPENGM_GRAPHICALMODELDECOMPOSER_HXX