00001 #ifndef SupportCounterFilter_HPP
00002 #define SupportCounterFilter_HPP
00003
00004 #include "common.hpp"
00005 #include <vector>
00006 #include "apriori/bodon/Leaf.hpp"
00007
00008
00009
00010
00011
00012
00013 namespace Bodon
00014 {
00015 namespace dynamic_trie
00016 {
00017 template <class TRIE_OEL, class TRIE_OI>
00018 class SupportCounterFilter
00019 {
00020 private:
00021 typedef Bodon::Leaf LEAF;
00022 public:
00023 SupportCounterFilter( ){}
00024
00025 void updateCounters(
00026 TRIE_OEL& main_trie, const std::vector<item_t>& transaction,
00027 item_t candidate_size, const counter_t counter_incr,
00028 std::vector<unsigned int>& filter)
00029 {
00030 if( candidate_size <= transaction.size() )
00031 findCandidates(
00032 &main_trie, transaction.end()-candidate_size+1,
00033 transaction.begin(), candidate_size,
00034 counter_incr, filter );
00035 }
00036 protected:
00039 unsigned int findCandidates( TRIE_OEL* subtrie,
00040 std::vector<item_t>::const_iterator it_basket_upper_bound,
00041 std::vector<item_t>::const_iterator it_basket,
00042 item_t step_to_candidate,
00043 const counter_t counter_incr,
00044 std::vector<unsigned int>& filter );
00045
00046 unsigned int findCandidates( TRIE_OI* subtrie,
00047 std::vector<item_t>::const_iterator it_basket_upper_bound,
00048 std::vector<item_t>::const_iterator it_basket,
00049 item_t step_to_candidate,
00050 const counter_t counter_incr,
00051 std::vector<unsigned int>& filter );
00052 };
00053
00054 template <class TRIE_OEL, class TRIE_OI> unsigned int
00055 SupportCounterFilter<TRIE_OEL, TRIE_OI>::findCandidates(
00056 TRIE_OEL* 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 std::vector<unsigned int>& filter )
00060 {
00061 --step_to_candidate;
00062 typename TRIE_OEL::iterator it_edge(subtrie->edgelist.begin());
00063 unsigned int return_value = 0;
00064 if( step_to_candidate )
00065 {
00066 while( it_edge != subtrie->edgelist.end() &&
00067 it_basket != it_basket_upper_bound )
00068 {
00069 if( (*it_edge).first < *it_basket) ++it_edge;
00070 else if( (*it_edge).first > *it_basket) ++it_basket;
00071 else
00072 {
00073 ++it_basket;
00074 unsigned int local_return_value;
00075 if(static_cast<LEAF*>((*it_edge).second)->getCounter() & TWO_POW31)
00076 local_return_value =
00077 findCandidates( static_cast<TRIE_OEL*>((*it_edge).second),
00078 it_basket_upper_bound + 1, it_basket,
00079 step_to_candidate, counter_incr, filter);
00080 else
00081 local_return_value =
00082 findCandidates( static_cast<TRIE_OI*>((*it_edge).second),
00083 it_basket_upper_bound + 1, it_basket,
00084 step_to_candidate, counter_incr, filter);
00085 return_value += local_return_value;
00086 filter[(*it_edge).first] += local_return_value;
00087 ++it_edge;
00088 }
00089 }
00090 }
00091 else
00092 {
00093 while( it_edge != subtrie->edgelist.end() &&
00094 it_basket != it_basket_upper_bound )
00095 {
00096 if( (*it_edge).first < *it_basket) ++it_edge;
00097 else if( (*it_edge).first > *it_basket) ++it_basket;
00098 else
00099 {
00100 ++it_basket;
00101 static_cast<LEAF*>((*it_edge).second)
00102 ->increaseCounter( counter_incr);
00103 ++filter[(*it_edge).first];
00104 ++return_value;
00105 ++it_edge;
00106 }
00107 }
00108 }
00109 return return_value;
00110 }
00111
00112 template <class TRIE_OEL, class TRIE_OI> unsigned int
00113 SupportCounterFilter<TRIE_OEL, TRIE_OI>::findCandidates(
00114 TRIE_OI* subtrie, std::vector<item_t>::const_iterator it_basket_upper_bound,
00115 std::vector<item_t>::const_iterator it_basket,
00116 item_t step_to_candidate, const counter_t counter_incr,
00117 std::vector<unsigned int>& filter )
00118 {
00119 --step_to_candidate;
00120 void* subsubtrie;
00121 item_t largest_label = subtrie->edgelist.largestEdgelabel();
00122 unsigned int return_value = 0;
00123 if( step_to_candidate )
00124 {
00125 while( it_basket != it_basket_upper_bound && *it_basket <= largest_label)
00126 {
00127 subtrie->edgelist.lookupNoUppercheck(*it_basket, subsubtrie);
00128 if(subsubtrie)
00129 {
00130 unsigned int local_return_value;
00131 if(static_cast<LEAF*>(subsubtrie)->getCounter() & TWO_POW31)
00132 local_return_value =
00133 findCandidates( static_cast<TRIE_OEL*>(subsubtrie),
00134 it_basket_upper_bound + 1, it_basket + 1,
00135 step_to_candidate, counter_incr, filter );
00136 else
00137 local_return_value =
00138 findCandidates( static_cast<TRIE_OI*>(subsubtrie),
00139 it_basket_upper_bound + 1, it_basket + 1,
00140 step_to_candidate, counter_incr, filter );
00141 return_value += local_return_value;
00142 filter[*it_basket] += local_return_value;
00143 }
00144 ++it_basket;
00145
00146 }
00147 }
00148 else
00149 {
00150 while( it_basket != it_basket_upper_bound && *it_basket <= largest_label)
00151 {
00152 subtrie->edgelist.lookupNoUppercheck(*it_basket, subsubtrie);
00153 if(subsubtrie)
00154 {
00155 static_cast<LEAF*>(subsubtrie)
00156 ->increaseCounter(counter_incr);
00157 ++return_value;
00158 ++filter[*it_basket];
00159 }
00160 ++it_basket;
00161 }
00162 }
00163 return return_value;
00164 }
00165 }
00166 }
00167 #endif