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 <vil/vil_image_view.h> 00013 #include <vcl_vector.h> 00014 00015 //: Find choice of values at each node which minimises Markov problem. 00016 // Minimises F() = sum node_costs + sum pair_costs 00017 // 00018 // Assumes graph defining relationships can be fully decomposed by 00019 // repeatedly removing any nodes with two or fewer neighbours. 00020 // Global optimum is found using a series of sequential exhaustive 00021 // optimisations. 00022 class mmn_dp_solver 00023 { 00024 private: 00025 //: Workspace for incremental costs of each node 00026 vcl_vector<vnl_vector<double> > nc_; 00027 00028 //: Workspace for incremental costs of each arc 00029 vcl_vector<vnl_matrix<double> > pc_; 00030 00031 //: index1[i][j] = optimal choice for i if other node is j 00032 vcl_vector<vcl_vector<unsigned> > index1_; 00033 00034 //: index2[i](j,k) = optimal choice of i if two other nodes are (j,k) 00035 vcl_vector<vnl_matrix<int> > index2_; 00036 00037 //: Dependencies 00038 vcl_vector<mmn_dependancy> deps_; 00039 00040 //: Compute optimal choice for node dep.v0 for each possible v1 00041 // Uses pair costs for v0-v1 (in pc_) and the node cost nc_(v0) 00042 void process_dep1(const mmn_dependancy& dep); 00043 00044 //: Compute optimal choice for dep.v0 given v1 and v2 00045 // Uses only pairwise and node costs (in nc_ and pc_) 00046 void process_dep2(const mmn_dependancy& dep); 00047 00048 //: Compute optimal choice for dep.v0 given v1 and v2 00049 // Includes cost depending on (v0,v1,v2) as well as pairwise and 00050 // node costs. 00051 // tri_cost(i,j,k) is cost of associating smallest node index 00052 // with i, next with j and largest node index with k. 00053 void process_dep2t(const mmn_dependancy& dep, 00054 const vil_image_view<double>& tri_cost); 00055 00056 public: 00057 //: Default constructor 00058 mmn_dp_solver(); 00059 00060 //: Index of root node 00061 unsigned root() const; 00062 00063 //: Define dependencies 00064 void set_dependancies(const vcl_vector<mmn_dependancy>& deps, 00065 unsigned n_nodes, unsigned max_n_arcs); 00066 00067 //: Find values for each node with minimise the total cost 00068 // \param node_cost: node_cost[i][j] is cost of selecting value j for node i 00069 // \param pair_cost: pair_cost[a](i,j) is cost of selecting values (i,j) for nodes at end of arc a. 00070 // \param x: On exit, x[i] gives choice for node i 00071 // NOTE: If arc a connects nodes v1,v2, the associated pair_cost is ordered 00072 // with the node with the lowest index being the first parameter. Thus if 00073 // v1 has value i1, v2 has value i2, then the cost of this choice is 00074 // (v1<v2?pair_cost(i1,i2):pair_cost(i2,i1)) 00075 // Returns the minimum cost 00076 double solve(const vcl_vector<vnl_vector<double> >& node_cost, 00077 const vcl_vector<vnl_matrix<double> >& pair_cost, 00078 vcl_vector<unsigned>& x); 00079 00080 //: Find values for each node with minimise the total cost 00081 // As solve(node_cost,pair_cost,x), but allows inclusion of 00082 // costs for triplets (ie when v0 depends on v1 and v2). 00083 // tri_cost(i,j,k) gives cost of node min(v0,v1,v2) being 00084 // value i, node mid(v0,v1,v2) being value j and 00085 // node max(v0,v1,v2) being value k. 00086 double solve(const vcl_vector<vnl_vector<double> >& node_cost, 00087 const vcl_vector<vnl_matrix<double> >& pair_cost, 00088 const vcl_vector<vil_image_view<double> >& tri_cost, 00089 vcl_vector<unsigned>& x); 00090 00091 //: Compute optimal values for x[i] given that root node is root_value 00092 // Assumes that solve() has been already called. 00093 void backtrace(unsigned root_value,vcl_vector<unsigned>& x); 00094 00095 //: root_cost()[i] is cost of selecting value i for the root node 00096 const vnl_vector<double>& root_cost() const { return nc_[root()]; } 00097 }; 00098 00099 #endif // mmn_dp_solver_h_
1.5.1