00001 #ifndef CandidateGeneratorPrune_HPP
00002 #define CandidateGeneratorPrune_HPP
00003
00004 #include "common.hpp"
00005 #include "common/Edge.hpp"
00006 #include <vector>
00007
00008
00009
00010
00011
00012
00013 namespace Bodon
00014 {
00015 namespace sequence
00016 {
00017 namespace inhomogeneous_trie
00018 {
00019 template <class P, class DF_D, class TRIE, class LEAF, class LEAF_ALLOCATOR>
00020 class CandidateGeneratorPrune : public P
00021 {
00022 protected:
00023 unsigned int nr_of_new_candidates;
00024 unsigned int nr_of_all_candidates;
00025 public:
00026 CandidateGeneratorPrune( TRIE& main_trie, DF_D& df_decoder,
00027 LEAF_ALLOCATOR& s_alloc ) :
00028 P(main_trie, df_decoder, s_alloc),
00029 nr_of_all_candidates(0){}
00030
00031
00037 void generateCandidate(unsigned int candidate_size);
00038
00039 void afterWorkCandGen();
00040 protected:
00041
00043 void generateCandidateFindParent(
00044 TRIE* trie, std::vector<item_t>& maybe_candidate,
00045 unsigned int step_to_freq_par);
00046 void removeNonCandPaths( TRIE* trie, unsigned int step_to_freq);
00047 };
00048
00049
00050 template <class P, class DF_D, class TRIE, class LEAF, class LEAF_ALLOCATOR>
00051 void CandidateGeneratorPrune<P, DF_D, TRIE, LEAF, LEAF_ALLOCATOR>::
00052 generateCandidate(unsigned int candidate_size)
00053 {
00054 assert(candidate_size > 1);
00055 nr_of_new_candidates = 0;
00056 std::vector<item_t> maybe_candidate;
00057 generateCandidateFindParent( &this->main_trie, maybe_candidate,
00058 candidate_size -2 );
00059 removeNonCandPaths(&this->main_trie, candidate_size - 2);
00060 log_dbg(0,"Number of newly generated candidates: %d",
00061 nr_of_new_candidates);
00062
00063 #if DEBUG_LEVEL >= LEVEL_DBG
00064 nr_of_all_candidates += nr_of_new_candidates;
00065 #endif
00066 }
00067 template <class P, class DF_D, class TRIE, class LEAF, class LEAF_ALLOCATOR>
00068 void CandidateGeneratorPrune<P, DF_D, TRIE, LEAF, LEAF_ALLOCATOR>::
00069 afterWorkCandGen()
00070 {
00071 log_dbg(0,"The total number of generated candidates (in del. p.): %d",
00072 nr_of_all_candidates);
00073 }
00074
00075 template <class P, class DF_D, class TRIE, class LEAF, class LEAF_ALLOCATOR>
00076 void CandidateGeneratorPrune<P, DF_D, TRIE, LEAF, LEAF_ALLOCATOR>::
00077 generateCandidateFindParent( TRIE* trie,
00078 std::vector<item_t>& maybe_candidate,
00079 unsigned int step_to_freq_par)
00080 {
00081 typename TRIE::iterator itEdge( trie->edgelist.begin() );
00082 if(step_to_freq_par)
00083 {
00084 --step_to_freq_par;
00085 while( itEdge != trie->edgelist.end() )
00086 {
00087 maybe_candidate.push_back((*itEdge).first);
00088 P::df_decoder.pushItem( (*itEdge).first );
00089 generateCandidateFindParent( static_cast<TRIE*>((*itEdge).second),
00090 maybe_candidate,
00091 step_to_freq_par);
00092 P::df_decoder.popItem();
00093 maybe_candidate.pop_back();
00094 ++itEdge;
00095 }
00096 }
00097 else
00098 {
00099 generateCandidateAtParent(trie, maybe_candidate);
00100 #if DEBUG_LEVEL >= LEVEL_DBG
00101 for( typename TRIE::iterator it( trie->edgelist.begin() );
00102 it != trie->edgelist.end(); ++it)
00103 nr_of_new_candidates +=
00104 static_cast<TRIE*>((*it).second)->edgelist.size();
00105 #endif
00106 }
00107 }
00108
00109 template <class P, class DF_D, class TRIE, class LEAF, class LEAF_ALLOCATOR>
00110 void CandidateGeneratorPrune<P, DF_D, TRIE, LEAF, LEAF_ALLOCATOR>::
00111 removeNonCandPaths( TRIE* trie, unsigned int step_to_freq_par)
00112 {
00113 typename TRIE::iterator itEdge( trie->edgelist.begin() );
00114 if(step_to_freq_par)
00115 {
00116 while( itEdge != trie->edgelist.end() )
00117 {
00118 removeNonCandPaths( static_cast<TRIE*>((*itEdge).second),
00119 step_to_freq_par-1);
00120 if(static_cast<TRIE*>((*itEdge).second)->edgelist.empty())
00121 {
00122 delete static_cast<TRIE*>((*itEdge).second);
00123 itEdge = trie->edgelist.erase(itEdge);
00124 }
00125 else ++itEdge;
00126 }
00127 }
00128 else
00129 {
00130 while( itEdge != trie->edgelist.end() )
00131 {
00132 if( static_cast<LEAF*>((*itEdge).second)->getCounter() == 0)
00133 {
00134 P::s_alloc.free(static_cast<LEAF*>((*itEdge).second));
00135 itEdge = trie->edgelist.erase(itEdge);
00136 }
00137 else ++itEdge;
00138 }
00139 }
00140 }
00141 }
00142 }
00143 }
00144 #endif