2 #ifndef OPENGM_GRAPHICALMODELDECOMPOSER_HXX
3 #define OPENGM_GRAPHICALMODELDECOMPOSER_HXX
22 class GraphicalModelDecomposer
25 typedef GM GraphicalModelType;
26 typedef GraphicalModelDecomposition DecompositionType;
27 typedef typename GraphicalModelType::FactorType FactorType;
28 typedef typename GraphicalModelType::FunctionIdentifier FunctionIdentifierType;
29 typedef typename DecompositionType::SubFactor SubFactorType;
30 typedef typename DecompositionType::SubVariable SubVariableType;
31 typedef typename DecompositionType::SubFactorListType SubFactorListType;
32 typedef typename DecompositionType::SubVariableListType SubVariableListType;
34 typedef typename GraphicalModelType::ValueType ValueType;
35 typedef typename GraphicalModelType::OperatorType OperatorType;
40 GraphicalModelDecomposer();
43 DecompositionType decomposeManual(
const GraphicalModelType&,
const std::vector<std::vector<size_t> >& subModelFactors)
const;
44 DecompositionType decomposeIntoTree(
const GraphicalModelType&)
const;
45 DecompositionType decomposeIntoSpanningTrees(
const GraphicalModelType&)
const;
46 DecompositionType decomposeIntoKFans(
const GraphicalModelType&,
const std::vector<std::set<size_t> >&)
const;
47 DecompositionType decomposeIntoKFans(
const GraphicalModelType&,
const size_t k)
const;
48 DecompositionType decomposeIntoClosedBlocks(
const GraphicalModelType&,
const std::vector<std::set<size_t> >&)
const;
49 DecompositionType decomposeIntoOpenBlocks(
const GraphicalModelType&,
const std::vector<std::set<size_t> >&)
const;
50 DecompositionType decomposeIntoClosedBlocks(
const GraphicalModelType&,
const size_t)
const;
54 inline GraphicalModelDecomposer<GM>::
55 GraphicalModelDecomposer()
59 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
62 const GraphicalModelType& gm,
63 const std::vector<std::vector<size_t> >& subModelFactors
66 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
67 for(
size_t subModel=0; subModel<subModelFactors.size(); ++subModel) {
68 decomposition.addSubModel();
70 for(
size_t subModel=0; subModel<subModelFactors.size(); ++subModel) {
71 std::vector<size_t> subVariableIds(gm.numberOfVariables(),gm.numberOfVariables());
73 for(
size_t nn=0; nn<subModelFactors[subModel].size(); ++nn) {
74 size_t factorId = subModelFactors[subModel][nn];
75 std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables());
76 for(
size_t j=0; j<gm[factorId].numberOfVariables(); ++j) {
77 const size_t variableIndex = gm[factorId].variableIndex(j);
78 if(subVariableIds[variableIndex] == gm.numberOfVariables()) {
79 subVariableIds[variableIndex] = decomposition.addSubVariable(subModel,variableIndex);
81 subVariableIndices[j] = subVariableIds[variableIndex];
83 decomposition.addSubFactor( subModel, factorId, subVariableIndices );
86 decomposition.reorder();
91 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
94 const GraphicalModelType& gm
97 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
99 decomposition.addSubModel();
100 Partition<size_t> partition(gm.numberOfVariables());
101 for(
size_t variableId=0; variableId<gm.numberOfVariables();++variableId) {
102 decomposition.addSubVariable(0,variableId);
104 for(
size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
105 std::map<size_t, size_t> counters;
106 std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables());
107 for(
size_t j=0; j<gm[factorId].numberOfVariables(); ++j) {
108 const size_t variableIndex = gm[factorId].variableIndex(j);
109 if( ++counters[partition.find(variableIndex)] > 1) {
110 subVariableIndices[j] = decomposition.addSubVariable(0,variableIndex);
113 subVariableIndices[j] = variableIndex;
116 decomposition.addSubFactor(0,factorId,subVariableIndices);
117 for(
size_t j=1; j<gm[factorId].numberOfVariables(); ++j) {
118 partition.merge(gm[factorId].variableIndex(j-1), gm[factorId].variableIndex(j));
121 decomposition.reorder();
122 return decomposition;
126 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
127 decomposeIntoSpanningTrees
129 const GraphicalModelType& gm
132 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
134 std::list<size_t> blackList;
135 std::list<size_t> grayList;
136 std::list<size_t> whiteList;
137 for(
size_t j=0; j<gm.numberOfFactors(); ++j) {
138 whiteList.push_back(j);
141 while(!whiteList.empty()) {
142 size_t subModelId = decomposition.addSubModel();
143 for(
size_t variableId=0; variableId<gm.numberOfVariables();++variableId) {
144 decomposition.addSubVariable(subModelId,variableId);
147 Partition<size_t> partition(gm.numberOfVariables());
148 std::list<size_t>* currentList;
150 for(
size_t listSwap=0; listSwap<2; ++listSwap) {
152 currentList = &whiteList;
155 currentList = &blackList;
158 std::list<size_t>::iterator it = currentList->begin();
159 while(it != currentList->end()) {
162 const FactorType& factor = gm[*it];
163 std::map<size_t, size_t> counters;
164 for(
size_t j=0; j<factor.numberOfVariables(); ++j) {
165 if( ++counters[partition.find(factor.variableIndex(j))] > 1) {
172 std::vector<size_t> subVariableIndices(factor.numberOfVariables());
173 for(
size_t j=0; j<factor.numberOfVariables(); ++j) {
174 const size_t variableId = factor.variableIndex(j);
175 subVariableIndices[j] = variableId;
177 decomposition.addSubFactor(subModelId,(*it),subVariableIndices);
179 if(currentList == &whiteList) {
180 grayList.push_back(*it);
181 it = currentList->erase(it);
186 for(
size_t j=1; j<factor.numberOfVariables(); ++j) {
187 partition.merge(factor.variableIndex(j-1), factor.variableIndex(j));
195 blackList.insert(blackList.end(), grayList.begin(), grayList.end());
198 return decomposition;
202 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
205 const GraphicalModelType& gm,
209 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
211 const size_t numberOfVariables = gm.numberOfVariables();
212 const size_t numberOfSubproblems = (
size_t)(ceil((
double)(numberOfVariables)/(
double)(k)));
213 std::vector<std::set<size_t> > innerFanVariables(numberOfSubproblems);
215 for(
size_t subModelId=0; subModelId<numberOfSubproblems; ++subModelId) {
216 for(
size_t i=0; i<k; ++i) {
217 innerFanVariables[subModelId].insert(counter);
218 counter = (counter+1) % numberOfVariables;
221 return decomposeIntoKFans(gm, innerFanVariables);
225 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
228 const GraphicalModelType& gm,
229 const std::vector<std::set<size_t> >& innerFanVariables
232 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
235 const size_t numberOfSubproblems = innerFanVariables.size();
237 for(
size_t subModelId=0;subModelId<numberOfSubproblems;++subModelId) {
238 decomposition.addSubModel();
240 std::vector<bool> includedVars(gm.numberOfVariables(),
false);
241 std::vector<size_t> subVars(gm.numberOfVariables());
242 for(
typename std::set<size_t>::iterator vit=innerFanVariables[subModelId].begin(); vit!=innerFanVariables[subModelId].end();++vit){
243 const size_t var = *vit;
244 includedVars[var] =
true;
245 for(
typename GM::ConstFactorIterator fit=gm.factorsOfVariableBegin(var); fit!=gm.factorsOfVariableEnd(var); ++fit){
246 for(
size_t n=0; n<gm[*fit].numberOfVariables();++n){
247 includedVars[gm[*fit].variableIndex(n)] =
true;
251 for(
size_t variableId=0; variableId<gm.numberOfVariables();++variableId) {
252 if(includedVars[variableId]){
253 subVars[variableId] = decomposition.addSubVariable(subModelId,variableId);
258 for(
size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
259 if(gm[factorId].numberOfVariables()==0) {
261 std::vector<size_t> subVariableIndices(0);
262 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
265 else if(gm[factorId].numberOfVariables()==1) {
266 if(includedVars[gm[factorId].variableIndex(0)]){
267 std::vector<size_t> subVariableIndices(1, subVars[gm[factorId].variableIndex(0)]);
268 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
271 else if(gm[factorId].numberOfVariables()==2) {
272 if(includedVars[gm[factorId].variableIndex(0)] && includedVars[gm[factorId].variableIndex(1)]){
273 if( (innerFanVariables[subModelId].count(gm[factorId].variableIndex(0)) > 0 ) ||
274 (innerFanVariables[subModelId].count(gm[factorId].variableIndex(1)) > 0 )) {
275 std::vector<size_t> subVariableIndices(2);
276 subVariableIndices[0] = subVars[gm[factorId].variableIndex(0)];
277 subVariableIndices[1] = subVars[gm[factorId].variableIndex(1)];
278 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
283 throw RuntimeError(
"The k-fan decomposition currently supports only models of order <= 2.");
287 return decomposition;
291 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
292 decomposeIntoOpenBlocks
294 const GraphicalModelType& gm,
295 const std::vector<std::set<size_t> >& innerVariables
298 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
300 const size_t numberOfVariables = gm.numberOfVariables();
301 const size_t numberOfSubproblems = innerVariables.size();
302 std::vector<size_t> subVariableMap(numberOfVariables);
304 for(
size_t subModelId=0;subModelId<numberOfSubproblems;++subModelId) {
305 decomposition.addSubModel();
306 for(
typename std::vector<size_t>::iterator it = subVariableMap.begin(); it !=subVariableMap.end(); ++it)
307 *it = std::numeric_limits<std::size_t>::max();
308 for(
typename std::set<size_t>::const_iterator it=innerVariables[subModelId].begin();it!=innerVariables[subModelId].end(); ++it)
309 subVariableMap[*it]=decomposition.addSubVariable(subModelId,*it);
312 for(
size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
313 if(gm[factorId].numberOfVariables()==0) {
314 std::vector<size_t> subVariableIndices(0);
315 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
319 for(
size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
320 test = test && (subVariableMap[gm[factorId].variableIndex(i)] != std::numeric_limits<std::size_t>::max());
323 std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables());
324 for(
size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
325 subVariableIndices[i] = subVariableMap[gm[factorId].variableIndex(i)];
327 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
332 return decomposition;
336 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
337 decomposeIntoClosedBlocks
339 const GraphicalModelType& gm,
340 const size_t numBlocks
343 std::vector<std::set<size_t> > innerVariables(numBlocks);
344 double fractalBlocksize = (1.0*gm.numberOfVariables())/numBlocks;
346 for(
size_t i=0; i<numBlocks;++i) {
347 while(var < fractalBlocksize*(i+1)+0.0000001 && var < gm.numberOfVariables()) {
348 innerVariables[i].insert(var++);
350 if( var != gm.numberOfVariables()) {
354 return decomposeIntoClosedBlocks(gm,innerVariables);
358 inline typename GraphicalModelDecomposer<GM>::DecompositionType GraphicalModelDecomposer<GM>::
359 decomposeIntoClosedBlocks
361 const GraphicalModelType& gm,
362 const std::vector<std::set<size_t> >& innerVariables
365 DecompositionType decomposition = GraphicalModelDecomposition(gm.numberOfVariables(),gm.numberOfFactors(),0);
367 const size_t numberOfVariables = gm.numberOfVariables();
368 const size_t numberOfSubproblems = innerVariables.size();
369 std::vector<size_t> subVariableMap(numberOfVariables);
371 for(
size_t subModelId=0;subModelId<numberOfSubproblems;++subModelId) {
372 decomposition.addSubModel();
373 for(
typename std::vector<size_t>::iterator it = subVariableMap.begin(); it !=subVariableMap.end(); ++it)
374 *it = std::numeric_limits<std::size_t>::max();
375 for(
typename std::set<size_t>::const_iterator it=innerVariables[subModelId].begin();it!=innerVariables[subModelId].end(); ++it)
376 subVariableMap[*it]=decomposition.addSubVariable(subModelId,*it);
379 for(
size_t factorId=0; factorId<gm.numberOfFactors(); ++factorId) {
380 if(gm[factorId].numberOfVariables()==0) {
381 std::vector<size_t> subVariableIndices(0);
382 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
386 for(
size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
387 test = test || (innerVariables[subModelId].count(gm[factorId].variableIndex(i))>0);
390 std::vector<size_t> subVariableIndices(gm[factorId].numberOfVariables());
391 for(
size_t i=0; i<gm[factorId].numberOfVariables(); ++i) {
392 const size_t varId = gm[factorId].variableIndex(i);
393 if(subVariableMap[varId] == std::numeric_limits<std::size_t>::max()) {
394 subVariableMap[varId] = decomposition.addSubVariable(subModelId,varId);
396 subVariableIndices[i] = subVariableMap[gm[factorId].variableIndex(i)];
398 decomposition.addSubFactor(subModelId,factorId,subVariableIndices);
403 decomposition.reorder();
404 return decomposition;
411 #endif // #ifndef OPENGM_GRAPHICALMODELDECOMPOSER_HXX