00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef CandGenInfreqRemoveNopruneMerge_HPP
00010 #define CandGenInfreqRemoveNopruneMerge_HPP
00011
00017 #include "common.hpp"
00018 #include "common/Edge.hpp"
00019 #include "common/log.h"
00020 #include "apriori/bodon/dynamic_trie/trie_manipulators/CandidateGeneratorNoprune.hpp"
00021 #include <vector>
00022
00023
00024
00025
00026
00027
00028 namespace Bodon
00029 {
00030 namespace dynamic_trie
00031 {
00032 template <class DF_D, class TRIE_OEL, class TRIE_OI, class LEAF,
00033 class LEAF_ALLOCATOR, NEELevel NEE>
00034 class CandGenInfreqRemoveNopruneMerge :
00035 public CandidateGeneratorNoprune<
00036 DF_D, TRIE_OEL, TRIE_OI, LEAF, LEAF_ALLOCATOR, NEE>
00037 {
00038 private:
00039 typedef CandidateGeneratorNoprune<
00040 DF_D, TRIE_OEL, TRIE_OI, LEAF, LEAF_ALLOCATOR, NEE> PARENT;
00041 protected:
00042 unsigned int nr_of_deleted;
00043 unsigned int total_nr_of_deleted;
00044 unsigned int nr_of_prefix_equiitem;
00045 unsigned int total_nr_of_prefix_equiitem;
00046
00047 public:
00048 static unsigned int total_nr_of_candidates;
00049 CandGenInfreqRemoveNopruneMerge(
00050 TRIE_OEL& main_trie, DF_D& df_decoder, LEAF_ALLOCATOR& s_alloc ) :
00051 PARENT(main_trie, df_decoder, s_alloc), total_nr_of_deleted(0),
00052 total_nr_of_prefix_equiitem(0){}
00053
00054 void generateCandidate(unsigned int candidate_size);
00055
00056 void deleteInfrequent( const counter_t min_supp,
00057 unsigned int candidate_size );
00058 void afterWorkDel();
00059 protected:
00060
00061
00062
00063
00065 template <class TRIE> void delete_infrequent_subtrie(
00066 TRIE* subtrie, const counter_t min_supp,
00067 unsigned int step_to_cand_par );
00068
00069 template <class TRIE> void delete_infrequent_subtrieNEE(
00070 TRIE* subtrie, const counter_t min_supp,
00071 unsigned int step_to_cand_par );
00072
00073
00074 public:
00075
00076 };
00077
00078 template <class DF_D, class TRIE_OEL, class TRIE_OI,
00079 class LEAF, class LEAF_ALLOCATOR, NEELevel NEE>
00080 unsigned int CandGenInfreqRemoveNopruneMerge<DF_D, TRIE_OEL, TRIE_OI, LEAF, LEAF_ALLOCATOR, NEE>::total_nr_of_candidates;
00081
00082 template <class DF_D, class TRIE_OEL, class TRIE_OI, class LEAF,
00083 class LEAF_ALLOCATOR, NEELevel NEE>
00084 void CandGenInfreqRemoveNopruneMerge<DF_D, TRIE_OEL, TRIE_OI, LEAF, LEAF_ALLOCATOR, NEE>::
00085 generateCandidate(const unsigned int candidate_size)
00086 {
00087 if(candidate_size == 3)
00088 {
00089 PARENT::nr_of_new_candidates = 0;
00090 if(NEE > NEE_Off)
00091 {
00092 generateCandidateFindParentNEE( &this->main_trie,
00093 candidate_size -2 );
00094 }
00095 else
00096 generateCandidateFindParent( &this->main_trie,
00097 candidate_size -2 );
00098 log_info_det(0,"Number of newly generated candidates: %d",
00099 PARENT::nr_of_new_candidates);
00100 #if DEBUG_LEVEL >= LEVEL_INFO
00101 total_nr_of_candidates += nr_of_new_candidates;
00102 #endif
00103 }
00104 }
00105
00106 template <class DF_D, class TRIE_OEL, class TRIE_OI, class LEAF,
00107 class LEAF_ALLOCATOR, NEELevel NEE>
00108 void CandGenInfreqRemoveNopruneMerge<DF_D, TRIE_OEL, TRIE_OI,
00109 LEAF, LEAF_ALLOCATOR, NEE>::
00110 deleteInfrequent( const counter_t min_supp, unsigned int candidate_size )
00111 {
00112 assert(candidate_size > 1);
00113 nr_of_deleted = 0;
00114 PARENT::nr_of_new_candidates = 0;
00115 if(NEE > NEE_Off)
00116 {
00117 nr_of_prefix_equiitem = 0;
00118 PARENT::df_decoder.pushEquisupportItemSet(
00119 this->main_trie.neelist);
00120 delete_infrequent_subtrieNEE<TRIE_OEL>( &this->main_trie, min_supp,
00121 candidate_size - 1 );
00122 #if DEBUG_LEVEL >= LEVEL_INFO
00123 total_nr_of_prefix_equiitem += nr_of_prefix_equiitem;
00124 #endif
00125
00126 }
00127 else
00128 delete_infrequent_subtrie<TRIE_OEL>( &this->main_trie, min_supp,
00129 candidate_size - 1 );
00130 log_info_det(0,"Number of infrequent candidates: %d", nr_of_deleted);
00131 log_info_det(0,"Number of newly generated candidates: %d",
00132 PARENT::nr_of_new_candidates);
00133 #if DEBUG_LEVEL >= LEVEL_INFO
00134 total_nr_of_candidates += nr_of_new_candidates;
00135 total_nr_of_deleted += nr_of_deleted;
00136 #endif
00137 }
00138
00139 template <class DF_D, class TRIE_OEL, class TRIE_OI,
00140 class LEAF, class LEAF_ALLOCATOR, NEELevel NEE>
00141 void CandGenInfreqRemoveNopruneMerge<DF_D, TRIE_OEL, TRIE_OI,
00142 LEAF, LEAF_ALLOCATOR, NEE>::
00143 afterWorkDel()
00144 {
00145 log_info(0,"The total number of infrequent candidates: %d",
00146 total_nr_of_deleted);
00147 log_info(0,"The total number of generated candidates: %d",
00148 total_nr_of_candidates);
00149 if(NEE > NEE_Off)
00150 log_info(0,"The total number of prefix equisupport item: %d",
00151 total_nr_of_prefix_equiitem);
00152 }
00153
00154 template <class DF_D, class TRIE_OEL, class TRIE_OI,
00155 class LEAF, class LEAF_ALLOCATOR, NEELevel NEE>
00156 template <class TRIE>
00157 void CandGenInfreqRemoveNopruneMerge<DF_D, TRIE_OEL, TRIE_OI,
00158 LEAF, LEAF_ALLOCATOR, NEE>::
00159 delete_infrequent_subtrie( TRIE* subtrie, const counter_t min_supp,
00160 unsigned int step_to_cand_par)
00161 {
00162 typename TRIE::iterator itEdge( subtrie->edgelist.begin() );
00163 if(step_to_cand_par)
00164 {
00165 --step_to_cand_par;
00166 while( itEdge != subtrie->edgelist.end() )
00167 {
00168 PARENT::df_decoder.pushItem( (*itEdge).first );
00169 if( static_cast<LEAF*>((*itEdge).second)->getCounter() & TWO_POW31 )
00170 {
00171 delete_infrequent_subtrie<TRIE_OEL>(
00172 static_cast<TRIE_OEL*>((*itEdge).second),
00173 min_supp, step_to_cand_par);
00174 if( static_cast<TRIE_OEL*>((*itEdge).second)->edgelist.empty() )
00175 {
00176 delete static_cast<TRIE_OEL*>((*itEdge).second);
00177 itEdge = subtrie->edgelist.erase(itEdge);
00178 }
00179 else ++itEdge;
00180 }
00181 else
00182 {
00183 delete_infrequent_subtrie<TRIE_OI>(
00184 static_cast<TRIE_OI*>((*itEdge).second),
00185 min_supp, step_to_cand_par);
00186 if( static_cast<TRIE_OI*>((*itEdge).second)->edgelist.empty() )
00187 {
00188 delete static_cast<TRIE_OI*>((*itEdge).second);
00189 itEdge = subtrie->edgelist.erase(itEdge);
00190 }
00191 else ++itEdge;
00192 }
00193 PARENT::df_decoder.popItem();
00194
00195 }
00196 }
00197 else
00198 {
00199 while( itEdge != subtrie->edgelist.end() )
00200 {
00201 if( static_cast<LEAF*>((*itEdge).second)->getCounter() < min_supp )
00202 {
00203 #if DEBUG_LEVEL >= LEVEL_INFO
00204 ++nr_of_deleted;
00205 #endif
00206 PARENT::s_alloc.free(static_cast<LEAF*>((*itEdge).second));
00207 itEdge = subtrie->edgelist.erase(itEdge);
00208 }
00209 else
00210 ++itEdge;
00211 }
00212 generateCandidateAtParent(subtrie);
00213 }
00214 }
00215 template <class DF_D, class TRIE_OEL, class TRIE_OI,
00216 class LEAF, class LEAF_ALLOCATOR, NEELevel NEE>
00217 template <class TRIE>
00218 void CandGenInfreqRemoveNopruneMerge<DF_D, TRIE_OEL, TRIE_OI,
00219 LEAF, LEAF_ALLOCATOR, NEE>::
00220 delete_infrequent_subtrieNEE( TRIE* subtrie, const counter_t min_supp,
00221 unsigned int step_to_cand_par)
00222 {
00223 typename TRIE::iterator itEdge( subtrie->edgelist.begin() );
00224 if(step_to_cand_par)
00225 {
00226 --step_to_cand_par;
00227 while( itEdge != subtrie->edgelist.end() )
00228 {
00229 PARENT::df_decoder.pushItem( (*itEdge).first );
00230 if( static_cast<LEAF*>((*itEdge).second)->getCounter() & TWO_POW31 )
00231 {
00232 PARENT::df_decoder.pushEquisupportItemSet(
00233 static_cast<TRIE_OEL*>((*itEdge).second)->neelist);
00234 delete_infrequent_subtrieNEE(
00235 static_cast<TRIE_OEL*>((*itEdge).second), min_supp,
00236 step_to_cand_par);
00237 if( static_cast<TRIE_OEL*>((*itEdge).second)->edgelist.empty() )
00238 {
00239 PARENT::df_decoder.write(
00240 static_cast<TRIE_OEL*>((*itEdge).second)->getCounter() & TWO_POW31_1);
00241 delete static_cast<TRIE_OEL*>((*itEdge).second);
00242 itEdge = subtrie->edgelist.erase(itEdge);
00243 }
00244 else ++itEdge;
00245 }
00246 else
00247 {
00248 PARENT::df_decoder.pushEquisupportItemSet(
00249 static_cast<TRIE_OI*>((*itEdge).second)->neelist);
00250 delete_infrequent_subtrieNEE(
00251 static_cast<TRIE_OI*>((*itEdge).second), min_supp,
00252 step_to_cand_par);
00253 if( static_cast<TRIE_OI*>((*itEdge).second)->edgelist.empty() )
00254 {
00255 PARENT::df_decoder.write( static_cast<TRIE_OI*>((*itEdge).second)->getCounter());
00256 delete static_cast<TRIE_OI*>((*itEdge).second);
00257 itEdge = subtrie->edgelist.erase(itEdge);
00258 }
00259 else ++itEdge;
00260 }
00261 PARENT::df_decoder.popItem();
00262 }
00263 }
00264 else
00265 {
00266 while( itEdge != subtrie->edgelist.end() )
00267 {
00268 if( static_cast<LEAF*>((*itEdge).second)->getCounter() < min_supp )
00269 {
00270 #if DEBUG_LEVEL >= LEVEL_INFO
00271 ++nr_of_deleted;
00272 #endif
00273 PARENT::s_alloc.free(static_cast<LEAF*>((*itEdge).second));
00274 itEdge = subtrie->edgelist.erase(itEdge);
00275 }
00276 else if(static_cast<LEAF*>((*itEdge).second)->getCounter() ==
00277 (subtrie->getCounter() & TWO_POW31_1) )
00278 {
00279 subtrie->neelist.push_back((*itEdge).first);
00280 PARENT::df_decoder.pushEquisupportItem((*itEdge).first);
00281 PARENT::s_alloc.free(static_cast<LEAF*>((*itEdge).second));
00282 itEdge = subtrie->edgelist.erase(itEdge);
00283 #if DEBUG_LEVEL >= LEVEL_INFO
00284 ++nr_of_prefix_equiitem;
00285 #endif
00286 }
00287 else
00288 ++itEdge;
00289 }
00290 generateCandidateAtParentNEE(subtrie);
00291 }
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 }
00331 }
00332 #endif