2 #ifndef OPENGM_DYNAMICPROGRAMMING_HXX 3 #define OPENGM_DYNAMICPROGRAMMING_HXX 15 template<
class GM,
class ACC>
34 template<
class _GM,
class _ACC>
54 std::string
name()
const;
57 template<
class VISITOR>
62 void getNodeInfo(
const IndexType Inode, std::vector<ValueType>& values, std::vector<std::vector<LabelType> >& substates, std::vector<IndexType>& nodes)
const;
66 const GraphicalModelType& gm_;
68 MyValueType* valueBuffer_;
69 MyStateType* stateBuffer_;
70 std::vector<MyValueType*> valueBuffers_;
71 std::vector<MyStateType*> stateBuffers_;
72 std::vector<size_t> nodeOrder_;
73 std::vector<size_t> orderedNodes_;
74 bool inferenceStarted_;
77 template<
class GM,
class ACC>
80 return "DynamicProgramming";
83 template<
class GM,
class ACC>
89 template<
class GM,
class ACC>
96 template<
class GM,
class ACC>
99 const GraphicalModelType& gm,
102 : gm_(gm), inferenceStarted_(
false)
108 std::vector<size_t> numChildren(gm_.numberOfVariables(),0);
109 std::vector<size_t> nodeList;
110 size_t orderCount = 0;
112 nodeOrder_.resize(gm_.numberOfVariables(),std::numeric_limits<std::size_t>::max());
113 size_t rootCounter=0;
114 while(varCount < gm_.numberOfVariables() && orderCount < gm_.numberOfVariables()){
115 if(rootCounter<para_.roots_.size()){
116 nodeOrder_[para_.roots_[rootCounter]] = orderCount++;
117 nodeList.push_back(para_.roots_[rootCounter]);
120 else if(nodeOrder_[varCount]==std::numeric_limits<std::size_t>::max()){
121 nodeOrder_[varCount] = orderCount++;
122 nodeList.push_back(varCount);
125 while(nodeList.size()>0){
126 size_t node = nodeList.back();
128 for(
typename GM::ConstFactorIterator it=gm_.factorsOfVariableBegin(node); it !=gm_.factorsOfVariableEnd(node); ++it){
129 const typename GM::FactorType& factor = gm_[(*it)];
130 if( factor.numberOfVariables() == 2 ){
131 if( factor.variableIndex(1) == node && nodeOrder_[factor.variableIndex(0)]==std::numeric_limits<std::size_t>::max() ){
132 nodeOrder_[factor.variableIndex(0)] = orderCount++;
133 nodeList.push_back(factor.variableIndex(0));
136 if( factor.variableIndex(0) == node && nodeOrder_[factor.variableIndex(1)]==std::numeric_limits<std::size_t>::max() ){
137 nodeOrder_[factor.variableIndex(1)] = orderCount++;
138 nodeList.push_back(factor.variableIndex(1));
147 size_t memSizeValue = 0;
148 size_t memSizeState = 0;
149 for(
size_t i=0; i<gm_.numberOfVariables();++i){
150 memSizeValue += gm_.numberOfLabels(i);
151 memSizeState += gm.numberOfLabels(i) * numChildren[i];
153 valueBuffer_ = (MyValueType*) malloc(memSizeValue*
sizeof(MyValueType));
154 stateBuffer_ = (MyStateType*) malloc(memSizeState*
sizeof(MyStateType));
155 valueBuffers_.resize(gm_.numberOfVariables());
156 stateBuffers_.resize(gm_.numberOfVariables());
158 MyValueType* valuePointer = valueBuffer_;
159 MyStateType* statePointer = stateBuffer_;
160 for(
size_t i=0; i<gm_.numberOfVariables();++i){
161 valueBuffers_[i] = valuePointer;
162 valuePointer += gm.numberOfLabels(i);
163 stateBuffers_[i] = statePointer;
164 statePointer += gm.numberOfLabels(i) * numChildren[i];
167 orderedNodes_.resize(gm_.numberOfVariables(),std::numeric_limits<std::size_t>::max());
168 for(
size_t i=0; i<gm_.numberOfVariables(); ++i)
169 orderedNodes_[nodeOrder_[i]] = i;
173 template<
class GM,
class ACC>
180 template<
class GM,
class ACC>
181 template<
class VISITOR>
187 visitor.begin(*
this);
188 inferenceStarted_ =
true;
189 for(
size_t i=1; i<=gm_.numberOfVariables();++i){
190 const size_t node = orderedNodes_[gm_.numberOfVariables()-i];
192 for(
size_t n=0; n<gm_.numberOfLabels(node); ++n){
193 OperatorType::neutral(valueBuffers_[node][n]);
196 size_t childrenCounter = 0;
197 for(
typename GM::ConstFactorIterator it=gm_.factorsOfVariableBegin(node); it !=gm_.factorsOfVariableEnd(node); ++it){
198 const typename GM::FactorType& factor = gm_[(*it)];
201 if(factor.numberOfVariables()==1 ){
202 for(
size_t n=0; n<gm_.numberOfLabels(node); ++n){
204 OperatorType::op(fac, valueBuffers_[node][n]);
209 if( factor.numberOfVariables()==2 ){
210 size_t vec[] = {0,0};
211 if(factor.variableIndex(0) == node && nodeOrder_[factor.variableIndex(1)]>nodeOrder_[node] ){
212 const size_t node2 = factor.variableIndex(1);
215 for(vec[0]=0; vec[0]<gm_.numberOfLabels(node); ++vec[0]){
217 for(vec[1]=0; vec[1]<gm_.numberOfLabels(node2); ++vec[1]){
219 OperatorType::op(fac,valueBuffers_[node2][vec[1]],v2) ;
225 stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+vec[0]] = s;
226 OperatorType::op(v,valueBuffers_[node][vec[0]]);
231 if(factor.variableIndex(1) == node && nodeOrder_[factor.variableIndex(0)]>nodeOrder_[node]){
232 const size_t node2 = factor.variableIndex(0);
235 for(vec[1]=0; vec[1]<gm_.numberOfLabels(node); ++vec[1]){
237 for(vec[0]=0; vec[0]<gm_.numberOfLabels(node2); ++vec[0]){
239 OperatorType::op(fac,valueBuffers_[node2][vec[0]],v2);
245 stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+vec[1]] = s;
246 OperatorType::op(v,valueBuffers_[node][vec[1]]);
252 if( factor.numberOfVariables()>2 ){
253 throw std::runtime_error(
"This implementation of Dynamic Programming does only support second order models so far, but could be extended.");
262 template<
class GM,
class ACC>
265 std::vector<LabelType>&
arg,
269 arg.assign(gm_.numberOfVariables(), 0);
273 if(inferenceStarted_) {
274 std::vector<size_t> nodeList;
275 arg.assign(gm_.numberOfVariables(), std::numeric_limits<LabelType>::max() );
277 while(var < gm_.numberOfVariables()){
278 if(arg[var]==std::numeric_limits<LabelType>::max()){
279 MyValueType v; ACC::neutral(v);
280 for(
size_t i=0; i<gm_.numberOfLabels(var); ++i){
281 if(ACC::bop(valueBuffers_[var][i], v)){
282 v = valueBuffers_[var][i];
286 nodeList.push_back(var);
289 while(nodeList.size()>0){
290 size_t node = nodeList.back();
291 size_t childrenCounter = 0;
293 for(
typename GM::ConstFactorIterator it=gm_.factorsOfVariableBegin(node); it !=gm_.factorsOfVariableEnd(node); ++it){
294 const typename GM::FactorType& factor = gm_[(*it)];
295 if(factor.numberOfVariables()==2 ){
296 if(factor.variableIndex(1)==node && nodeOrder_[factor.variableIndex(0)] > nodeOrder_[node] ){
297 arg[factor.variableIndex(0)] = stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]];
298 nodeList.push_back(factor.variableIndex(0));
301 if(factor.variableIndex(0)==node && nodeOrder_[factor.variableIndex(1)] > nodeOrder_[node] ){
302 arg[factor.variableIndex(1)] = stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]];
303 nodeList.push_back(factor.variableIndex(1));
312 arg.assign(gm_.numberOfVariables(), 0);
318 template<
class GM,
class ACC>
323 values.resize(gm_.numberOfLabels(Inode));
324 substates.resize(gm_.numberOfLabels(Inode));
325 std::vector<LabelType>
arg;
326 bool firstround =
true;
327 std::vector<size_t> nodeList;
328 for(
IndexType i=0;i<gm_.numberOfLabels(Inode); ++i){
329 arg.assign(gm_.numberOfVariables(), std::numeric_limits<LabelType>::max() );
331 values[i]=valueBuffers_[Inode][i];
332 nodeList.push_back(Inode);
337 while(nodeList.size()>0){
338 size_t node = nodeList.back();
339 size_t childrenCounter = 0;
341 for(
typename GM::ConstFactorIterator it=gm_.factorsOfVariableBegin(node); it !=gm_.factorsOfVariableEnd(node); ++it){
342 const typename GM::FactorType& factor = gm_[(*it)];
343 if(factor.numberOfVariables()==2 ){
344 if(factor.variableIndex(1)==node && nodeOrder_[factor.variableIndex(0)] > nodeOrder_[node] ){
345 arg[factor.variableIndex(0)] = stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]];
346 substates[i].push_back(stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]]);
347 if(firstround==
true){
348 nodes.push_back(factor.variableIndex(0));
350 nodeList.push_back(factor.variableIndex(0));
353 if(factor.variableIndex(0)==node && nodeOrder_[factor.variableIndex(1)] > nodeOrder_[node] ){
354 arg[factor.variableIndex(1)] = stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]];
355 substates[i].push_back(stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]]);
356 if(firstround==
true){
357 nodes.push_back(factor.variableIndex(1));
359 nodeList.push_back(factor.variableIndex(1));
371 #endif // #ifndef OPENGM_DYNAMICPROGRAMMING_HXX
#define OPENGM_ASSERT(expression)
InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
GraphicalModelType::IndexType IndexType
GraphicalModelType::ValueType ValueType
Inference algorithm interface.
void getNodeInfo(const IndexType Inode, std::vector< ValueType > &values, std::vector< std::vector< LabelType > > &substates, std::vector< IndexType > &nodes) const
visitors::VerboseVisitor< DynamicProgramming< GM, ACC > > VerboseVisitorType
DynamicProgramming< _GM, _ACC > type
visitors::EmptyVisitor< DynamicProgramming< GM, ACC > > EmptyVisitorType
InferenceTermination infer()
DynamicProgramming< _GM, ACC > type
GraphicalModelType::LabelType LabelType
std::vector< IndexType > roots_
DynamicProgramming(const GraphicalModelType &, const Parameter &=Parameter())
const GraphicalModelType & graphicalModel() const
visitors::TimingVisitor< DynamicProgramming< GM, ACC > > TimingVisitorType