@@ -16,18 +16,23 @@ class FPTree
1616
1717 private FPNode $ root ;
1818
19+ private int $ maxLength = 0 ;
20+
21+ private int $ depth = 0 ;
22+
1923 /**
2024 * Initialize the tree.
2125 * @param array $transactions
2226 * @param int $threshold
2327 * @param $rootValue
2428 * @param int $rootCount
2529 */
26- public function __construct (array $ transactions , int $ threshold , $ rootValue , int $ rootCount )
30+ public function __construct (array $ transactions , int $ threshold , $ rootValue , int $ rootCount, $ maxLength = 0 )
2731 {
2832 $ this ->frequent = $ this ->findFrequentItems ($ transactions , $ threshold );
2933 $ this ->headers = $ this ->buildHeaderTable ();
3034 $ this ->root = $ this ->buildFPTree ($ transactions , $ rootValue , $ rootCount , $ this ->frequent );
35+ $ this ->maxLength = $ maxLength ;
3136 }
3237
3338 /**
@@ -168,6 +173,8 @@ public function minePatterns(int $threshold): array
168173 {
169174 if ($ this ->treeHasSinglePath ($ this ->root )) {
170175 return $ this ->generatePatternList ();
176+ } elseif ($ this ->maxLength && $ this ->maxLength <= $ this ->getDepth ()) {
177+ return [];
171178 }
172179
173180 return $ this ->zipPatterns ($ this ->mineSubTrees ($ threshold ));
@@ -211,7 +218,13 @@ protected function generatePatternList(): array
211218 $ patterns [$ this ->root ->value ] = $ this ->root ->count ;
212219 }
213220
214- for ($ i = 1 ; $ i <= count ($ items ); $ i ++) {
221+ // limit length of combinations to remaining length
222+ $ count = count ($ items );
223+ if ($ this ->maxLength ) {
224+ $ count = min ($ count , $ this ->maxLength - $ this ->getDepth ());
225+ }
226+
227+ for ($ i = 1 ; $ i <= $ count ; $ i ++) {
215228 $ combinations = new Combinations ($ items ,$ i );
216229 foreach ($ combinations ->generator () as $ subset ) {
217230 $ pattern = $ this ->root ->value !== null ? array_merge ($ subset , [$ this ->root ->value ]) : $ subset ;
@@ -270,7 +283,8 @@ protected function mineSubTrees(int $threshold): array
270283 }
271284
272285 // Now we have the input for a subtree, so construct it and grab the patterns.
273- $ subtree = new FPTree ($ conditionalTreeInput , $ threshold , $ item , $ this ->frequent [$ item ]);
286+ $ subtree = new FPTree ($ conditionalTreeInput , $ threshold , $ item , $ this ->frequent [$ item ], $ this ->maxLength );
287+ $ subtree ->depth = $ this ->depth + 1 ;
274288 $ subtreePatterns = $ subtree ->minePatterns ($ threshold );
275289
276290 // Insert subtree patterns into main patterns dictionary.
@@ -285,4 +299,9 @@ protected function mineSubTrees(int $threshold): array
285299
286300 return $ patterns ;
287301 }
302+
303+ private function getDepth (): int
304+ {
305+ return $ this ->depth ;
306+ }
288307}
0 commit comments