contrib/mul/mbl/mbl_minimum_spanning_tree.cxx
Go to the documentation of this file.
00001 #include "mbl_minimum_spanning_tree.h"
00002 //:
00003 // \file
00004 #include <vnl/vnl_matrix.h>
00005 #include <vnl/vnl_vector.h> // for vnl_matrix<double>::get_row()
00006 #include <vcl_algorithm.h>
00007 
00008 //: Select the smallest pair s.t. first is in \param a, second in \param b
00009 static vcl_pair<unsigned,unsigned> mbl_mst_next_pair(
00010                                            const vnl_matrix<double>& D,
00011                                            const vcl_vector<unsigned>& a,
00012                                            const vcl_vector<unsigned>& b)
00013 {
00014   vcl_pair<unsigned,unsigned> p;
00015   double min_sim = 9.9e9;
00016   for (unsigned i=0; i<a.size(); ++i)
00017     for (unsigned j=0; j<b.size(); ++j)
00018     {
00019       double s = D(a[i],b[j]);
00020       if (s<min_sim)
00021       {
00022         min_sim=s;
00023         p.first=a[i];
00024         p.second=b[j];
00025       }
00026     }
00027   return p;
00028 }
00029 
00030 //: Compute the minimum spanning tree given a distance matrix
00031 //  \param pairs[0].first is the root node
00032 //  Tree defined by pairs.
00033 //  \param pairs[i].second is linked to \param pairs[i].first
00034 //  We compute the minimum spanning tree of the graph using Prim's algorithm.
00035 void mbl_minimum_spanning_tree(const vnl_matrix<double>& D,
00036                                vcl_vector<vcl_pair<int,int> >& pairs)
00037 {
00038   unsigned n = D.rows();
00039   vcl_vector<unsigned> a(0),b(n);
00040   for (unsigned i=0;i<n;++i) b[i]=i;
00041   // Select element closest to all others on average
00042   double min_sum=9e9;
00043   unsigned best_i=0;
00044   for (unsigned i=0;i<n;++i)
00045   {
00046     double sum = D.get_row(i).sum();
00047     if (sum<min_sum) { min_sum=sum; best_i=i; }
00048   }
00049   b.erase(vcl_find(b.begin(),b.end(),best_i));
00050   a.push_back(best_i);
00051 
00052   for (unsigned i=1;i<n;++i)
00053   {
00054     vcl_pair<unsigned,unsigned> p = mbl_mst_next_pair(D,a,b);
00055     pairs.push_back(p);
00056     b.erase(vcl_find(b.begin(),b.end(),p.second));
00057     a.push_back(p.second);
00058   }
00059 }
00060 
00061 //: Compute the minimum spanning tree of given points
00062 // \param  pairs[0].first is the root node
00063 //  Tree defined by pairs.
00064 //  \param pairs[i].second is linked to \param pairs[i].first
00065 //  We compute the minimum spanning tree of the graph using Prim's algorithm.
00066 void mbl_minimum_spanning_tree(const vcl_vector<vgl_point_2d<double> >& pts,
00067                                vcl_vector<vcl_pair<int,int> >& pairs)
00068 {
00069   unsigned n=pts.size();
00070   vnl_matrix<double> D(n,n);
00071   for (unsigned i=0;i<n;++i) D(i,i)=0.0;
00072   for (unsigned i=1;i<n;++i)
00073     for (unsigned j=0;j<i;++j)
00074     {
00075       D(i,j) = (pts[i]-pts[j]).length();
00076       D(j,i) = D(i,j);
00077     }
00078 
00079   mbl_minimum_spanning_tree(D,pairs);
00080 }
00081 
00082 //: Compute the minimum spanning tree of given points
00083 //  \param pairs[0].first is the root node
00084 //  Tree defined by pairs.
00085 //  \param pairs[i].second is linked to \param pairs[i].first
00086 //  We compute the minimum spanning tree of the graph using Prim's algorithm.
00087 void mbl_minimum_spanning_tree(const vcl_vector<vgl_point_3d<double> >& pts,
00088                                vcl_vector<vcl_pair<int,int> >& pairs)
00089 {
00090   unsigned n=pts.size();
00091   vnl_matrix<double> D(n,n);
00092   for (unsigned i=0;i<n;++i) D(i,i)=0.0;
00093   for (unsigned i=1;i<n;++i)
00094     for (unsigned j=0;j<i;++j)
00095     {
00096       D(i,j) = (pts[i]-pts[j]).length();
00097       D(j,i) = D(i,j);
00098     }
00099 
00100   mbl_minimum_spanning_tree(D,pairs);
00101 }