2 #ifndef OPENGM_DYNAMICPROGRAMMING_HXX
3 #define OPENGM_DYNAMICPROGRAMMING_HXX
15 template<
class GM,
class ACC>
34 std::string
name()
const;
37 template<
class VISITOR>
42 void getNodeInfo(
const IndexType Inode, std::vector<ValueType>& values, std::vector<std::vector<LabelType> >& substates, std::vector<IndexType>& nodes)
const;
46 const GraphicalModelType& gm_;
48 MyValueType* valueBuffer_;
49 MyStateType* stateBuffer_;
50 std::vector<MyValueType*> valueBuffers_;
51 std::vector<MyStateType*> stateBuffers_;
52 std::vector<size_t> nodeOrder_;
53 std::vector<size_t> orderedNodes_;
54 bool inferenceStarted_;
57 template<
class GM,
class ACC>
60 return "DynamicProgramming";
63 template<
class GM,
class ACC>
69 template<
class GM,
class ACC>
76 template<
class GM,
class ACC>
79 const GraphicalModelType& gm,
82 : gm_(gm), inferenceStarted_(
false)
88 std::vector<size_t> numChildren(gm_.numberOfVariables(),0);
89 std::vector<size_t> nodeList;
90 size_t orderCount = 0;
92 nodeOrder_.resize(gm_.numberOfVariables(),std::numeric_limits<std::size_t>::max());
94 while(varCount < gm_.numberOfVariables() && orderCount < gm_.numberOfVariables()){
95 if(rootCounter<para_.roots_.size()){
96 nodeOrder_[para_.roots_[rootCounter]] = orderCount++;
97 nodeList.push_back(para_.roots_[rootCounter]);
100 else if(nodeOrder_[varCount]==std::numeric_limits<std::size_t>::max()){
101 nodeOrder_[varCount] = orderCount++;
102 nodeList.push_back(varCount);
105 while(nodeList.size()>0){
106 size_t node = nodeList.back();
108 for(
typename GM::ConstFactorIterator it=gm_.factorsOfVariableBegin(node); it !=gm_.factorsOfVariableEnd(node); ++it){
109 const typename GM::FactorType& factor = gm_[(*it)];
110 if( factor.numberOfVariables() == 2 ){
111 if( factor.variableIndex(1) == node && nodeOrder_[factor.variableIndex(0)]==std::numeric_limits<std::size_t>::max() ){
112 nodeOrder_[factor.variableIndex(0)] = orderCount++;
113 nodeList.push_back(factor.variableIndex(0));
116 if( factor.variableIndex(0) == node && nodeOrder_[factor.variableIndex(1)]==std::numeric_limits<std::size_t>::max() ){
117 nodeOrder_[factor.variableIndex(1)] = orderCount++;
118 nodeList.push_back(factor.variableIndex(1));
127 size_t memSizeValue = 0;
128 size_t memSizeState = 0;
129 for(
size_t i=0; i<gm_.numberOfVariables();++i){
130 memSizeValue += gm_.numberOfLabels(i);
131 memSizeState += gm.numberOfLabels(i) * numChildren[i];
133 valueBuffer_ = (MyValueType*) malloc(memSizeValue*
sizeof(MyValueType));
134 stateBuffer_ = (MyStateType*) malloc(memSizeState*
sizeof(MyStateType));
135 valueBuffers_.resize(gm_.numberOfVariables());
136 stateBuffers_.resize(gm_.numberOfVariables());
138 MyValueType* valuePointer = valueBuffer_;
139 MyStateType* statePointer = stateBuffer_;
140 for(
size_t i=0; i<gm_.numberOfVariables();++i){
141 valueBuffers_[i] = valuePointer;
142 valuePointer += gm.numberOfLabels(i);
143 stateBuffers_[i] = statePointer;
144 statePointer += gm.numberOfLabels(i) * numChildren[i];
147 orderedNodes_.resize(gm_.numberOfVariables(),std::numeric_limits<std::size_t>::max());
148 for(
size_t i=0; i<gm_.numberOfVariables(); ++i)
149 orderedNodes_[nodeOrder_[i]] = i;
153 template<
class GM,
class ACC>
160 template<
class GM,
class ACC>
161 template<
class VISITOR>
167 visitor.begin(*
this);
168 inferenceStarted_ =
true;
169 for(
size_t i=1; i<=gm_.numberOfVariables();++i){
170 const size_t node = orderedNodes_[gm_.numberOfVariables()-i];
172 for(
size_t n=0; n<gm_.numberOfLabels(node); ++n){
173 OperatorType::neutral(valueBuffers_[node][n]);
176 size_t childrenCounter = 0;
177 for(
typename GM::ConstFactorIterator it=gm_.factorsOfVariableBegin(node); it !=gm_.factorsOfVariableEnd(node); ++it){
178 const typename GM::FactorType& factor = gm_[(*it)];
181 if(factor.numberOfVariables()==1 ){
182 for(
size_t n=0; n<gm_.numberOfLabels(node); ++n){
184 OperatorType::op(fac, valueBuffers_[node][n]);
189 if( factor.numberOfVariables()==2 ){
190 size_t vec[] = {0,0};
191 if(factor.variableIndex(0) == node && nodeOrder_[factor.variableIndex(1)]>nodeOrder_[node] ){
192 const size_t node2 = factor.variableIndex(1);
195 for(vec[0]=0; vec[0]<gm_.numberOfLabels(node); ++vec[0]){
197 for(vec[1]=0; vec[1]<gm_.numberOfLabels(node2); ++vec[1]){
199 OperatorType::op(fac,valueBuffers_[node2][vec[1]],v2) ;
205 stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+vec[0]] = s;
206 OperatorType::op(v,valueBuffers_[node][vec[0]]);
211 if(factor.variableIndex(1) == node && nodeOrder_[factor.variableIndex(0)]>nodeOrder_[node]){
212 const size_t node2 = factor.variableIndex(0);
215 for(vec[1]=0; vec[1]<gm_.numberOfLabels(node); ++vec[1]){
217 for(vec[0]=0; vec[0]<gm_.numberOfLabels(node2); ++vec[0]){
219 OperatorType::op(fac,valueBuffers_[node2][vec[0]],v2);
225 stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+vec[1]] = s;
226 OperatorType::op(v,valueBuffers_[node][vec[1]]);
232 if( factor.numberOfVariables()>2 ){
233 throw std::runtime_error(
"This implementation of Dynamic Programming does only support second order models so far, but could be extended.");
242 template<
class GM,
class ACC>
245 std::vector<LabelType>& arg,
249 arg.assign(gm_.numberOfVariables(), 0);
253 if(inferenceStarted_) {
254 std::vector<size_t> nodeList;
255 arg.assign(gm_.numberOfVariables(), std::numeric_limits<LabelType>::max() );
257 while(var < gm_.numberOfVariables()){
258 if(arg[var]==std::numeric_limits<LabelType>::max()){
259 MyValueType v; ACC::neutral(v);
260 for(
size_t i=0; i<gm_.numberOfLabels(var); ++i){
261 if(ACC::bop(valueBuffers_[var][i], v)){
262 v = valueBuffers_[var][i];
266 nodeList.push_back(var);
269 while(nodeList.size()>0){
270 size_t node = nodeList.back();
271 size_t childrenCounter = 0;
273 for(
typename GM::ConstFactorIterator it=gm_.factorsOfVariableBegin(node); it !=gm_.factorsOfVariableEnd(node); ++it){
274 const typename GM::FactorType& factor = gm_[(*it)];
275 if(factor.numberOfVariables()==2 ){
276 if(factor.variableIndex(1)==node && nodeOrder_[factor.variableIndex(0)] > nodeOrder_[node] ){
277 arg[factor.variableIndex(0)] = stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]];
278 nodeList.push_back(factor.variableIndex(0));
281 if(factor.variableIndex(0)==node && nodeOrder_[factor.variableIndex(1)] > nodeOrder_[node] ){
282 arg[factor.variableIndex(1)] = stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]];
283 nodeList.push_back(factor.variableIndex(1));
292 arg.assign(gm_.numberOfVariables(), 0);
298 template<
class GM,
class ACC>
303 values.resize(gm_.numberOfLabels(Inode));
304 substates.resize(gm_.numberOfLabels(Inode));
305 std::vector<LabelType> arg;
306 bool firstround =
true;
307 std::vector<size_t> nodeList;
308 for(
IndexType i=0;i<gm_.numberOfLabels(Inode); ++i){
309 arg.assign(gm_.numberOfVariables(), std::numeric_limits<LabelType>::max() );
311 values[i]=valueBuffers_[Inode][i];
312 nodeList.push_back(Inode);
317 while(nodeList.size()>0){
318 size_t node = nodeList.back();
319 size_t childrenCounter = 0;
321 for(
typename GM::ConstFactorIterator it=gm_.factorsOfVariableBegin(node); it !=gm_.factorsOfVariableEnd(node); ++it){
322 const typename GM::FactorType& factor = gm_[(*it)];
323 if(factor.numberOfVariables()==2 ){
324 if(factor.variableIndex(1)==node && nodeOrder_[factor.variableIndex(0)] > nodeOrder_[node] ){
325 arg[factor.variableIndex(0)] = stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]];
326 substates[i].push_back(stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]]);
327 if(firstround==
true){
328 nodes.push_back(factor.variableIndex(0));
330 nodeList.push_back(factor.variableIndex(0));
333 if(factor.variableIndex(0)==node && nodeOrder_[factor.variableIndex(1)] > nodeOrder_[node] ){
334 arg[factor.variableIndex(1)] = stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]];
335 substates[i].push_back(stateBuffers_[node][childrenCounter*gm_.numberOfLabels(node)+arg[node]]);
336 if(firstround==
true){
337 nodes.push_back(factor.variableIndex(1));
339 nodeList.push_back(factor.variableIndex(1));
351 #endif // #ifndef OPENGM_DYNAMICPROGRAMMING_HXX
#define OPENGM_ASSERT(expression)
GraphicalModelType::IndexType IndexType
void getNodeInfo(const IndexType Inode, std::vector< ValueType > &values, std::vector< std::vector< LabelType > > &substates, std::vector< IndexType > &nodes) const
GraphicalModelType::ValueType ValueType
Inference algorithm interface.
InferenceTermination arg(std::vector< LabelType > &, const size_t=1) const
output a solution
const GraphicalModelType & graphicalModel() const
visitors::VerboseVisitor< DynamicProgramming< GM, ACC > > VerboseVisitorType
visitors::EmptyVisitor< DynamicProgramming< GM, ACC > > EmptyVisitorType
InferenceTermination infer()
GraphicalModelType::LabelType LabelType
std::vector< IndexType > roots_
DynamicProgramming(const GraphicalModelType &, const Parameter &=Parameter())
visitors::TimingVisitor< DynamicProgramming< GM, ACC > > TimingVisitorType