00001 #ifndef mmn_dp_solver_h_ 00002 #define mmn_dp_solver_h_ 00003 //: 00004 // \file 00005 // \brief Find choice of values at each node which minimises Markov problem 00006 // \author Tim Cootes 00007 00008 #include <mmn/mmn_arc.h> 00009 #include <mmn/mmn_dependancy.h> 00010 #include <vnl/vnl_vector.h> 00011 #include <vnl/vnl_matrix.h> 00012 #include <vcl_vector.h> 00013 00014 //: Find choice of values at each node which minimises Markov problem. 00015 // Minimises F() = sum node_costs + sum pair_costs 00016 // 00017 // Assumes graph defining relationships can be fully decomposed by 00018 // repeatedly removing any nodes with two or fewer neighbours. 00019 // Global optimum is found using a series of sequential exhaustive 00020 // optimisations. 00021 class mmn_dp_solver 00022 { 00023 private: 00024 //: Workspace for incremental costs of each node 00025 vcl_vector<vnl_vector<double> > nc_; 00026 00027 //: Workspace for incremental costs of each arc 00028 vcl_vector<vnl_matrix<double> > pc_; 00029 00030 //: index1[i][j] = optimal choice for i if other node is j 00031 vcl_vector<vcl_vector<unsigned> > index1_; 00032 00033 //: index2[i](j,k) = optimal choice of i if two other nodes are (j,k) 00034 vcl_vector<vnl_matrix<int> > index2_; 00035 00036 //: Dependencies 00037 vcl_vector<mmn_dependancy> deps_; 00038 00039 void process_dep1(const mmn_dependancy& dep); 00040 void process_dep2(const mmn_dependancy& dep); 00041 public: 00042 //: Default constructor 00043 mmn_dp_solver(); 00044 00045 //: Index of root node 00046 unsigned root() const; 00047 00048 //: Define dependencies 00049 void set_dependancies(const vcl_vector<mmn_dependancy>& deps, 00050 unsigned n_nodes, unsigned max_n_arcs); 00051 00052 //: Find values for each node with minimise the total cost 00053 // \param node_cost: node_cost[i][j] is cost of selecting value j for node i 00054 // \param pair_cost: pair_cost[a](i,j) is cost of selecting values (i,j) for nodes at end of arc a. 00055 // \param x: On exit, x[i] gives choice for node i 00056 // NOTE: If arc a connects nodes v1,v2, the associated pair_cost is ordered 00057 // with the node with the lowest index being the first parameter. Thus if 00058 // v1 has value i1, v2 has value i2, then the cost of this choice is 00059 // (v1<v2?pair_cost(i1,i2):pair_cost(i2,i1)) 00060 // Returns the minimum cost 00061 double solve(const vcl_vector<vnl_vector<double> >& node_cost, 00062 const vcl_vector<vnl_matrix<double> >& pair_cost, 00063 vcl_vector<unsigned>& x); 00064 00065 //: Compute optimal values for x[i] given that root node is root_value 00066 // Assumes that solve() has been already called. 00067 void backtrace(unsigned root_value,vcl_vector<unsigned>& x); 00068 00069 //: root_cost()[i] is cost of selecting value i for the root node 00070 const vnl_vector<double>& root_cost() const { return nc_[root()]; } 00071 }; 00072 00073 #endif // mmn_dp_solver_h_
1.4.4