Go to the documentation of this file.00001 #include "mmn_csp_solver.h"
00002
00003
00004
00005
00006
00007 #include <vcl_algorithm.h>
00008 #include <vcl_cassert.h>
00009
00010
00011 mmn_csp_solver::mmn_csp_solver():nnodes_(0),verbose_(false)
00012 {
00013 init();
00014 }
00015
00016
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
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
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
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;
00114
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 }
00157
00158 if (!found)
00159 {
00160
00161
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 }
00177 }
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)
00206 {
00207 deleted=true;
00208
00209 vcl_pair<unsigned,unsigned > pair2(linkIter->first,linkIter->second);
00210
00211 labels_linked1.erase(linkIter++);
00212
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
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 }