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