00001 #ifndef SimplePruner_HPP
00002 #define SimplePruner_HPP
00003
00004 #include "common.hpp"
00005 #include "common/Edge.hpp"
00006 #include "common/allocators.hpp"
00007 #include "apriori/bodon/inhomogeneous_trie/trie_manipulators/ManipulatorBase.hpp"
00008 #include <vector>
00009
00010
00011
00012
00013
00014
00015 namespace Bodon
00016 {
00017 namespace trie
00018 {
00019 template <class DF_D, class TRIE,
00020 class TRIE_ALLOCATOR = NewWrapperAlloc<TRIE>, bool NEE= true>
00021 class SimplePruner : public Bodon::inhomogeneous_trie::ManipulatorBase<
00022 DF_D, TRIE, TRIE_ALLOCATOR>
00023 {
00024 private:
00025 typedef Bodon::inhomogeneous_trie::ManipulatorBase<DF_D, TRIE, TRIE_ALLOCATOR> PARENT;
00026 protected:
00027 std::vector<Edge> extenders;
00028
00029 public:
00030 SimplePruner( TRIE& main_trie, DF_D& df_decoder,
00031 TRIE_ALLOCATOR& s_alloc ) :
00032 Bodon::inhomogeneous_trie::ManipulatorBase<DF_D, TRIE, TRIE_ALLOCATOR>(
00033 main_trie, df_decoder, s_alloc){}
00034
00035
00036 protected:
00038 int isAllSubsetFrequent( std::vector<item_t>& maybe_candidate,
00039 const item_t new_item ) const;
00040
00041
00042 void generateCandidateAtParent(
00043 TRIE* trie, std::vector<item_t>& maybe_candidate );
00044 void generateCandidateAtParentNEE(
00045 TRIE* trie, std::vector<item_t>& maybe_candidate,
00046 std::vector<item_t>& NEEsum );
00047 };
00048
00049
00050 template <class DF_D, class TRIE, class TRIE_ALLOCATOR, bool NEE> inline int
00051 SimplePruner<DF_D, TRIE, TRIE_ALLOCATOR, NEE>::isAllSubsetFrequent(
00052 std::vector<item_t>& generator, const item_t new_item ) const
00053 {
00054 assert(itemset.size() > 1);
00055 std::vector<item_t>::iterator item_it = generator.end()-2;
00056 register item_t deleted_item = *item_it, temp_item;
00057 const TRIE* temp_trie;
00058
00059 generator.erase( item_it );
00060 temp_trie = PARENT::main_trie.isIncluded( generator, generator.begin() );
00061 if( temp_trie)
00062 {
00063 if( !temp_trie->edgelist.find(new_item) )
00064 {
00065 generator.insert( item_it, deleted_item );
00066 if(NEE)
00067 {
00068 if( temp_trie->neeFind(new_item) )
00069 return 2;
00070 else
00071 return 0;
00072 }
00073 else
00074 return 0;
00075 }
00076 }
00077 else
00078 {
00079 generator.insert( item_it, deleted_item );
00080 return 0;
00081 }
00082 while(item_it != generator.begin())
00083 {
00084 --item_it;
00085 temp_item = *item_it;
00086 *item_it = deleted_item;
00087 deleted_item = temp_item;
00088 temp_trie = PARENT::main_trie.isIncluded( generator, generator.begin() );
00089 if( temp_trie)
00090 {
00091 if( !temp_trie->edgelist.find(new_item) )
00092 {
00093 generator.insert( item_it, deleted_item );
00094 if(NEE)
00095 {
00096 if( temp_trie->neeFind(new_item) )
00097 return 2;
00098 else
00099 return 0;
00100 }
00101 else
00102 return 0;
00103 }
00104 }
00105 else
00106 {
00107 generator.insert( item_it, deleted_item );
00108 return 0;
00109 }
00110 }
00111 generator.insert( item_it, deleted_item );
00112 return 1;
00113 }
00114
00115
00116 template <class DF_D, class TRIE, class TRIE_ALLOCATOR, bool NEE> inline void
00117 SimplePruner<DF_D, TRIE, TRIE_ALLOCATOR, NEE>::
00118 generateCandidateAtParent(TRIE* trie, std::vector<item_t>& maybe_candidate)
00119 {
00120 typename TRIE::iterator itEdge( trie->edgelist.begin() ), itEdge2;
00121 TRIE* toExtend;
00122 while( itEdge != trie->edgelist.end() )
00123 {
00124 toExtend = static_cast<TRIE*>((*itEdge).second);
00125 PARENT::df_decoder.pushItemWithWrite( (*itEdge).first, toExtend->getCounter() );
00126 PARENT::df_decoder.popItem();
00127 maybe_candidate.push_back((*itEdge).first);
00128 itEdge2 = itEdge;
00129 ++itEdge2;
00130 extenders.clear();
00131 for( ; itEdge2 != trie->edgelist.end(); ++itEdge2 )
00132 {
00133 if( isAllSubsetFrequent( maybe_candidate, (*itEdge2).first ) == 1 )
00134 {
00135 extenders.push_back(Edge((*itEdge2).first, PARENT::s_alloc.allocate()));
00136 static_cast<TRIE*>(extenders.back().second)->setCounter(0);
00137 }
00138 }
00139 maybe_candidate.pop_back();
00140 if(extenders.empty())
00141 {
00142 delete toExtend;
00143 itEdge = trie->edgelist.erase(itEdge);
00144 }
00145 else
00146 {
00147 toExtend->edgelist.insert(extenders);
00148 ++itEdge;
00149 }
00150 }
00151 }
00152
00153 template <class DF_D, class TRIE, class TRIE_ALLOCATOR, bool NEE> inline void
00154 SimplePruner<DF_D, TRIE, TRIE_ALLOCATOR, NEE>::
00155 generateCandidateAtParentNEE( TRIE* trie, std::vector<item_t>& maybe_candidate,
00156 std::vector<item_t>& NEEsum )
00157 {
00158 NEEsum.insert( NEEsum.end(),
00159 trie->neelist.begin(), trie->neelist.end() );
00160 typename TRIE::iterator itEdge( trie->edgelist.begin() ), itEdge2;
00161 TRIE* toExtend;
00162 while( itEdge != trie->edgelist.end() )
00163 {
00164 toExtend = static_cast<TRIE*>((*itEdge).second);
00165 maybe_candidate.push_back((*itEdge).first);
00166 itEdge2 = itEdge;
00167 ++itEdge2;
00168 extenders.clear();
00169 for( ; itEdge2 != trie->edgelist.end(); ++itEdge2 )
00170 {
00171 switch (isAllSubsetFrequent( maybe_candidate, (*itEdge2).first ))
00172 {
00173 case 1:
00174 extenders.push_back(Edge((*itEdge2).first, PARENT::s_alloc.allocate()));
00175 static_cast<TRIE*>(extenders.back().second)->setCounter(0);
00176 break;
00177 case 2: toExtend->neelist.push_back((*itEdge2).first);break;
00178 }
00179 }
00180 maybe_candidate.pop_back();
00181 if(extenders.empty() && NEEsum.size() < 1 && toExtend->neelist.empty() )
00182 {
00183 PARENT::df_decoder.pushItemWithWrite( (*itEdge).first,
00184 toExtend->getCounter() );
00185 PARENT::df_decoder.popItem();
00186 delete toExtend;
00187 itEdge = trie->edgelist.erase(itEdge);
00188 }
00189 else
00190 {
00191 toExtend->edgelist.insert(extenders);
00192 ++itEdge;
00193 }
00194 }
00195 NEEsum.resize( NEEsum.size() - trie->neelist.size() );
00196 }
00197 }
00198 }
00199 #endif