00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _GRAPH_EVAT_H_
00021 #define _GRAPH_EVAT_H_
00022
00023 using namespace std;
00024
00025 template <template <typename> class ALLOC_ >
00026 class evat;
00027
00028 template <template <typename> class ALLOC >
00029 ostream& operator<< (ostream& ostr, const evat<ALLOC>& ev);
00030
00035 template <template <typename> class ALLOC_=std::allocator >
00036 class evat
00037 {
00038 public:
00039 typedef pair<int, int> VID_PAIR;
00040 typedef vector<VID_PAIR, ALLOC_<VID_PAIR> > EVAT;
00042 typedef typename EVAT::const_iterator CONST_IT;
00043 typedef typename EVAT::iterator IT;
00044
00045 evat() {}
00046
00047 IT begin() {
00048 return _evat.begin();
00049 }
00050 CONST_IT begin() const {
00051 return _evat.begin();
00052 }
00053 IT end() {
00054 return _evat.end();
00055 }
00056 CONST_IT end() const {
00057 return _evat.end();
00058 }
00059
00060 friend ostream& operator<< <> (ostream&, const evat<ALLOC_ >&);
00061
00062 unsigned long int byte_size() const{
00063 return 2*sizeof(int)*_evat.size();
00064 }
00065
00066 void write_file(ostream & output) const{
00067 CONST_IT it;
00068 int ITSZ=sizeof(int);
00069 for(it=begin(); it!=end(); ++it){
00070 output.write(reinterpret_cast<const char *>(&it->first), ITSZ);
00071 output.write(reinterpret_cast<const char *>(&it->second), ITSZ);
00072 }
00073 }
00074
00075 void print(){
00076 CONST_IT it;
00077 int ITSZ=sizeof(int);
00078 cout << "Evat: " << endl;
00079 for(it=begin(); it!=end(); ++it){
00080 cout << it->first << " " << it->second << endl;
00081 }
00082 }
00083
00084 void read_file(istream & input, unsigned long int size){
00085
00086 }
00087
00088 VID_PAIR& operator[] (const int& i) {
00089 return _evat[i];
00090 }
00091
00092 const VID_PAIR& operator[] (const int& i) const {
00093 return _evat[i];
00094 }
00095
00096 void push_back(const pair<int, int>& ids) {
00097 _evat.push_back(ids);
00098 }
00099
00100 bool empty() const {
00101 return _evat.empty();
00102 }
00103
00104 int size() const {
00105 return _evat.size();
00106 }
00107
00111 template<template<typename, typename> class VAT_ST, typename VAT, template <typename> class ALLOC >
00112 static void fwd_intersect(const VAT& vat_v1, const evat& evat_v1, const evat& evat_v2,
00113 VAT& cand_vat, bool is_fwd_chain, const int& rmp_index,
00114 const int& new_edge_state, const int& tid, bool l2_eq) {
00115 #ifdef PRINT
00116 cout<<"In evat::fwd_intersect with is_fwd_chain="<<is_fwd_chain<<" rmp_index="<<rmp_index<<" new_edge_state="<<new_edge_state<<" tid="<<tid<<endl;
00117 cout<<"evat_v1.size="<<evat_v1.size()<<" evat_v2.size()="<<evat_v2.size()<<endl;
00118 #endif
00119
00120 CONST_IT it_evat_v1, it_evat_v2;
00121 const VAT_ST<typename VAT::VSET, ALLOC<typename VAT::VSET> >& v1_vids=vat_v1._vids[tid];
00122 const pair<int, VAT_ST<evat, ALLOC<evat> > >& v1=vat_v1._vat[tid];
00123
00124
00125
00126 int offset_v1;
00127
00128 bool swap_vids;
00129
00130 bool l2_swap=0;
00131
00132
00133 for(it_evat_v1=evat_v1.begin(), offset_v1=0; it_evat_v1!=evat_v1.end(); it_evat_v1++, offset_v1++) {
00134 #ifdef PRINT
00135 cout<<"evat_v1="<<it_evat_v1->first<<" "<<it_evat_v1->second<<endl;
00136 #endif
00137 for(it_evat_v2=evat_v2.begin(); it_evat_v2!=evat_v2.end(); it_evat_v2++) {
00138 #ifdef PRINT
00139 cout<<"evat_v2="<<it_evat_v2->first<<" "<<it_evat_v2->second<<endl;
00140 #endif
00141
00147
00148 if(!new_edge_state) {
00149 if(l2_eq) {
00150
00151
00152
00153 if(it_evat_v1->second==it_evat_v2->first) {
00154 swap_vids=0;
00155 l2_swap=0;
00156 }
00157 else if(it_evat_v1->second==it_evat_v2->second) {
00158 swap_vids=1;
00159 l2_swap=0;
00160 }
00161 else if(it_evat_v1->first==it_evat_v2->first) {
00162 swap_vids=0;
00163 l2_swap=1;
00164 }
00165 else if(it_evat_v1->first==it_evat_v2->second) {
00166 swap_vids=1;
00167 l2_swap=1;
00168 }
00169 else
00170 continue;
00171 }
00172 else {
00173 if(is_fwd_chain) {
00174 if(it_evat_v1->second!=it_evat_v2->first)
00175 if(it_evat_v1->second!=it_evat_v2->second)
00176 continue;
00177 else
00178 swap_vids=1;
00179 else
00180 swap_vids=0;
00181 }
00182 else {
00183 if(it_evat_v1->first!=it_evat_v2->first)
00184 if(it_evat_v1->first!=it_evat_v2->second)
00185 continue;
00186 else
00187 swap_vids=1;
00188 else
00189 swap_vids=0;
00190 }
00191 }
00192 }
00193 else {
00194 swap_vids=new_edge_state-1;
00195
00196
00197 if(l2_eq) {
00198 if(!swap_vids) {
00199 if(it_evat_v1->first!=it_evat_v2->first)
00200 if(it_evat_v1->second!=it_evat_v2->first)
00201 continue;
00202 else
00203 l2_swap=0;
00204 else
00205 l2_swap=1;
00206 }
00207 else {
00208 if(it_evat_v1->first!=it_evat_v2->second)
00209 if(it_evat_v1->second!=it_evat_v2->second)
00210 continue;
00211 else
00212 l2_swap=0;
00213 else
00214 l2_swap=1;
00215 }
00216 }
00217 else {
00218 if(is_fwd_chain) {
00219 if(swap_vids && it_evat_v1->second!=it_evat_v2->second)
00220 continue;
00221 if(!swap_vids && it_evat_v1->second!=it_evat_v2->first)
00222 continue;
00223 }
00224 else {
00225 if(swap_vids) {
00226 cerr<<"evat.fwd_intersect: swap_vids="<<swap_vids<<" for !fwd_chain. This candidate should not have been canonical"<<endl;
00227 return;
00228 }
00229 if(it_evat_v1->first!=it_evat_v2->first)
00230 continue;
00231 }
00232 }
00233 }
00234
00235 if(!swap_vids) {
00236 if(!vat_v1.is_new_vertex(it_evat_v2->second, tid, offset_v1))
00237 continue;
00238 }
00239 else
00240 if(!vat_v1.is_new_vertex(it_evat_v2->first, tid, offset_v1))
00241 continue;
00242 #ifdef PRINT
00243 cout<<"evat::fwd_intersect: valid fwd extension"<<endl;
00244 #endif
00246 // first append common evats from v1's rmp
00247 if(!cand_vat.empty() && cand_vat.back().first==v1.first) {
00248 if(rmp_index>0)
00249 cand_vat.copy_vats(v1, offset_v1, rmp_index, l2_swap);
00250 cand_vat.copy_vids_hs(v1_vids[offset_v1]);
00251 }
00252 else {
00253 if(rmp_index>0)
00254 cand_vat.copy_vats_tid(v1, offset_v1, rmp_index, l2_swap);
00255 cand_vat.copy_vids_tid(v1_vids[offset_v1]);
00256 }
00257
00258 #ifdef PRINT
00259 cout<<"evat::fwd_intersect: appending new_occurrence"<<endl;
00260 #endif
00261 pair<int, int> new_occurrence;
00262 if(!l2_eq)
00263 new_occurrence.first=(is_fwd_chain?it_evat_v1->second: it_evat_v1->first);
00264 else
00265 new_occurrence.first=(!l2_swap?it_evat_v1->second: it_evat_v1->first);
00266 new_occurrence.second=(swap_vids?it_evat_v2->first: it_evat_v2->second);
00267
00268
00269 if(!is_fwd_chain) {
00270 if(!cand_vat.empty() && cand_vat.back().first==v1.first) {
00271 #ifdef PRINT
00272 cout<<"!fwd_chain, same tid"<<endl;
00273 #endif
00274 cand_vat.insert_occurrence(new_occurrence);
00275 cand_vat.insert_vid(new_occurrence.first);
00276 cand_vat.insert_vid(new_occurrence.second);
00277 }
00278 else {
00279 #ifdef PRINT
00280 cout<<"!fwd_chain, new tid"<<endl;
00281 #endif
00282 cand_vat.insert_occurrence_tid(v1.first, new_occurrence);
00283 cand_vat.insert_vid(new_occurrence.first);
00284 cand_vat.insert_vid(new_occurrence.second);
00285 }
00286 }
00287 else {
00288
00289 if(cand_vat.back().second.size()==(unsigned) rmp_index) {
00290
00291 #ifdef PRINT
00292 cout<<"fwd_chain, new evat"<<endl;
00293 #endif
00294 cand_vat.insert_occurrence_evat(new_occurrence);
00295 cand_vat.insert_vid(new_occurrence.first);
00296 cand_vat.insert_vid(new_occurrence.second);
00297 }
00298 else {
00299 #ifdef PRINT
00300 cout<<"fwd_chain, new occurrence"<<endl;
00301 #endif
00302 cand_vat.insert_occurrence(new_occurrence);
00303 cand_vat.insert_vid(new_occurrence.first);
00304 cand_vat.insert_vid(new_occurrence.second);
00305 }
00306 }
00307 }
00308 }
00309 }
00310
00311
00314 template<template<typename, typename> class VAT_ST, typename VAT, template <typename> class ALLOC>
00315 static void back_intersect(const VAT& vat_v1, const evat& evat_v1, const evat& evat_v2, VAT& cand_vat,
00316 const int& back_idx, const int& new_edge_state, const int& tid) {
00317 #ifdef PRINT
00318 cout<<"evat.back_intersect entered with back_idx="<<back_idx<<" "<<"new_edge_stat="<<new_edge_state<<" tid="<<tid<<endl;
00319 #endif
00320 const VAT_ST<typename VAT::VSET, ALLOC<typename VAT::VSET> >& v1_vids=vat_v1._vids[tid];
00321 const pair<int, VAT_ST<evat, ALLOC<evat> > >& v1=vat_v1._vat[tid];
00322 CONST_IT it_evat_v1, it_evat_v2;
00323
00324 int offset_v1;
00325
00326 bool swap_vids;
00327
00328
00329 for(it_evat_v1=evat_v1.begin(), offset_v1=0; it_evat_v1!=evat_v1.end(); it_evat_v1++, offset_v1++)
00330 for(it_evat_v2=evat_v2.begin(); it_evat_v2!=evat_v2.end(); it_evat_v2++) {
00332
00333 if(!new_edge_state) {
00334 if(it_evat_v1->second!=it_evat_v2->first)
00335 if(it_evat_v1->second!=it_evat_v2->second)
00336 continue;
00337 else
00338 swap_vids=1;
00339 else
00340 swap_vids=0;
00341 }
00342 else {
00343 swap_vids=new_edge_state-1;
00344
00345
00346 if(!swap_vids && it_evat_v1->second!=it_evat_v2->first)
00347 continue;
00348 if(swap_vids && it_evat_v1->second!=it_evat_v2->second)
00349 continue;
00350 }
00351
00352
00353 if(!swap_vids && v1.second[back_idx][offset_v1].first!=it_evat_v2->second)
00354 continue;
00355 if(swap_vids && v1.second[back_idx][offset_v1].first!=it_evat_v2->first)
00356 continue;
00357
00358
00359
00360
00361 if(!cand_vat.empty() && cand_vat.back().first==v1.first) {
00362
00363 cand_vat.copy_vats(v1, offset_v1, v1.second.size());
00364 cand_vat.copy_vids_hs(v1_vids[offset_v1]);
00365 }
00366 else {
00367
00368 cand_vat.copy_vats_tid(v1, offset_v1, v1.second.size());
00369 cand_vat.copy_vids_tid(v1_vids[offset_v1]);
00370 }
00371 }
00372 }
00373
00374 private:
00375 EVAT _evat;
00376 };
00377
00378 template <template <typename> class ALLOC >
00379 ostream& operator<< (ostream& ostr, const evat<ALLOC>& ev) {
00380 typename evat<ALLOC>::CONST_IT it;
00381 for(it=ev.begin(); it!=ev.end(); it++)
00382 ostr<<it->first<<","<<it->second<<" ";
00383 return ostr;
00384 }
00385
00386 #endif