00001 #ifndef mmn_dp_solver_h_ 00002 #define mmn_dp_solver_h_ 00003 //: 00004 // \file 00005 // \brief Solve restricted class of Markov problems (trees and tri-trees) 00006 // \author Tim Cootes 00007 00008 #include <mmn/mmn_arc.h> 00009 #include <mmn/mmn_dependancy.h> 00010 #include <mmn/mmn_solver.h> 00011 #include <vnl/vnl_vector.h> 00012 #include <vnl/vnl_matrix.h> 00013 #include <vil/vil_image_view.h> 00014 #include <vcl_vector.h> 00015 #include <vcl_iosfwd.h> 00016 00017 //: Solve restricted class of Markov problems (trees and tri-trees) 00018 // Find choice of values at each node which minimises Markov problem. 00019 // Minimises F() = sum node_costs + sum pair_costs 00020 // 00021 // Assumes graph defining relationships can be fully decomposed by 00022 // repeatedly removing any nodes with two or fewer neighbours. 00023 // Global optimum is found using a series of sequential exhaustive 00024 // optimisations. 00025 class mmn_dp_solver : public mmn_solver 00026 { 00027 private: 00028 //: Workspace for incremental costs of each node 00029 vcl_vector<vnl_vector<double> > nc_; 00030 00031 //: Workspace for incremental costs of each arc 00032 vcl_vector<vnl_matrix<double> > pc_; 00033 00034 //: index1[i][j] = optimal choice for i if other node is j 00035 vcl_vector<vcl_vector<unsigned> > index1_; 00036 00037 //: index2[i](j,k) = optimal choice of i if two other nodes are (j,k) 00038 vcl_vector<vnl_matrix<int> > index2_; 00039 00040 //: Dependencies 00041 vcl_vector<mmn_dependancy> deps_; 00042 00043 //: Compute optimal choice for node dep.v0 for each possible v1 00044 // Uses pair costs for v0-v1 (in pc_) and the node cost nc_(v0) 00045 void process_dep1(const mmn_dependancy& dep); 00046 00047 //: Compute optimal choice for dep.v0 given v1 and v2 00048 // Uses only pairwise and node costs (in nc_ and pc_) 00049 void process_dep2(const mmn_dependancy& dep); 00050 00051 //: Compute optimal choice for dep.v0 given v1 and v2 00052 // Includes cost depending on (v0,v1,v2) as well as pairwise and 00053 // node costs. 00054 // tri_cost(i,j,k) is cost of associating smallest node index 00055 // with i, next with j and largest node index with k. 00056 void process_dep2t(const mmn_dependancy& dep, 00057 const vil_image_view<double>& tri_cost); 00058 00059 public: 00060 //: Default constructor 00061 mmn_dp_solver(); 00062 00063 //: Index of root node 00064 unsigned root() const; 00065 00066 //: Input the arcs that define the graph 00067 virtual void set_arcs(unsigned num_nodes, 00068 const vcl_vector<mmn_arc>& arcs); 00069 00070 //: Define dependencies 00071 void set_dependancies(const vcl_vector<mmn_dependancy>& deps, 00072 unsigned n_nodes, unsigned max_n_arcs); 00073 00074 //: Read access to dependencies 00075 const vcl_vector<mmn_dependancy>& deps() const { return deps_; } 00076 00077 //: Find values for each node with minimise the total cost 00078 // \param node_cost: node_cost[i][j] is cost of selecting value j for node i 00079 // \param pair_cost: pair_cost[a](i,j) is cost of selecting values (i,j) for nodes at end of arc a. 00080 // \param x: On exit, x[i] gives choice for node i 00081 // NOTE: If arc a connects nodes v1,v2, the associated pair_cost is ordered 00082 // with the node with the lowest index being the first parameter. Thus if 00083 // v1 has value i1, v2 has value i2, then the cost of this choice is 00084 // (v1<v2?pair_cost(i1,i2):pair_cost(i2,i1)) 00085 // Returns the minimum cost 00086 virtual double solve(const vcl_vector<vnl_vector<double> >& node_cost, 00087 const vcl_vector<vnl_matrix<double> >& pair_cost, 00088 vcl_vector<unsigned>& x); 00089 00090 //: Find values for each node with minimise the total cost 00091 // As solve(node_cost,pair_cost,x), but allows inclusion of 00092 // costs for triplets (ie when v0 depends on v1 and v2). 00093 // tri_cost(i,j,k) gives cost of node min(v0,v1,v2) being 00094 // value i, node mid(v0,v1,v2) being value j and 00095 // node max(v0,v1,v2) being value k. 00096 double solve(const vcl_vector<vnl_vector<double> >& node_cost, 00097 const vcl_vector<vnl_matrix<double> >& pair_cost, 00098 const vcl_vector<vil_image_view<double> >& tri_cost, 00099 vcl_vector<unsigned>& x); 00100 00101 //: Compute optimal values for x[i] given that root node is root_value 00102 // Assumes that solve() has been already called. 00103 void backtrace(unsigned root_value,vcl_vector<unsigned>& x); 00104 00105 //: root_cost()[i] is cost of selecting value i for the root node 00106 const vnl_vector<double>& root_cost() const { return nc_[root()]; } 00107 00108 //: Initialise from a text stream 00109 virtual bool set_from_stream(vcl_istream &is); 00110 00111 //: Version number for I/O 00112 short version_no() const; 00113 00114 //: Name of the class 00115 virtual vcl_string is_a() const; 00116 00117 //: Create a copy on the heap and return base class pointer 00118 virtual mmn_solver* clone() const; 00119 00120 //: Print class to os 00121 virtual void print_summary(vcl_ostream& os) const; 00122 00123 //: Save class to binary file stream 00124 virtual void b_write(vsl_b_ostream& bfs) const; 00125 00126 //: Load class from binary file stream 00127 virtual void b_read(vsl_b_istream& bfs); 00128 }; 00129 00130 #endif // mmn_dp_solver_h_