Changeset 1060 for trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/Trie.java
- Timestamp:
- 02/07/13 17:57:07 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-usageprofiles/src/main/java/de/ugoe/cs/autoquest/usageprofiles/Trie.java
r927 r1060 34 34 * </p> 35 35 * 36 * @author Steffen Herbold 36 * @author Steffen Herbold, Patrick Harms 37 37 * 38 38 * @param <T> … … 66 66 /** 67 67 * <p> 68 * Contructor. Creates a new Trie. 68 * Comparator to be used for comparing the symbols with each other 69 * </p> 70 */ 71 private SymbolComparator<T> comparator; 72 73 /** 74 * <p> 75 * Contructor. Creates a new Trie with a {@link DefaultSymbolComparator}. 69 76 * </p> 70 77 */ 71 78 public Trie() { 72 rootNode = new TrieNode<T>(); 79 this(new DefaultSymbolComparator<T>()); 80 } 81 82 /** 83 * <p> 84 * Contructor. Creates a new Trie with that uses a specific {@link SymbolComparator}. 85 * </p> 86 */ 87 public Trie(SymbolComparator<T> comparator) { 88 this.comparator = comparator; 89 rootNode = new TrieNode<T>(comparator); 73 90 knownSymbols = new LinkedHashSet<T>(); 74 91 } … … 76 93 /** 77 94 * <p> 78 * Copy-Constructor. Creates a new Trie as the copy of other. The other trie must no chbe null.95 * Copy-Constructor. Creates a new Trie as the copy of other. The other trie must not be null. 79 96 * </p> 80 97 * … … 88 105 rootNode = new TrieNode<T>(other.rootNode); 89 106 knownSymbols = new LinkedHashSet<T>(other.knownSymbols); 107 comparator = other.comparator; 90 108 } 91 109 … … 120 138 for (T currentEvent : sequence) { 121 139 latestActions.add(currentEvent); 122 knownSymbols.add(currentEvent);140 addToKnownSymbols(currentEvent); 123 141 i++; 124 142 if (i >= maxOrder) { … … 143 161 protected void add(List<T> subsequence) { 144 162 if (subsequence != null && !subsequence.isEmpty()) { 145 knownSymbols.addAll(subsequence);163 addToKnownSymbols(subsequence); 146 164 subsequence = new LinkedList<T>(subsequence); // defensive copy! 147 165 T firstSymbol = subsequence.get(0); … … 306 324 /** 307 325 * <p> 326 * returns a list of symbol sequences which have a minimal length and that occurred most often 327 * with the same number of occurrences. The resulting list is empty, if there is no symbol 328 * sequence with the minimal length. 329 * </p> 330 * 331 * @param minimalLength the minimal length of the returned sequences 332 * 333 * @return as described 334 */ 335 public Collection<List<T>> getSequencesWithMostOccurrences(int minimalLength) { 336 LinkedList<TrieNode<T>> context = new LinkedList<TrieNode<T>>(); 337 Collection<List<TrieNode<T>>> paths = new LinkedList<List<TrieNode<T>>>(); 338 339 context.push(rootNode); 340 341 // traverse the trie and determine all sequences, which have the maximum number of 342 // occurrences and a minimal length. 343 344 // minimalLength + 1 because we denote the depth including the root node 345 determineLongPathsWithMostOccurrences(minimalLength + 1, paths, context); 346 347 Collection<List<T>> resultingPaths = new LinkedList<List<T>>(); 348 List<T> resultingPath; 349 350 if (paths.size() > 0) { 351 352 for (List<TrieNode<T>> path : paths) { 353 resultingPath = new LinkedList<T>(); 354 355 for (TrieNode<T> node : path) { 356 if (node.getSymbol() != null) { 357 resultingPath.add(node.getSymbol()); 358 } 359 } 360 361 resultingPaths.add(resultingPath); 362 } 363 } 364 365 return resultingPaths; 366 } 367 368 /** 369 * <p> 370 * Traverses the trie to collect all sequences with a maximum number of occurrences and with 371 * a minimal length. The length is encoded in the provided recursion depth. 372 * </p> 373 * 374 * @param minimalDepth the minimal recursion depth to be done 375 * @param paths the paths through the trie that all occurred with the same amount and 376 * that have the so far found maximum of occurrences (is updated each 377 * time a further path with the same number of occurrences is found; is 378 * replaced if a path with more occurrences is found) 379 * @param context the path through the trie, that is analyzed by the recursive call 380 */ 381 private void determineLongPathsWithMostOccurrences(int minimalDepth, 382 Collection<List<TrieNode<T>>> paths, 383 LinkedList<TrieNode<T>> context) 384 { 385 int maxCount = 0; 386 387 // only if we already reached the depth to be achieved, we check if the paths have the 388 // maximum number of occurrences 389 if (context.size() >= minimalDepth) { 390 391 // try to determine the maximum number of occurrences so far, if any 392 if (paths.size() > 0) { 393 List<TrieNode<T>> path = paths.iterator().next(); 394 maxCount = path.get(path.size() - 1).getCount(); 395 } 396 397 // if the current path has a higher number of occurrences than all so far, clear 398 // the paths collected so far and set the new number of occurrences as new maximum 399 if (context.getLast().getCount() > maxCount) { 400 paths.clear(); 401 maxCount = context.getLast().getCount(); 402 } 403 404 // if the path matches the current maximal number of occurrences, add it to the list 405 // of collected paths with these number of occurrences 406 if (context.getLast().getCount() == maxCount) { 407 paths.add(new LinkedList<TrieNode<T>>(context)); 408 } 409 } 410 411 // perform the trie traversal 412 for (TrieNode<T> child : context.getLast().getChildren()) { 413 if (child.getCount() >= maxCount) { 414 context.add(child); 415 determineLongPathsWithMostOccurrences(minimalDepth, paths, context); 416 context.removeLast(); 417 } 418 } 419 } 420 421 /** 422 * <p> 423 * adds a new symbol to the collection of known symbols if this symbol is not already 424 * contained. The symbols are compared using the comparator. 425 * </p> 426 * 427 * @param symbol the symbol to be added to the known symbols 428 */ 429 private void addToKnownSymbols(T symbol) { 430 for (T knownSymbol : knownSymbols) { 431 if (comparator.equals(knownSymbol, symbol)) { 432 return; 433 } 434 } 435 436 knownSymbols.add(symbol); 437 } 438 439 /** 440 * <p> 441 * adds a list of new symbols to the collection of known symbols. Uses the 442 * {@link #addToKnownSymbols(Object)} method for each element of the provided list. 443 * </p> 444 * 445 * @param symbols the list of symbols to be added to the known symbols 446 */ 447 private void addToKnownSymbols(List<T> symbols) { 448 for (T symbol : symbols) { 449 addToKnownSymbols(symbol); 450 } 451 } 452 453 /** 454 * <p> 308 455 * Helper class for graph visualization of a trie. 309 456 * </p> … … 441 588 knownSymbols = new HashSet<T>(); 442 589 for (TrieNode<T> node : rootNode.getChildren()) { 443 knownSymbols.add(node.getSymbol());590 addToKnownSymbols(node.getSymbol()); 444 591 } 445 592 } … … 478 625 return hash; 479 626 } 627 480 628 }
Note: See TracChangeset
for help on using the changeset viewer.