contrib/mul/mmn/mmn_csp_solver.cxx
Go to the documentation of this file.
00001 #include "mmn_csp_solver.h"
00002 //:
00003 // \file
00004 // \brief see if the Constraint Satisfaction Problem is satisfiable
00005 // \author Martin Roberts
00006 
00007 #include <vcl_algorithm.h>
00008 #include <vcl_cassert.h>
00009 
00010 //: Default constructor
00011 mmn_csp_solver::mmn_csp_solver():nnodes_(0),verbose_(false)
00012 {
00013     init();
00014 }
00015 
00016 //: Construct with arcs
00017 mmn_csp_solver::mmn_csp_solver(unsigned num_nodes,const vcl_vector<mmn_arc>& arcs):
00018         nnodes_(num_nodes),verbose_(false)
00019 {
00020     init();
00021     set_arcs(num_nodes,arcs);
00022 }
00023 
00024 void mmn_csp_solver::init()
00025 {
00026 }
00027 
00028 //: Pass in the arcs, which are then used to build the graph object
00029 void mmn_csp_solver::set_arcs(unsigned num_nodes,const vcl_vector<mmn_arc>& arcs)
00030 {
00031     nnodes_=num_nodes;
00032     arcs_ = arcs;
00033     //Verify consistency
00034     unsigned max_node=0;
00035     for (unsigned i=0; i<arcs.size();++i)
00036     {
00037         max_node=vcl_max(max_node,arcs[i].max_v());
00038     }
00039     if (nnodes_ != max_node+1)
00040     {
00041         vcl_cerr<<"Arcs appear to be inconsistent with number of nodes in mmn_csp_solver::set_arcs\n"
00042                 <<"Max node in Arcs is: "<<max_node<<" but number of nodes= "<<nnodes_ << '\n';
00043     }
00044 
00045     graph_.build(nnodes_,arcs_);
00046 }
00047 
00048 
00049 //: Run the algorithm
00050 bool mmn_csp_solver::operator()(const vcl_vector<mmn_csp_solver::label_subset_t >& node_labels_subset,
00051                                 const vcl_vector<mmn_csp_solver::arc_labels_subset_t >& links_subset)
00052 {
00053     init();
00054 
00055     node_labels_present_ = node_labels_subset;
00056     initialise_arc_labels_linked(links_subset);
00057 
00058 
00059     bool deletedNode=false;
00060     bool deletedArc=false;
00061 
00062     do
00063     {
00064         deletedNode = check_for_node_deletions();
00065         deletedArc = check_for_arc_deletions();
00066     }
00067     while (deletedNode || deletedArc);
00068 
00069     bool emptyKernel=true;
00070 
00071     for (unsigned i=0; i<nnodes_;i++)
00072     {
00073         emptyKernel = emptyKernel && node_labels_present_[i].empty();
00074     }
00075 
00076     return !emptyKernel;
00077 }
00078 
00079 void  mmn_csp_solver::initialise_arc_labels_linked(const vcl_vector<mmn_csp_solver::arc_labels_subset_t >& links_subset)
00080 {
00081     arc_labels_linked1_.clear();
00082     arc_labels_linked2_.clear();
00083     unsigned narcs=arcs_.size();
00084     arc_labels_linked1_.resize(narcs);
00085     arc_labels_linked2_.resize(narcs);
00086 
00087     for (unsigned iarc=0;iarc<narcs;++iarc)
00088     {
00089         arc_labels_subset_t1& labels_linked1=arc_labels_linked1_[iarc];
00090         arc_labels_subset_t2& labels_linked2=arc_labels_linked2_[iarc];
00091 
00092         arc_labels_subset_t::const_iterator linkIter=links_subset[iarc].begin();
00093         arc_labels_subset_t::const_iterator linkIterEnd=links_subset[iarc].end();
00094         while (linkIter != linkIterEnd)
00095         {
00096             labels_linked1.insert(*linkIter);
00097             labels_linked2.insert(*linkIter);
00098             ++linkIter;
00099         }
00100     }
00101 }
00102 
00103 bool mmn_csp_solver::check_for_node_deletions()
00104 {
00105     bool deleted=false;
00106     for (unsigned inode=0;inode<nnodes_;++inode)
00107     {
00108         vcl_set<unsigned>::iterator labelIter=node_labels_present_[inode].begin();
00109         vcl_set<unsigned>::iterator labelIterEnd=node_labels_present_[inode].end();
00110         const vcl_vector<vcl_pair<unsigned,unsigned> >& neighbourhood = graph_.node_data()[inode];
00111         while (labelIter != labelIterEnd)
00112         {
00113             unsigned label = *labelIter; //this label value
00114             //Now loop over all arcs in the node's neighbourhood
00115             vcl_vector<vcl_pair<unsigned,unsigned> >::const_iterator neighIter=neighbourhood.begin();
00116             vcl_vector<vcl_pair<unsigned,unsigned> >::const_iterator neighIterEnd=neighbourhood.end();
00117             bool found=true;
00118             while (neighIter != neighIterEnd)
00119             {
00120                 bool foundThisNeighbour=false;
00121                 unsigned arcId=neighIter->second;
00122                 if (inode<neighIter->first)
00123                 {
00124                     vcl_pair<unsigned ,unsigned > sought(label,0);
00125                     arc_labels_subset_t1::const_iterator linkIter=arc_labels_linked1_[arcId].lower_bound(sought);
00126                     if (linkIter != arc_labels_linked1_[arcId].end())
00127                     {
00128                         if (linkIter->first==label)
00129                         {
00130                             foundThisNeighbour=true;
00131                         }
00132                     }
00133                 }
00134                 else
00135                 {
00136                     vcl_pair<unsigned ,unsigned > sought(0,label);
00137                     arc_labels_subset_t2::const_iterator linkIter=arc_labels_linked2_[arcId].lower_bound(sought);
00138                     if (linkIter != arc_labels_linked2_[arcId].end())
00139                     {
00140                         if (linkIter->second==label)
00141                         {
00142                             foundThisNeighbour=true;
00143                         }
00144                     }
00145                 }
00146                 found = found && foundThisNeighbour;
00147                 if (!foundThisNeighbour)
00148                 {
00149                     if (verbose_)
00150                     {
00151                         vcl_cout<<"Found no arc linking labels for node "<<inode<<" label "<<label<<" to node "<<neighIter->first<<"along arc ID "<<arcId<<vcl_endl;
00152                     }
00153                     break;
00154                 }
00155                 ++neighIter;
00156             } //loop over all neighbours (pencils)
00157 
00158             if (!found)
00159             {
00160                 //Found no links from this label to anywhere
00161                 //So delete it
00162                 vcl_set<unsigned>::iterator labelIterNext=labelIter;
00163                 ++labelIterNext;
00164                 if (verbose_)
00165                 {
00166                     vcl_cout<<"Have removed label "<<*labelIter<<" for node "<<inode<<" as it has no linking arcs"<<vcl_endl;
00167                 }
00168                 node_labels_present_[inode].erase(labelIter);
00169                 labelIter=labelIterNext;
00170                 deleted=true;
00171             }
00172             else
00173             {
00174                 ++labelIter;
00175             }
00176         } //next label of this node (object)
00177     } //next node (object)
00178     return deleted;
00179 }
00180 
00181 bool mmn_csp_solver::check_for_arc_deletions()
00182 {
00183     bool deleted=false;
00184     for (unsigned iarc=0;iarc<arcs_.size();++iarc)
00185     {
00186         arc_labels_subset_t1& labels_linked1=arc_labels_linked1_[iarc];
00187         arc_labels_subset_t2& labels_linked2=arc_labels_linked2_[iarc];
00188         arc_labels_subset_t1::iterator linkIter=labels_linked1.begin();
00189         arc_labels_subset_t1::iterator linkIterEnd=labels_linked1.end();
00190         while (linkIter != linkIterEnd)
00191         {
00192             unsigned label1=linkIter->first;
00193             unsigned label2=linkIter->second;
00194             unsigned node1=arcs_[iarc].min_v();
00195             unsigned node2=arcs_[iarc].max_v();
00196             assert(node1<node2);
00197             vcl_set<unsigned>& labelSet1=node_labels_present_[node1];
00198 
00199             bool found=false;
00200             if (labelSet1.find(label1)!=labelSet1.end())
00201             {
00202                 vcl_set<unsigned>& labelSet2=node_labels_present_[node2];
00203                 found = labelSet2.find(label2)!=labelSet2.end();
00204             }
00205             if (!found) //failed to find at least one of target labels
00206             {
00207                 deleted=true;
00208                 //vcl_pair<unsigned,unsigned > pair2(linkIter->second,linkIter->first); //transpose
00209                 vcl_pair<unsigned,unsigned > pair2(linkIter->first,linkIter->second); //transpose
00210 
00211                 labels_linked1.erase(linkIter++); //remove from multset 1
00212                 //Find all possible instances in multiset 2 for removal
00213                 vcl_pair<arc_labels_subset_t2::iterator,arc_labels_subset_t2::iterator> range=
00214                     labels_linked2.equal_range(pair2);
00215                 arc_labels_subset_t2::iterator killer=range.first;
00216 
00217                 while (killer != range.second)
00218                 {
00219                     if (killer->first==pair2.first)
00220                     {
00221                         //remove target link
00222                         labels_linked2.erase(killer++);
00223                         if (verbose_)
00224                         {
00225                             vcl_cout<<"Have removed arc Id "<<iarc<<" Linking nodes "<<node1<<'\t'<<node2
00226                                     <<" for respective labels "<<pair2.second<<'\t'<<pair2.first<<vcl_endl;
00227                         }
00228                     }
00229                     else
00230                     {
00231                         ++killer;
00232                     }
00233                 }
00234             }
00235             else
00236             {
00237                 ++linkIter;
00238             }
00239         }
00240     }
00241     return deleted;
00242 }