00001 #ifndef SupportCounterLookupTransLinBin_HPP
00002 #define SupportCounterLookupTransLinBin_HPP
00003
00004 #include "common.hpp"
00005 #include <vector>
00006 #include "apriori/bodon/Leaf.hpp"
00007
00008
00009
00010
00011
00012 namespace Bodon
00013 {
00014 template <class TRIE, unsigned int THRESHOLD=100>
00015 class SupportCounterLookupTransLinBin
00016 {
00017 public:
00018 SupportCounterLookupTransLinBin( ){}
00019
00020 void updateCounters(
00021 TRIE& main_trie, const std::vector<item_t>& transaction,
00022 item_t candidate_size, const counter_t counter_incr)
00023 {
00024 if( candidate_size <= transaction.size() )
00025 findCandidates(
00026 &main_trie, transaction.end()-candidate_size+1,
00027 transaction.begin(), candidate_size,
00028 counter_incr );
00029 }
00030
00031 protected:
00034 void findCandidates( TRIE* subtrie,
00035 std::vector<item_t>::const_iterator it_basket_upper_bound,
00036 std::vector<item_t>::const_iterator it_basket,
00037 item_t step_to_candidate,
00038 const counter_t counter_incr );
00039
00040 void findCandidatesSpecMerge( TRIE* subtrie,
00041 std::vector<item_t>::const_iterator it_basket_upper_bound,
00042 std::vector<item_t>::const_iterator it_basket,
00043 item_t step_to_candidate,
00044 const counter_t counter_incr,
00045 typename TRIE::iterator it_edge );
00046
00047 void findCandidatesMerge( TRIE* subtrie,
00048 std::vector<item_t>::const_iterator it_basket_upper_bound,
00049 std::vector<item_t>::const_iterator it_basket,
00050 item_t step_to_candidate,
00051 const counter_t counter_incr );
00052 };
00053
00054 template <class TRIE, unsigned int THRESHOLD> void
00055 SupportCounterLookupTransLinBin<TRIE, THRESHOLD>::findCandidates(
00056 TRIE* subtrie, std::vector<item_t>::const_iterator it_basket_upper_bound,
00057 std::vector<item_t>::const_iterator it_basket,
00058 item_t step_to_candidate, const counter_t counter_incr )
00059 {
00060 --step_to_candidate;
00061 for( typename TRIE::iterator it_edge(subtrie->edgelist.begin());
00062 it_edge != subtrie->edgelist.end(); ++it_edge)
00063 {
00064 if( static_cast<unsigned int>(it_basket_upper_bound - it_basket)
00065 < THRESHOLD )
00066 {
00067 findCandidatesSpecMerge(
00068 subtrie, it_basket_upper_bound,
00069 it_basket, step_to_candidate, counter_incr, it_edge );
00070 break;
00071 }
00072 else
00073 it_basket = std::lower_bound( it_basket, it_basket_upper_bound,
00074 (*it_edge).first);
00075 if(it_basket == it_basket_upper_bound)
00076 break;
00077 else
00078 {
00079 if(*it_basket == (*it_edge).first)
00080 {
00081 if( step_to_candidate )
00082 findCandidates( static_cast<TRIE*>((*it_edge).second),
00083 it_basket_upper_bound + 1, it_basket,
00084 step_to_candidate, counter_incr);
00085 else
00086 static_cast<Leaf*>((*it_edge).second)
00087 ->increaseCounter( counter_incr);
00088 ++it_basket;
00089 }
00090 }
00091 }
00092 }
00093 template <class TRIE, unsigned int THRESHOLD> void
00094 SupportCounterLookupTransLinBin<TRIE, THRESHOLD>::findCandidatesSpecMerge(
00095 TRIE* subtrie, std::vector<item_t>::const_iterator it_basket_upper_bound,
00096 std::vector<item_t>::const_iterator it_basket,
00097 item_t step_to_candidate, const counter_t counter_incr,
00098 typename TRIE::iterator it_edge )
00099 {
00100 while( it_edge != subtrie->edgelist.end() &&
00101 it_basket != it_basket_upper_bound )
00102 {
00103 if( (*it_edge).first < *it_basket) ++it_edge;
00104 else if( (*it_edge).first > *it_basket) ++it_basket;
00105 else
00106 {
00107 ++it_basket;
00108 if( step_to_candidate )
00109 findCandidatesMerge( static_cast<TRIE*>((*it_edge).second),
00110 it_basket_upper_bound + 1, it_basket,
00111 step_to_candidate, counter_incr);
00112 else
00113 static_cast<Leaf*>((*it_edge).second)
00114 ->increaseCounter( counter_incr);
00115 ++it_edge;
00116 }
00117 }
00118 }
00119 template <class TRIE, unsigned int THRESHOLD> void
00120 SupportCounterLookupTransLinBin<TRIE, THRESHOLD>::findCandidatesMerge(
00121 TRIE* subtrie, std::vector<item_t>::const_iterator it_basket_upper_bound,
00122 std::vector<item_t>::const_iterator it_basket,
00123 item_t step_to_candidate, const counter_t counter_incr )
00124 {
00125 --step_to_candidate;
00126 typename TRIE::iterator it_edge(subtrie->edgelist.begin());
00127 while( it_edge != subtrie->edgelist.end() &&
00128 it_basket != it_basket_upper_bound )
00129 {
00130 if( (*it_edge).first < *it_basket) ++it_edge;
00131 else if( (*it_edge).first > *it_basket) ++it_basket;
00132 else
00133 {
00134 ++it_basket;
00135 if( step_to_candidate )
00136 findCandidatesMerge( static_cast<TRIE*>((*it_edge).second),
00137 it_basket_upper_bound + 1, it_basket,
00138 step_to_candidate, counter_incr);
00139 else
00140 static_cast<Leaf*>((*it_edge).second)
00141 ->increaseCounter( counter_incr);
00142 ++it_edge;
00143 }
00144 }
00145 }
00146 }
00147 #endif