Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

mmn_graph_rep1.cxx

Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \brief Representation of a graph, stored by links at each node.
00004 // \author Tim Cootes
00005 
00006 #include <mmn/mmn_graph_rep1.h>
00007 
00008   //: Default constructor
00009 mmn_graph_rep1::mmn_graph_rep1()
00010   : max_n_arcs_(0), n_arcs_(0)
00011 {
00012 }
00013 
00014   //: Build from list of arcs
00015 void mmn_graph_rep1::build(unsigned n_nodes,
00016                            const vcl_vector<mmn_arc>& arcs)
00017 {
00018   node_data_.resize(n_nodes);
00019   for (unsigned i=0;i<n_nodes;++i) node_data_[i].resize(0);
00020 
00021   for (unsigned i=0;i<arcs.size();++i)
00022   {
00023     node_data_[arcs[i].v1].push_back(vcl_pair<unsigned,unsigned>(arcs[i].v2,i));
00024     node_data_[arcs[i].v2].push_back(vcl_pair<unsigned,unsigned>(arcs[i].v1,i));
00025   }
00026 
00027   max_n_arcs_ = arcs.size();
00028   n_arcs_ = arcs.size();
00029 }
00030 
00031 //: Return index of arc between v1 and v2, or -1 if none
00032 int mmn_graph_rep1::arc_index(unsigned v1, unsigned v2) const
00033 {
00034   const vcl_vector<vcl_pair<unsigned,unsigned> >& nd = node_data_[v1];
00035   for (unsigned i=0;i<nd.size();++i)
00036     if (nd[i].first==v2) return nd[i].second;
00037   return -1;
00038 }
00039 
00040 //: Return index of arc between v1 and v2, creating one if none exists
00041 unsigned mmn_graph_rep1::get_arc(unsigned v1, unsigned v2)
00042 {
00043   int a = arc_index(v1,v2);
00044   if (a>=0) return a;
00045 
00046   // No existing arc, so add one.
00047   a = max_n_arcs_;
00048   node_data_[v1].push_back(vcl_pair<unsigned,unsigned>(v2,a));
00049   node_data_[v2].push_back(vcl_pair<unsigned,unsigned>(v1,a));
00050   max_n_arcs_++;
00051   n_arcs_++;
00052   return a;
00053 }
00054 
00055 #if 0
00056 //: Remove record of arc between v1 and v2
00057 //  Returns false if there isn't one.
00058 bool mmn_graph_rep1::remove_arc(unsigned v1, unsigned v2)
00059 {
00060 }
00061 #endif // 0
00062 
00063 //: Remove record of arc v1-v2 from v1
00064 void mmn_graph_rep1::remove_arc_from_node(unsigned v1, unsigned v2)
00065 {
00066   vcl_vector<vcl_pair<unsigned,unsigned> >& nd = node_data_[v1];
00067   vcl_vector<vcl_pair<unsigned,unsigned> >::iterator ndi;
00068   for (ndi=nd.begin();ndi!=nd.end();++ndi)
00069     if (ndi->first==v2)
00070     {
00071       nd.erase(ndi);
00072       break;
00073     }
00074 }
00075 
00076 
00077 //: Remove some of leaves of graph, recording dependencies
00078 //  A leaf node is one with only one arc
00079 //  For each leaf node removed, add one dependency object to
00080 //  the deps list.
00081 //  Returns number of leaves removed.
00082 unsigned mmn_graph_rep1::remove_leaves(vcl_vector<mmn_dependancy>& deps)
00083 {
00084   unsigned n_removed = 0;
00085   for (unsigned v1=0;v1<node_data_.size();++v1)
00086   {
00087     if (node_data_[v1].size()==1)
00088     {
00089       // v1 is a leaf node, connected to node_data_[v1][0].first
00090       unsigned v2 = node_data_[v1][0].first;
00091       unsigned arc12 = node_data_[v1][0].second;
00092 
00093       // Record dependency
00094       deps.push_back(mmn_dependancy(v1,v2,arc12));
00095       n_removed++;
00096 
00097       // Remove the record of the arc from v1
00098       node_data_[v1].resize(0);
00099       // Remove the record of the arc from v2
00100       remove_arc_from_node(v2,v1);
00101 
00102       n_arcs_--;
00103       if (n_arcs_==0) break;
00104     }
00105   }
00106 
00107   return n_removed;
00108 }
00109 
00110 //: Remove all of leaves of graph, recording dependencies
00111 //  A leaf node is one with only one arc
00112 //  For each leaf node removed, add one dependency object to
00113 //  the deps list.  On exit, this graph has no leaves.
00114 //  Returns number of leaves removed.
00115 unsigned mmn_graph_rep1::remove_all_leaves(vcl_vector<mmn_dependancy>& deps)
00116 {
00117   unsigned n_removed=0;
00118   unsigned nr=0;
00119   do
00120   {
00121     nr=remove_leaves(deps);
00122     n_removed+=nr;
00123   } while (nr!=0);
00124 
00125   return n_removed;
00126 }
00127 
00128 //: Remove arcs from some of the nodes with two neighbours
00129 //  Record the pairwise dependencies.
00130 //  For each node removed, add one dependency object to
00131 //  the deps list.
00132 //  Returns number of removed.
00133 unsigned mmn_graph_rep1::remove_pair_deps(vcl_vector<mmn_dependancy>& deps)
00134 {
00135   unsigned n_removed = 0;
00136   for (unsigned v0=0;v0<node_data_.size();++v0)
00137   {
00138     if (node_data_[v0].size()==2)
00139     {
00140       // v0 has two neighbours,
00141       // node_data_[v0][0].first and node_data_[v0][1].first
00142       unsigned v1 = node_data_[v0][0].first;
00143       unsigned arc1 = node_data_[v0][0].second;
00144       unsigned v2 = node_data_[v0][1].first;
00145       unsigned arc2 = node_data_[v0][1].second;
00146 
00147       // Find arc between v1-v2, or create one if necessary
00148       unsigned arc12 = get_arc(v1,v2);
00149 
00150       // Record dependency
00151       deps.push_back(mmn_dependancy(v0,v1,v2,arc1,arc2,arc12));
00152       n_removed++;
00153 
00154       // Remove the record of the arcs from v0
00155       node_data_[v0].resize(0);
00156       // Remove the record of the arc from v1
00157       remove_arc_from_node(v1,v0);
00158       // Remove the record of the arc from v2
00159       remove_arc_from_node(v2,v0);
00160 
00161       n_arcs_-=2;
00162       if (n_arcs_<2) break;
00163     }
00164   }
00165 
00166   return n_removed;
00167 }
00168 
00169 //: Compute list of all single and pairwise dependencies
00170 //  Return true if graph can be fully decomposed in this way
00171 bool mmn_graph_rep1::compute_dependancies(vcl_vector<mmn_dependancy>& deps)
00172 {
00173   deps.resize(0);
00174   unsigned nr1=0;
00175   do
00176   {
00177     nr1=remove_all_leaves(deps);
00178     if (n_arcs_>1)
00179       nr1+=remove_pair_deps(deps);
00180   }
00181   while (nr1>0 && n_arcs_>0);
00182 
00183   return n_arcs_==0;
00184 }
00185 

Generated on Thu Jan 10 14:44:52 2008 for contrib/mul/mmn by  doxygen 1.4.4