00001 #ifndef CandidateGeneratorNoprune_HPP
00002 #define CandidateGeneratorNoprune_HPP
00003
00004
00005 #include "common.hpp"
00006 #include "common/Edge.hpp"
00007 #include "common/log.h"
00008 #include "apriori/bodon/trie/trie_manipulators/ManipulatorBase.hpp"
00009 #include <vector>
00010
00011
00012
00013
00014
00015
00016 namespace Bodon
00017 {
00018 namespace trie
00019 {
00020 template <class DF_D, class TRIE, bool NEE>
00021 class CandidateGeneratorNoprune : public ManipulatorBase<DF_D, TRIE>
00022 {
00023 protected:
00024 std::vector<Edge> extenders;
00025 unsigned int nr_of_new_candidates;
00026 unsigned int nr_of_all_candidates;
00027 typedef ManipulatorBase<DF_D, TRIE> PARENT;
00028
00029 public:
00030 CandidateGeneratorNoprune( TRIE& main_trie, DF_D& df_decoder ) :
00031 ManipulatorBase<DF_D, TRIE>(main_trie, df_decoder),
00032 nr_of_all_candidates(0){}
00033
00034
00040 void generateCandidate(unsigned int candidate_size);
00041
00042 void afterWorkCandGen();
00043 protected:
00044
00045 void generateCandidateAtParent( TRIE* trie );
00046 void generateCandidateAtParentNEE( TRIE* trie,
00047 std::vector<item_t>& NEEsum );
00048
00050 void generateCandidateFindParent(
00051 TRIE* trie, unsigned int step_to_freq_par);
00052 void generateCandidateFindParentNEE(
00053 TRIE* trie, std::vector<item_t>& NEEsum,
00054 unsigned int step_to_freq_par);
00055
00056
00057
00058
00059 public:
00060
00061 };
00062
00063
00064 template <class DF_D, class TRIE, bool NEE>
00065 void CandidateGeneratorNoprune<DF_D, TRIE, NEE>::
00066 generateCandidate(unsigned int candidate_size)
00067 {
00068 assert(candidate_size > 1);
00069 nr_of_new_candidates = 0;
00070 if(NEE > NEE_Off)
00071 {
00072 std::vector<item_t> NEEsum;
00073 generateCandidateFindParentNEE( &PARENT::main_trie, NEEsum,
00074 candidate_size -2 );
00075 }
00076 else generateCandidateFindParent( &PARENT::main_trie,
00077 candidate_size -2 );
00078 log_dbg(0, "Number of newly generated candidates: %d", nr_of_new_candidates);
00079 #if DEBUG_LEVEL >= LEVEL_DBG
00080 nr_of_all_candidates += nr_of_new_candidates;
00081 #endif
00082 }
00083 template <class DF_D, class TRIE, bool NEE>
00084 void CandidateGeneratorNoprune<DF_D, TRIE, NEE>::
00085 afterWorkCandGen()
00086 {
00087 log_dbg(0, "The total number of generated candidates: %d", nr_of_all_candidates);
00088 }
00089
00090
00091 template <class DF_D, class TRIE, bool NEE> inline void
00092 CandidateGeneratorNoprune<DF_D, TRIE, NEE>::
00093 generateCandidateAtParent(TRIE* trie)
00094 {
00095 typename TRIE::iterator itEdge( trie->edgelist.begin() ), itEdge2;
00096 TRIE* toExtend;
00097 while( itEdge != trie->edgelist.end() )
00098 {
00099 toExtend = static_cast<TRIE*>((*itEdge).second);
00100 PARENT::df_decoder.pushItemWithWrite( (*itEdge).first,
00101 toExtend->getCounter() );
00102 PARENT::df_decoder.popItem();
00103 itEdge2 = itEdge;
00104 ++itEdge2;
00105 extenders.clear();
00106 for( ; itEdge2 != trie->edgelist.end(); ++itEdge2 )
00107 extenders.push_back(Edge((*itEdge2).first, new TRIE(0)));
00108 if(extenders.empty())
00109 {
00110 delete toExtend;
00111 itEdge = trie->edgelist.erase(itEdge);
00112 }
00113 else
00114 {
00115 toExtend->edgelist.insert(extenders);
00116 ++itEdge;
00117 }
00118 }
00119 }
00120
00121 template <class DF_D, class TRIE, bool NEE> inline void
00122 CandidateGeneratorNoprune<DF_D, TRIE, NEE>::
00123 generateCandidateAtParentNEE( TRIE* trie,
00124 std::vector<item_t>& NEEsum )
00125 {
00126 NEEsum.insert( NEEsum.end(),
00127 trie->neelist.begin(), trie->neelist.end() );
00128 typename TRIE::iterator itEdge( trie->edgelist.begin() ), itEdge2;
00129 TRIE* toExtend;
00130 while( itEdge != trie->edgelist.end() )
00131 {
00132 itEdge2 = itEdge;
00133 ++itEdge2;
00134 extenders.clear();
00135 for( ; itEdge2 != trie->edgelist.end(); ++itEdge2 )
00136 extenders.push_back(Edge((*itEdge2).first, new TRIE(0)));
00137 toExtend = static_cast<TRIE*>((*itEdge).second);
00138 if(extenders.empty())
00139 {
00140 PARENT::df_decoder.pushItem( (*itEdge).first );
00141 PARENT::df_decoder.writeNEE( static_cast<TRIE*>(toExtend)->getCounter(), NEEsum);
00142 PARENT::df_decoder.popItem();
00143 delete toExtend;
00144 itEdge = trie->edgelist.erase(itEdge);
00145 }
00146 else
00147 {
00148 toExtend->edgelist.insert(extenders);
00149 ++itEdge;
00150 }
00151 }
00152 NEEsum.resize( NEEsum.size() - trie->neelist.size() );
00153 }
00154
00155
00156 template <class DF_D, class TRIE, bool NEE> void
00157 CandidateGeneratorNoprune<DF_D, TRIE, NEE>::
00158 generateCandidateFindParent( TRIE* trie,
00159 unsigned int step_to_freq_par)
00160 {
00161 typename TRIE::iterator itEdge( trie->edgelist.begin() );
00162 if(step_to_freq_par)
00163 {
00164 --step_to_freq_par;
00165 while( itEdge != trie->edgelist.end() )
00166 {
00167 PARENT::df_decoder.pushItem( (*itEdge).first );
00168 generateCandidateFindParent(
00169 static_cast<TRIE*>((*itEdge).second), step_to_freq_par);
00170 if(static_cast<TRIE*>((*itEdge).second)->edgelist.empty())
00171 {
00172 delete static_cast<TRIE*>((*itEdge).second);
00173 itEdge = trie->edgelist.erase(itEdge);
00174 }
00175 else ++itEdge;
00176 PARENT::df_decoder.popItem();
00177 }
00178 }
00179 else
00180 {
00181 generateCandidateAtParent(trie);
00182 #if DEBUG_LEVEL >= LEVEL_DBG
00183 for( typename TRIE::iterator it( trie->edgelist.begin() );
00184 it != trie->edgelist.end(); ++it)
00185 nr_of_new_candidates +=
00186 static_cast<TRIE*>((*it).second)->edgelist.size();
00187 #endif
00188 }
00189 }
00190 template <class DF_D, class TRIE, bool NEE> void
00191 CandidateGeneratorNoprune<DF_D, TRIE, NEE>::
00192 generateCandidateFindParentNEE( TRIE* trie,
00193 std::vector<item_t>& NEEsum,
00194 unsigned int step_to_freq_par)
00195 {
00196 typename TRIE::iterator itEdge( trie->edgelist.begin() );
00197 if(step_to_freq_par)
00198 {
00199 NEEsum.insert( NEEsum.end(),
00200 trie->neelist.begin(), trie->neelist.end() );
00201 --step_to_freq_par;
00202 while( itEdge != trie->edgelist.end() )
00203 {
00204 PARENT::df_decoder.pushItem( (*itEdge).first );
00205 generateCandidateFindParentNEE(
00206 static_cast<TRIE*>((*itEdge).second), NEEsum, step_to_freq_par);
00207 if(static_cast<TRIE*>((*itEdge).second)->edgelist.empty())
00208 {
00209 NEEsum.insert( NEEsum.end(),
00210 static_cast<TRIE*>((*itEdge).second)->neelist.begin(),
00211 static_cast<TRIE*>((*itEdge).second)->neelist.end() );
00212 PARENT::df_decoder.writeNEE( static_cast<TRIE*>((*itEdge).second)->getCounter(),
00213 NEEsum);
00214 NEEsum.resize( NEEsum.size() -
00215 static_cast<TRIE*>((*itEdge).second)->neelist.size() );
00216 delete static_cast<TRIE*>((*itEdge).second);
00217 itEdge = trie->edgelist.erase(itEdge);
00218 }
00219 else ++itEdge;
00220 PARENT::df_decoder.popItem();
00221 }
00222 NEEsum.resize( NEEsum.size() - trie->neelist.size() );
00223 }
00224 else
00225 {
00226 generateCandidateAtParentNEE(trie, NEEsum);
00227 #if DEBUG_LEVEL >= LEVEL_DBG
00228 for( typename TRIE::iterator it( trie->edgelist.begin() );
00229 it != trie->edgelist.end(); ++it)
00230 nr_of_new_candidates +=
00231 static_cast<TRIE*>((*it).second)->edgelist.size();
00232 #endif
00233 }
00234 }
00235 }
00236 }
00237 #endif