2 #ifndef OPENGM_MOVEMAKER_HXX
3 #define OPENGM_MOVEMAKER_HXX
31 typedef opengm::VectorViewSpace<IndexType, LabelType> SubGmSpace;
36 template<
class StateIterator>
37 Movemaker(
const GraphicalModelType&, StateIterator);
38 ValueType
value()
const;
39 template<
class IndexIterator,
class StateIterator>
40 ValueType
valueAfterMove(IndexIterator, IndexIterator, StateIterator);
45 template<
class StateIterator>
47 template<
class IndexIterator,
class StateIterator>
48 ValueType
move(IndexIterator, IndexIterator, StateIterator);
49 template<
class ACCUMULATOR,
class IndexIterator>
51 template<
class ACCUMULATOR,
class IndexIterator>
55 template<
class INFERENCE_TYPE,
class INFERENCE_PARAMETER,
class INDEX_ITERATOR,
class STATE_ITERATOR>
59 typedef PositionAndLabel<IndexType, LabelType > PositionAndLabelType;
60 typedef opengm::BufferVector<PositionAndLabelType> PositionAndLabelVector;
63 template<
class INDEX_ITERATOR>
64 void addFactorsToSubGm(INDEX_ITERATOR, INDEX_ITERATOR, SubGmType&)
const;
66 void addSingleSide(
const IndexType,
const IndexType, SubGmType &, std::set<IndexType>&)
const;
67 void addHigherOrderBorderFactor(
const IndexType,
const opengm::BufferVector<IndexType>&,
const PositionAndLabelVector &, SubGmType &, std::set<IndexType> &)
const;
68 void addHigherOrderInsideFactor(
const IndexType,
const opengm::BufferVector<IndexType>&, SubGmType &, std::set<IndexType> &)
const;
69 template<
class FactorIndexIterator>
70 ValueType evaluateFactors(FactorIndexIterator, FactorIndexIterator,
const std::vector<LabelType>&)
const;
72 const GraphicalModelType& gm_;
73 std::vector<std::set<size_t> > factorsOfVariable_;
74 std::vector<LabelType> state_;
75 std::vector<LabelType> stateBuffer_;
100 template<
class INFERENCE_TYPE,
class INFERENCE_PARAMETER,
class INDEX_ITERATOR,
class STATE_ITERATOR>
104 const INFERENCE_PARAMETER& inferenceParam,
105 INDEX_ITERATOR variablesBegin,
106 INDEX_ITERATOR variablesEnd,
107 std::vector<LabelType>& states
109 OPENGM_ASSERT(opengm::isSorted(variablesBegin, variablesEnd));
110 const size_t numberOfVariables = std::distance(variablesBegin, variablesEnd);
111 std::vector<LabelType> spaceVector(numberOfVariables);
112 for (
size_t v = 0; v < numberOfVariables; ++v)
113 spaceVector[v] = gm_.numberOfLabels(variablesBegin[v]);
114 SubGmSpace subGmSpace(spaceVector);
115 SubGmType subGm(subGmSpace);
116 this->addFactorsToSubGm(variablesBegin, variablesEnd, subGm);
117 INFERENCE_TYPE subGmInference(subGm, inferenceParam);
118 subGmInference.infer();
119 subGmInference.arg(states);
130 const size_t var1Index[] = {subGmVarIndex};
131 ViewFunction<GM>
function = (gm_[gmFactorIndex]);
132 typename GM::FunctionIdentifier fid = subGm.addFunction(
function);
133 subGm.addFactor(fid, var1Index, var1Index + 1);
134 addedFactors.insert(gmFactorIndex);
138 inline void Movemaker<GM>::addHigherOrderInsideFactor
140 const typename Movemaker<GM>::IndexType gmFactorIndex,
141 const opengm::BufferVector<
typename Movemaker<GM>::IndexType> & subGmFactorVi,
142 typename Movemaker<GM>::SubGmType & subGm,
143 std::set<
typename Movemaker<GM>::IndexType> & addedFactors
145 ViewFunction<GM>
function(gm_[gmFactorIndex]);
146 typename GM::FunctionIdentifier fid = subGm.addFunction(
function);
147 subGm.addFactor(fid, subGmFactorVi.begin(), subGmFactorVi.end());
148 addedFactors.insert(gmFactorIndex);
152 inline void Movemaker<GM>::addHigherOrderBorderFactor
154 const typename Movemaker<GM>::IndexType gmFactorIndex,
155 const opengm::BufferVector<
typename Movemaker<GM>::IndexType> & subGmFactorVi,
156 const typename Movemaker<GM>::PositionAndLabelVector & factorFixVi,
157 typename Movemaker<GM>::SubGmType & subGm,
158 std::set<
typename Movemaker<GM>::IndexType> & addedFactors
160 ViewFixVariablesFunction<GM>
function(gm_[gmFactorIndex], factorFixVi);
161 typename GM::FunctionIdentifier fid = subGm.addFunction(
function);
162 subGm.addFactor(fid, subGmFactorVi.begin(), subGmFactorVi.end());
163 addedFactors.insert(gmFactorIndex);
167 template<
class INDEX_ITERATOR >
168 inline void Movemaker<GM>::addFactorsToSubGm
170 INDEX_ITERATOR variablesBegin,
171 INDEX_ITERATOR variablesEnd,
172 typename Movemaker<GM>::SubGmType & subGm
174 std::set<IndexType> addedFactors;
175 opengm::BufferVector<IndexType> subGmFactorVi;
176 opengm::BufferVector<opengm::PositionAndLabel<IndexType, LabelType > >factorFixVi;
177 subGm.reserveFactors(subGm.numberOfVariables()*7);
178 for (IndexType subGmVi = 0; subGmVi < subGm.numberOfVariables(); ++subGmVi) {
179 for (
size_t f = 0; f < gm_.numberOfFactors(variablesBegin[subGmVi]); ++f) {
180 const size_t factorIndex = gm_.factorOfVariable(variablesBegin[subGmVi], f);
182 if (addedFactors.find(factorIndex) == addedFactors.end()) {
183 if (gm_[factorIndex].numberOfVariables() == 0) {
184 }
else if (gm_[factorIndex].numberOfVariables() == 1)
185 this->addSingleSide(factorIndex, subGmVi, subGm, addedFactors);
188 subGmFactorVi.clear();
190 for (IndexType vv = 0; vv < gm_[factorIndex].numberOfVariables(); ++vv) {
191 bool foundVarIndex =
false;
192 IndexType varIndexSubGm = 0;
193 foundVarIndex = findInSortedSequence(variablesBegin, subGm.numberOfVariables(), gm_[factorIndex].variableIndex(vv), varIndexSubGm);
194 if (foundVarIndex ==
false)
195 factorFixVi.push_back(opengm::PositionAndLabel<IndexType, LabelType > (vv, this->state(gm_[factorIndex].variableIndex(vv))));
197 subGmFactorVi.push_back(varIndexSubGm);
199 if (factorFixVi.size() == 0)
200 this->addHigherOrderInsideFactor(factorIndex, subGmFactorVi, subGm, addedFactors);
202 this->addHigherOrderBorderFactor(factorIndex, subGmFactorVi, factorFixVi, subGm, addedFactors);
215 factorsOfVariable_(gm.numberOfVariables()),
216 state_(gm.numberOfVariables()),
217 stateBuffer_(gm.numberOfVariables()),
218 energy_(gm.evaluate(state_.begin()))
220 for (
size_t f = 0; f < gm.numberOfFactors(); ++f) {
221 for (
size_t v = 0; v < gm[f].numberOfVariables(); ++v) {
222 factorsOfVariable_[gm[f].variableIndex(v)].insert(f);
228 template<
class StateIterator>
235 factorsOfVariable_(gm.numberOfVariables()),
236 state_(gm.numberOfVariables()),
237 stateBuffer_(gm.numberOfVariables()),
238 energy_(gm.evaluate(it))
240 for (
size_t j = 0; j < gm.numberOfVariables(); ++j, ++it) {
242 stateBuffer_[j] = *it;
244 for (
size_t f = 0; f < gm.numberOfFactors(); ++f) {
245 for (
size_t v = 0; v < gm[f].numberOfVariables(); ++v) {
246 factorsOfVariable_[gm[f].variableIndex(v)].insert(f);
252 template<
class StateIterator>
257 energy_ = gm_.evaluate(it);
258 for (
size_t j = 0; j < gm_.numberOfVariables(); ++j, ++it) {
260 stateBuffer_[j] = *it;
267 for (
size_t j = 0; j < gm_.numberOfVariables(); ++j) {
271 energy_ = gm_.evaluate(state_.begin());
281 template<
class IndexIterator,
class StateIterator>
287 StateIterator destinationState
289 ValueType destinationValue;
290 if(meta::Compare<OperatorType, opengm::Multiplier>::value){
294 for (IndexIterator it = begin; it != end; ++it, ++destinationState) {
295 stateBuffer_[*it] = *destinationState;
298 destinationValue = gm_.evaluate(stateBuffer_);
300 for (IndexIterator it = begin; it != end; ++it) {
301 stateBuffer_[*it] = state_[*it];
307 std::set<size_t> factorsToRecompute;
308 for (IndexIterator it = begin; it != end; ++it, ++destinationState) {
310 if (state_[*it] != *destinationState) {
312 stateBuffer_[*it] = *destinationState;
313 std::set<size_t> tmpSet;
314 std::set_union(factorsToRecompute.begin(), factorsToRecompute.end(),
315 factorsOfVariable_[*it].begin(), factorsOfVariable_[*it].end(),
316 std::inserter(tmpSet, tmpSet.begin()));
317 factorsToRecompute.swap(tmpSet);
321 destinationValue = energy_;
322 for (std::set<size_t>::const_iterator it = factorsToRecompute.begin(); it != factorsToRecompute.end(); ++it) {
325 std::vector<size_t> currentFactorState(gm_[*it].numberOfVariables());
326 std::vector<size_t> destinationFactorState(gm_[*it].numberOfVariables());
327 for (
size_t j = 0; j < gm_[*it].numberOfVariables(); ++j) {
328 currentFactorState[j] = state_[gm_[*it].variableIndex(j)];
329 OPENGM_ASSERT(currentFactorState[j] < gm_[*it].numberOfLabels(j));
330 destinationFactorState[j] = stateBuffer_[gm_[*it].variableIndex(j)];
331 OPENGM_ASSERT(destinationFactorState[j] < gm_[*it].numberOfLabels(j));
333 OperatorType::op(destinationValue, gm_[*it](destinationFactorState.begin()), destinationValue);
334 OperatorType::iop(destinationValue, gm_[*it](currentFactorState.begin()), destinationValue);
337 for (IndexIterator it = begin; it != end; ++it) {
338 stateBuffer_[*it] = state_[*it];
341 return destinationValue;
345 template<
class IndexIterator,
class StateIterator>
353 energy_ = valueAfterMove(begin, end, sit);
354 while (begin != end) {
355 state_[*begin] = *sit;
356 stateBuffer_[*begin] = *sit;
369 template<
class ACCUMULATOR,
class IndexIterator>
373 IndexIterator variableIndices,
374 IndexIterator variableIndicesEnd
377 std::set<size_t> factorsToRecompute;
378 for (IndexIterator it = variableIndices; it != variableIndicesEnd; ++it) {
379 std::set<size_t> tmpSet;
380 std::set_union(factorsToRecompute.begin(), factorsToRecompute.end(),
381 factorsOfVariable_[*it].begin(), factorsOfVariable_[*it].end(),
382 std::inserter(tmpSet, tmpSet.begin()));
383 factorsToRecompute.swap(tmpSet);
387 size_t numberOfVariables = std::distance(variableIndices, variableIndicesEnd);
388 ValueType initialEnergy = evaluateFactors(
389 factorsToRecompute.begin(),
390 factorsToRecompute.end(),
392 ValueType bestEnergy = initialEnergy;
393 std::vector<size_t> bestState(numberOfVariables);
394 for (
size_t j=0; j<numberOfVariables; ++j) {
395 const size_t vi = variableIndices[j];
396 stateBuffer_[vi] = 0;
400 ValueType energy = evaluateFactors(
401 factorsToRecompute.begin(),
402 factorsToRecompute.end(),
404 if(ACCUMULATOR::bop(energy, bestEnergy)) {
407 for (
size_t j = 0; j < numberOfVariables; ++j) {
408 bestState[j] = stateBuffer_[variableIndices[j]];
412 for (
size_t j = 0; j < numberOfVariables; ++j) {
413 const size_t vi = variableIndices[j];
414 if (stateBuffer_[vi] < gm_.numberOfLabels(vi) - 1) {
418 if (j < numberOfVariables - 1) {
419 stateBuffer_[vi] = 0;
429 if (ACCUMULATOR::bop(bestEnergy, initialEnergy)) {
431 for (
size_t j = 0; j < numberOfVariables; ++j) {
432 const size_t vi = variableIndices[j];
433 state_[vi] = bestState[j];
434 stateBuffer_[vi] = bestState[j];
438 meta::Compare<ACCUMULATOR, opengm::Maximizer>::value,
439 meta::Compare<OperatorType, opengm::Multiplier>::value
440 >::value && energy_ == static_cast<ValueType> (0)) {
442 energy_ = gm_.evaluate(state_.begin());
445 OperatorType::iop(initialEnergy, energy_);
446 OperatorType::op(bestEnergy, energy_);
450 for (
size_t j = 0; j < numberOfVariables; ++j) {
451 const size_t vi = variableIndices[j];
452 stateBuffer_[vi] = state_[vi];
462 template<
class ACCUMULATOR,
class IndexIterator>
466 IndexIterator variableIndices,
467 IndexIterator variableIndicesEnd
470 std::set<size_t> factorsToRecompute;
471 for (IndexIterator it = variableIndices; it != variableIndicesEnd; ++it) {
472 std::set<size_t> tmpSet;
473 std::set_union(factorsToRecompute.begin(), factorsToRecompute.end(),
474 factorsOfVariable_[*it].begin(), factorsOfVariable_[*it].end(),
475 std::inserter(tmpSet, tmpSet.begin()));
476 factorsToRecompute.swap(tmpSet);
480 size_t numberOfVariables = std::distance(variableIndices, variableIndicesEnd);
481 ValueType initialEnergy = evaluateFactors(
482 factorsToRecompute.begin(),
483 factorsToRecompute.end(),
485 ValueType bestEnergy = initialEnergy;
486 std::vector<size_t> bestState(numberOfVariables);
488 for(
size_t j=0; j<numberOfVariables; ++j) {
489 if(gm_.space().numberOfLabels(variableIndices[j]) == 1) {
491 for(
size_t k=0; k<j; ++k) {
492 stateBuffer_[k] = state_[k];
497 const size_t vi = variableIndices[j];
498 if(state_[vi] == 0) {
499 stateBuffer_[vi] = 1;
502 stateBuffer_[vi] = 0;
508 for(
size_t j=0; j<numberOfVariables; ++j) {
509 const size_t vi = variableIndices[j];
514 ValueType energy = evaluateFactors(
515 factorsToRecompute.begin(),
516 factorsToRecompute.end(),
518 if(ACCUMULATOR::bop(energy, bestEnergy)) {
521 for (
size_t j = 0; j < numberOfVariables; ++j) {
522 bestState[j] = stateBuffer_[variableIndices[j]];
526 for (
size_t j=0; j<numberOfVariables; ++j) {
527 const size_t vi = variableIndices[j];
528 if(stateBuffer_[vi] < gm_.numberOfLabels(vi) - 1) {
529 if(stateBuffer_[vi] + 1 != state_[vi]) {
533 else if(stateBuffer_[vi] + 1 < gm_.numberOfLabels(vi) - 1) {
534 stateBuffer_[vi] += 2;
538 if (j < numberOfVariables - 1) {
539 if(state_[vi] == 0) {
540 stateBuffer_[vi] = 1;
543 stateBuffer_[vi] = 0;
550 if (j < numberOfVariables - 1) {
551 if(state_[vi] == 0) {
552 stateBuffer_[vi] = 1;
555 stateBuffer_[vi] = 0;
566 if (ACCUMULATOR::bop(bestEnergy, initialEnergy)) {
568 for (
size_t j = 0; j < numberOfVariables; ++j) {
569 const size_t vi = variableIndices[j];
570 state_[vi] = bestState[j];
571 stateBuffer_[vi] = bestState[j];
575 meta::Compare<ACCUMULATOR, opengm::Maximizer>::value,
576 meta::Compare<OperatorType, opengm::Multiplier>::value
577 >::value && energy_ == static_cast<ValueType> (0)) {
578 energy_ = gm_.evaluate(state_.begin());
581 OperatorType::iop(initialEnergy, energy_);
582 OperatorType::op(bestEnergy, energy_);
586 for (
size_t j = 0; j < numberOfVariables; ++j) {
587 const size_t vi = variableIndices[j];
588 stateBuffer_[vi] = state_[vi];
599 const size_t variableIndex
602 return state_[variableIndex];
608 return state_.begin();
618 template<
class FactorIndexIterator>
622 FactorIndexIterator begin,
623 FactorIndexIterator end,
624 const std::vector<LabelType>& state
626 ValueType value = OperatorType::template neutral<ValueType>();
627 for(; begin != end; ++begin) {
628 std::vector<size_t> currentFactorState(gm_[*begin].numberOfVariables());
629 for (
size_t j=0; j<gm_[*begin].numberOfVariables(); ++j) {
630 currentFactorState[j] = state[gm_[*begin].variableIndex(j)];
632 OperatorType::op(value, gm_[*begin](currentFactorState.begin()), value);
639 #endif // #ifndef OPENGM_MOVEMAKER_HXX
const LabelType & state(const size_t) const
void proposeMoveAccordingToInference(const INFERENCE_PARAMETER &, INDEX_ITERATOR, INDEX_ITERATOR, std::vector< LabelType > &) const
ValueType valueAfterMove(IndexIterator, IndexIterator, StateIterator)
std::vector< LabelType >::const_iterator LabelIterator
Movemaker(const GraphicalModelType &)
#define OPENGM_ASSERT(expression)
LabelIterator stateEnd() const
ValueType moveOptimallyWithAllLabelsChanging(IndexIterator, IndexIterator)
A fremework for move making algorithms.
ValueType moveOptimally(IndexIterator, IndexIterator)
for a subset of variables, move to a labeling that is optimal w.r.t. ACCUMULATOR
void initialize(StateIterator)
LabelIterator stateBegin() const
Funcion that refers to a factor of another GraphicalModel in which some variables are fixed...
ValueType move(IndexIterator, IndexIterator, StateIterator)