2 #ifndef OPENGM_MOVEMAKER_HXX 3 #define OPENGM_MOVEMAKER_HXX 31 typedef opengm::VectorViewSpace<IndexType, LabelType> SubGmSpace;
44 template<
class StateIterator>
45 Movemaker(
const GraphicalModelType&, StateIterator);
46 ValueType
value()
const;
47 template<
class IndexIterator,
class StateIterator>
48 ValueType
valueAfterMove(IndexIterator, IndexIterator, StateIterator);
53 template<
class StateIterator>
55 template<
class IndexIterator,
class StateIterator>
56 ValueType
move(IndexIterator, IndexIterator, StateIterator);
57 template<
class ACCUMULATOR,
class IndexIterator>
59 template<
class ACCUMULATOR,
class IndexIterator>
63 template<
class INFERENCE_TYPE,
class INFERENCE_PARAMETER,
class INDEX_ITERATOR,
class STATE_ITERATOR>
67 typedef PositionAndLabel<IndexType, LabelType > PositionAndLabelType;
68 typedef opengm::BufferVector<PositionAndLabelType> PositionAndLabelVector;
71 template<
class INDEX_ITERATOR>
72 void addFactorsToSubGm(INDEX_ITERATOR, INDEX_ITERATOR, SubGmType&)
const;
74 void addSingleSide(
const IndexType,
const IndexType, SubGmType &, std::set<IndexType>&)
const;
75 void addHigherOrderBorderFactor(
const IndexType,
const opengm::BufferVector<IndexType>&,
const PositionAndLabelVector &, SubGmType &, std::set<IndexType> &)
const;
76 void addHigherOrderInsideFactor(
const IndexType,
const opengm::BufferVector<IndexType>&, SubGmType &, std::set<IndexType> &)
const;
77 template<
class FactorIndexIterator>
78 ValueType evaluateFactors(FactorIndexIterator, FactorIndexIterator,
const std::vector<LabelType>&)
const;
80 const GraphicalModelType& gm_;
81 std::vector<std::set<size_t> > factorsOfVariable_;
82 std::vector<LabelType> state_;
83 std::vector<LabelType> stateBuffer_;
108 template<
class INFERENCE_TYPE,
class INFERENCE_PARAMETER,
class INDEX_ITERATOR,
class STATE_ITERATOR>
112 const INFERENCE_PARAMETER& inferenceParam,
113 INDEX_ITERATOR variablesBegin,
114 INDEX_ITERATOR variablesEnd,
115 std::vector<LabelType>& states
117 OPENGM_ASSERT(opengm::isSorted(variablesBegin, variablesEnd));
118 const size_t numberOfVariables = std::distance(variablesBegin, variablesEnd);
119 std::vector<LabelType> spaceVector(numberOfVariables);
120 for (
size_t v = 0; v < numberOfVariables; ++v)
121 spaceVector[v] = gm_.numberOfLabels(variablesBegin[v]);
122 SubGmSpace subGmSpace(spaceVector);
123 SubGmType subGm(subGmSpace);
124 this->addFactorsToSubGm(variablesBegin, variablesEnd, subGm);
125 INFERENCE_TYPE subGmInference(subGm, inferenceParam);
126 subGmInference.infer();
127 subGmInference.arg(states);
138 const size_t var1Index[] = {subGmVarIndex};
140 typename GM::FunctionIdentifier fid = subGm.addFunction(
function);
141 subGm.addFactor(fid, var1Index, var1Index + 1);
142 addedFactors.insert(gmFactorIndex);
154 typename GM::FunctionIdentifier fid = subGm.addFunction(
function);
155 subGm.addFactor(fid, subGmFactorVi.begin(), subGmFactorVi.end());
156 addedFactors.insert(gmFactorIndex);
164 const typename Movemaker<GM>::PositionAndLabelVector & factorFixVi,
169 typename GM::FunctionIdentifier fid = subGm.addFunction(
function);
170 subGm.addFactor(fid, subGmFactorVi.begin(), subGmFactorVi.end());
171 addedFactors.insert(gmFactorIndex);
175 template<
class INDEX_ITERATOR >
178 INDEX_ITERATOR variablesBegin,
179 INDEX_ITERATOR variablesEnd,
182 std::set<IndexType> addedFactors;
183 opengm::BufferVector<IndexType> subGmFactorVi;
184 opengm::BufferVector<opengm::PositionAndLabel<IndexType, LabelType > >factorFixVi;
185 subGm.reserveFactors(subGm.numberOfVariables()*7);
186 for (IndexType subGmVi = 0; subGmVi < subGm.numberOfVariables(); ++subGmVi) {
187 for (
size_t f = 0; f < gm_.numberOfFactors(variablesBegin[subGmVi]); ++f) {
188 const size_t factorIndex = gm_.factorOfVariable(variablesBegin[subGmVi], f);
190 if (addedFactors.find(factorIndex) == addedFactors.end()) {
191 if (gm_[factorIndex].numberOfVariables() == 0) {
192 }
else if (gm_[factorIndex].numberOfVariables() == 1)
193 this->addSingleSide(factorIndex, subGmVi, subGm, addedFactors);
196 subGmFactorVi.clear();
198 for (IndexType vv = 0; vv < gm_[factorIndex].numberOfVariables(); ++vv) {
199 bool foundVarIndex =
false;
200 IndexType varIndexSubGm = 0;
201 foundVarIndex = findInSortedSequence(variablesBegin, subGm.numberOfVariables(), gm_[factorIndex].variableIndex(vv), varIndexSubGm);
202 if (foundVarIndex ==
false)
203 factorFixVi.push_back(opengm::PositionAndLabel<IndexType, LabelType > (vv, this->
state(gm_[factorIndex].variableIndex(vv))));
205 subGmFactorVi.push_back(varIndexSubGm);
207 if (factorFixVi.size() == 0)
208 this->addHigherOrderInsideFactor(factorIndex, subGmFactorVi, subGm, addedFactors);
210 this->addHigherOrderBorderFactor(factorIndex, subGmFactorVi, factorFixVi, subGm, addedFactors);
223 factorsOfVariable_(gm.numberOfVariables()),
224 state_(gm.numberOfVariables()),
225 stateBuffer_(gm.numberOfVariables()),
226 energy_(gm.evaluate(state_.begin()))
228 for (
size_t f = 0; f < gm.numberOfFactors(); ++f) {
229 for (
size_t v = 0; v < gm[f].numberOfVariables(); ++v) {
230 factorsOfVariable_[gm[f].variableIndex(v)].insert(f);
236 template<
class StateIterator>
243 factorsOfVariable_(gm.numberOfVariables()),
244 state_(gm.numberOfVariables()),
245 stateBuffer_(gm.numberOfVariables()),
246 energy_(gm.evaluate(it))
248 for (
size_t j = 0; j < gm.numberOfVariables(); ++j, ++it) {
250 stateBuffer_[j] = *it;
252 for (
size_t f = 0; f < gm.numberOfFactors(); ++f) {
253 for (
size_t v = 0; v < gm[f].numberOfVariables(); ++v) {
254 factorsOfVariable_[gm[f].variableIndex(v)].insert(f);
260 template<
class StateIterator>
265 energy_ = gm_.evaluate(it);
266 for (
size_t j = 0; j < gm_.numberOfVariables(); ++j, ++it) {
268 stateBuffer_[j] = *it;
275 for (
size_t j = 0; j < gm_.numberOfVariables(); ++j) {
279 energy_ = gm_.evaluate(state_.begin());
289 template<
class IndexIterator,
class StateIterator>
295 StateIterator destinationState
297 ValueType destinationValue;
298 if(meta::Compare<OperatorType, opengm::Multiplier>::value){
302 for (IndexIterator it = begin; it != end; ++it, ++destinationState) {
303 stateBuffer_[*it] = *destinationState;
306 destinationValue = gm_.evaluate(stateBuffer_);
308 for (IndexIterator it = begin; it != end; ++it) {
309 stateBuffer_[*it] = state_[*it];
315 std::set<size_t> factorsToRecompute;
316 for (IndexIterator it = begin; it != end; ++it, ++destinationState) {
318 if (state_[*it] != *destinationState) {
320 stateBuffer_[*it] = *destinationState;
321 std::set<size_t> tmpSet;
322 std::set_union(factorsToRecompute.begin(), factorsToRecompute.end(),
323 factorsOfVariable_[*it].begin(), factorsOfVariable_[*it].end(),
324 std::inserter(tmpSet, tmpSet.begin()));
325 factorsToRecompute.swap(tmpSet);
329 destinationValue = energy_;
330 for (std::set<size_t>::const_iterator it = factorsToRecompute.begin(); it != factorsToRecompute.end(); ++it) {
333 std::vector<size_t> currentFactorState(gm_[*it].numberOfVariables());
334 std::vector<size_t> destinationFactorState(gm_[*it].numberOfVariables());
335 for (
size_t j = 0; j < gm_[*it].numberOfVariables(); ++j) {
336 currentFactorState[j] = state_[gm_[*it].variableIndex(j)];
337 OPENGM_ASSERT(currentFactorState[j] < gm_[*it].numberOfLabels(j));
338 destinationFactorState[j] = stateBuffer_[gm_[*it].variableIndex(j)];
339 OPENGM_ASSERT(destinationFactorState[j] < gm_[*it].numberOfLabels(j));
341 OperatorType::op(destinationValue, gm_[*it](destinationFactorState.begin()), destinationValue);
342 OperatorType::iop(destinationValue, gm_[*it](currentFactorState.begin()), destinationValue);
345 for (IndexIterator it = begin; it != end; ++it) {
346 stateBuffer_[*it] = state_[*it];
349 return destinationValue;
353 template<
class IndexIterator,
class StateIterator>
362 while (begin != end) {
363 state_[*begin] = *sit;
364 stateBuffer_[*begin] = *sit;
377 template<
class ACCUMULATOR,
class IndexIterator>
381 IndexIterator variableIndices,
382 IndexIterator variableIndicesEnd
385 std::set<size_t> factorsToRecompute;
386 for (IndexIterator it = variableIndices; it != variableIndicesEnd; ++it) {
387 std::set<size_t> tmpSet;
388 std::set_union(factorsToRecompute.begin(), factorsToRecompute.end(),
389 factorsOfVariable_[*it].begin(), factorsOfVariable_[*it].end(),
390 std::inserter(tmpSet, tmpSet.begin()));
391 factorsToRecompute.swap(tmpSet);
395 size_t numberOfVariables = std::distance(variableIndices, variableIndicesEnd);
396 ValueType initialEnergy = evaluateFactors(
397 factorsToRecompute.begin(),
398 factorsToRecompute.end(),
400 ValueType bestEnergy = initialEnergy;
401 std::vector<size_t> bestState(numberOfVariables);
402 for (
size_t j=0; j<numberOfVariables; ++j) {
403 const size_t vi = variableIndices[j];
404 stateBuffer_[vi] = 0;
408 ValueType energy = evaluateFactors(
409 factorsToRecompute.begin(),
410 factorsToRecompute.end(),
412 if(ACCUMULATOR::bop(energy, bestEnergy)) {
415 for (
size_t j = 0; j < numberOfVariables; ++j) {
416 bestState[j] = stateBuffer_[variableIndices[j]];
420 for (
size_t j = 0; j < numberOfVariables; ++j) {
421 const size_t vi = variableIndices[j];
422 if (stateBuffer_[vi] < gm_.numberOfLabels(vi) - 1) {
426 if (j < numberOfVariables - 1) {
427 stateBuffer_[vi] = 0;
437 if (ACCUMULATOR::bop(bestEnergy, initialEnergy)) {
439 for (
size_t j = 0; j < numberOfVariables; ++j) {
440 const size_t vi = variableIndices[j];
441 state_[vi] = bestState[j];
442 stateBuffer_[vi] = bestState[j];
446 meta::Compare<ACCUMULATOR, opengm::Maximizer>::value,
447 meta::Compare<OperatorType, opengm::Multiplier>::value
448 >::
value && energy_ == static_cast<ValueType> (0)) {
450 energy_ = gm_.evaluate(state_.begin());
453 OperatorType::iop(initialEnergy, energy_);
454 OperatorType::op(bestEnergy, energy_);
458 for (
size_t j = 0; j < numberOfVariables; ++j) {
459 const size_t vi = variableIndices[j];
460 stateBuffer_[vi] = state_[vi];
470 template<
class ACCUMULATOR,
class IndexIterator>
474 IndexIterator variableIndices,
475 IndexIterator variableIndicesEnd
478 std::set<size_t> factorsToRecompute;
479 for (IndexIterator it = variableIndices; it != variableIndicesEnd; ++it) {
480 std::set<size_t> tmpSet;
481 std::set_union(factorsToRecompute.begin(), factorsToRecompute.end(),
482 factorsOfVariable_[*it].begin(), factorsOfVariable_[*it].end(),
483 std::inserter(tmpSet, tmpSet.begin()));
484 factorsToRecompute.swap(tmpSet);
488 size_t numberOfVariables = std::distance(variableIndices, variableIndicesEnd);
489 ValueType initialEnergy = evaluateFactors(
490 factorsToRecompute.begin(),
491 factorsToRecompute.end(),
493 ValueType bestEnergy = initialEnergy;
494 std::vector<size_t> bestState(numberOfVariables);
496 for(
size_t j=0; j<numberOfVariables; ++j) {
497 if(gm_.space().numberOfLabels(variableIndices[j]) == 1) {
499 for(
size_t k=0; k<j; ++k) {
500 stateBuffer_[k] = state_[k];
505 const size_t vi = variableIndices[j];
506 if(state_[vi] == 0) {
507 stateBuffer_[vi] = 1;
510 stateBuffer_[vi] = 0;
516 for(
size_t j=0; j<numberOfVariables; ++j) {
517 const size_t vi = variableIndices[j];
522 ValueType energy = evaluateFactors(
523 factorsToRecompute.begin(),
524 factorsToRecompute.end(),
526 if(ACCUMULATOR::bop(energy, bestEnergy)) {
529 for (
size_t j = 0; j < numberOfVariables; ++j) {
530 bestState[j] = stateBuffer_[variableIndices[j]];
534 for (
size_t j=0; j<numberOfVariables; ++j) {
535 const size_t vi = variableIndices[j];
536 if(stateBuffer_[vi] < gm_.numberOfLabels(vi) - 1) {
537 if(stateBuffer_[vi] + 1 != state_[vi]) {
541 else if(stateBuffer_[vi] + 1 < gm_.numberOfLabels(vi) - 1) {
542 stateBuffer_[vi] += 2;
546 if (j < numberOfVariables - 1) {
547 if(state_[vi] == 0) {
548 stateBuffer_[vi] = 1;
551 stateBuffer_[vi] = 0;
558 if (j < numberOfVariables - 1) {
559 if(state_[vi] == 0) {
560 stateBuffer_[vi] = 1;
563 stateBuffer_[vi] = 0;
574 if (ACCUMULATOR::bop(bestEnergy, initialEnergy)) {
576 for (
size_t j = 0; j < numberOfVariables; ++j) {
577 const size_t vi = variableIndices[j];
578 state_[vi] = bestState[j];
579 stateBuffer_[vi] = bestState[j];
583 meta::Compare<ACCUMULATOR, opengm::Maximizer>::value,
584 meta::Compare<OperatorType, opengm::Multiplier>::value
585 >::
value && energy_ == static_cast<ValueType> (0)) {
586 energy_ = gm_.evaluate(state_.begin());
589 OperatorType::iop(initialEnergy, energy_);
590 OperatorType::op(bestEnergy, energy_);
594 for (
size_t j = 0; j < numberOfVariables; ++j) {
595 const size_t vi = variableIndices[j];
596 stateBuffer_[vi] = state_[vi];
607 const size_t variableIndex
610 return state_[variableIndex];
616 return state_.begin();
626 template<
class FactorIndexIterator>
630 FactorIndexIterator begin,
631 FactorIndexIterator end,
632 const std::vector<LabelType>&
state 634 ValueType
value = OperatorType::template neutral<ValueType>();
635 for(; begin != end; ++begin) {
636 std::vector<size_t> currentFactorState(gm_[*begin].numberOfVariables());
637 for (
size_t j=0; j<gm_[*begin].numberOfVariables(); ++j) {
638 currentFactorState[j] = state[gm_[*begin].variableIndex(j)];
640 OperatorType::op(value, gm_[*begin](currentFactorState.begin()), value);
647 #endif // #ifndef OPENGM_MOVEMAKER_HXX LabelIterator stateBegin() const
LabelIterator stateEnd() const
ValueType valueAfterMove(IndexIterator, IndexIterator, StateIterator)
std::vector< LabelType >::const_iterator LabelIterator
Movemaker(const GraphicalModelType &)
#define OPENGM_ASSERT(expression)
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
reference to a Factor of a GraphicalModel
const LabelType & state(const size_t) const
void initialize(StateIterator)
Funcion that refers to a factor of another GraphicalModel in which some variables are fixed...
ValueType move(IndexIterator, IndexIterator, StateIterator)
void proposeMoveAccordingToInference(const INFERENCE_PARAMETER &, INDEX_ITERATOR, INDEX_ITERATOR, std::vector< LabelType > &) const