Changeset 1146 for trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRule.java
- Timestamp:
- 04/04/13 16:06:07 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRule.java
r1133 r1146 15 15 package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 16 16 17 import java.util.HashMap; 17 18 import java.util.Iterator; 18 19 import java.util.LinkedList; 19 20 import java.util.List; 20 21 21 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEquality; 22 import de.ugoe.cs.autoquest.tasktrees.nodeequality.NodeEqualityRuleManager; 22 import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEquality; 23 import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEqualityRuleManager; 24 import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; 23 25 import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; 24 26 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; 25 27 import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; 26 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeBuilder; 27 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode; 28 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeFactory; 28 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 29 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder; 30 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory; 31 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 32 import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList; 33 import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession; 34 import de.ugoe.cs.autoquest.usageprofiles.SymbolComparator; 29 35 import de.ugoe.cs.autoquest.usageprofiles.Trie; 30 36 import de.ugoe.cs.autoquest.usageprofiles.TrieProcessor; 31 37 import de.ugoe.cs.util.StopWatch; 32 import de.ugoe.cs.util.console.Console;33 38 34 39 /** … … 39 44 * @author Patrick Harms 40 45 */ 41 class SequenceForTaskDetectionRule implements TemporalRelationshipRule {46 class SequenceForTaskDetectionRule implements ISessionScopeRule { 42 47 43 48 /** 44 49 * <p> 45 * the task tree nodefactory to be used for creating substructures for the temporal50 * the task factory to be used for creating substructures for the temporal 46 51 * relationships identified during rule 47 52 * </p> 48 53 */ 49 private ITask TreeNodeFactory taskTreeNodeFactory;54 private ITaskFactory taskFactory; 50 55 /** 51 56 * <p> 52 * the task treebuilder to be used for creating substructures for the temporal relationships57 * the task builder to be used for creating substructures for the temporal relationships 53 58 * identified during rule application 54 59 * </p> 55 60 */ 56 private ITask TreeBuilder taskTreeBuilder;61 private ITaskBuilder taskBuilder; 57 62 58 63 /** 59 64 * <p> 60 * the node comparator to be used for comparing task tree nodes65 * the task comparator to be used for comparing tasks 61 66 * </p> 62 67 */ 63 private Task TreeNodeComparator nodeComparator;68 private TaskComparator taskComparator; 64 69 65 70 /** 66 71 * <p> 67 * instantiates the rule and initializes it with a nodeequality rule manager and the minimal68 * nodeequality identified sublist must have to consider them as iterated.72 * instantiates the rule and initializes it with a task equality rule manager and the minimal 73 * task equality identified sublist must have to consider them as iterated. 69 74 * </p> 70 75 */ 71 SequenceForTaskDetectionRule( NodeEqualityRuleManager nodeEqualityRuleManager,72 NodeEquality minimalNodeEquality,73 ITask TreeNodeFactory taskTreeNodeFactory,74 ITask TreeBuilder taskTreeBuilder)76 SequenceForTaskDetectionRule(TaskEqualityRuleManager taskEqualityRuleManager, 77 TaskEquality minimalTaskEquality, 78 ITaskFactory taskFactory, 79 ITaskBuilder taskBuilder) 75 80 { 76 this.taskTreeNodeFactory = taskTreeNodeFactory; 77 this.taskTreeBuilder = taskTreeBuilder; 78 79 this.nodeComparator = 80 new TaskTreeNodeComparator(nodeEqualityRuleManager, minimalNodeEquality); 81 this.taskFactory = taskFactory; 82 this.taskBuilder = taskBuilder; 83 84 this.taskComparator = new TaskComparator(taskEqualityRuleManager, minimalTaskEquality); 81 85 } 82 86 … … 89 93 } 90 94 91 /* 92 * (non-Javadoc) 93 * 94 * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode, 95 * boolean) 95 /* (non-Javadoc) 96 * @see de.ugoe.cs.autoquest.tasktrees.temporalrelation.ISessionScopeRule#apply(java.util.List) 96 97 */ 97 98 @Override 98 public RuleApplicationResult apply(ITaskTreeNode parent, boolean finalize) { 99 if (!(parent instanceof ISequence)) { 100 return null; 101 } 102 103 if (!finalize) { 104 // the rule is always feasible as tasks may occur at any time 105 RuleApplicationResult result = new RuleApplicationResult(); 106 result.setRuleApplicationStatus(RuleApplicationStatus.FEASIBLE); 107 return result; 108 } 109 110 List<ITaskTreeNode> children = parent.getChildren(); 111 List<ISequence> sessions = new LinkedList<ISequence>(); 112 113 for (ITaskTreeNode child : children) { 114 if (child instanceof ISequence) { 115 sessions.add((ISequence) child); 116 } 117 else { 118 Console.println("provided parent is no parent of sessions"); 119 return null; 120 } 121 } 122 99 public RuleApplicationResult apply(List<IUserSession> sessions) { 123 100 RuleApplicationData appData = new RuleApplicationData(sessions); 124 101 125 boolean finished = false;126 127 102 // this is the real rule application. Loop while something is replaced. 128 103 do { … … 137 112 appData.getStopWatch().stop("whole loop"); 138 113 139 //((TaskTreeNodeComparator) nodeComparator).getStopWatch().dumpStatistics(System.out);140 //((TaskTreeNodeComparator) nodeComparator).getStopWatch().reset();114 //((TaskTreeNodeComparator) taskComparator).getStopWatch().dumpStatistics(System.out); 115 //((TaskTreeNodeComparator) taskComparator).getStopWatch().reset(); 141 116 142 117 appData.getStopWatch().dumpStatistics(System.out); 143 118 appData.getStopWatch().reset(); 144 119 145 finished = (appData.getReplacementCounter() == 0); 146 } 147 while (!finished); 148 149 System.out.println("created " + appData.getResult().getNewlyCreatedParentNodes().size() + 150 " new parent nodes\n"); 151 152 if (appData.getResult().getNewlyCreatedParentNodes().size() > 0) { 120 } 121 while (appData.detectedAndReplacedTasks()); 122 123 System.out.println 124 ("created " + appData.getResult().getNewlyCreatedTasks().size() + 125 " new tasks and " + appData.getResult().getNewlyCreatedTaskInstances().size() + 126 " appropriate instances\n"); 127 128 if ((appData.getResult().getNewlyCreatedTasks().size() > 0) || 129 (appData.getResult().getNewlyCreatedTaskInstances().size() > 0)) 130 { 153 131 appData.getResult().setRuleApplicationStatus(RuleApplicationStatus.FINISHED); 154 132 } … … 164 142 appData.getStopWatch().start("detecting iterations"); 165 143 166 List<ISequence> sessions = appData.getSessions(); 167 int foundIterations = 0; 168 169 for (ISequence session : sessions) { 170 foundIterations += detectAndReplaceIterations(session, appData); 171 } 144 List<IUserSession> sessions = appData.getSessions(); 145 int iteratedTasks = 0; 146 147 ITask iteratedTask = null; 148 149 do { 150 iteratedTask = searchIteratedTask(sessions); 151 152 if (iteratedTask != null) { 153 replaceIterationsOf(iteratedTask, sessions, appData); 154 iteratedTasks++; 155 } 156 } 157 while (iteratedTask != null); 172 158 173 159 appData.getStopWatch().stop("detecting iterations"); 174 System.out.println(" --> found " + foundIterations); 175 } 176 177 /** 178 * @param appData 179 */ 180 private int detectAndReplaceIterations(ISequence session, 181 RuleApplicationData appData) 160 System.out.println(" --> found " + iteratedTasks + " iterated tasks"); 161 } 162 163 /** 164 * 165 */ 166 private ITask searchIteratedTask(List<IUserSession> sessions) { 167 for (IUserSession session : sessions) { 168 for (int i = 0; i < (session.size() - 1); i++) { 169 if (taskComparator.equals(session.get(i).getTask(), session.get(i + 1).getTask())) { 170 return session.get(i).getTask(); 171 } 172 } 173 } 174 175 return null; 176 } 177 178 /** 179 * 180 */ 181 private void replaceIterationsOf(ITask iteratedTask, 182 List<IUserSession> sessions, 183 RuleApplicationData appData) 182 184 { 183 int count = 0; 184 185 TemporalRelationshipRule rule = new SimpleIterationDetectionRule 186 (nodeComparator, taskTreeNodeFactory, taskTreeBuilder); 187 188 RuleApplicationResult result = rule.apply(session, true); 189 190 if ((result != null) && (result.getNewlyCreatedParentNodes() != null)) { 191 for (ITaskTreeNode newParent : result.getNewlyCreatedParentNodes()) { 192 appData.getResult().addNewlyCreatedParentNode(newParent); 193 if (newParent instanceof IIteration) { 194 count++; 195 } 196 } 197 } 198 199 return count; 185 IIteration iteration = taskFactory.createNewIteration(); 186 ITaskInstance iterationInstance = null; 187 188 List<ITaskInstance> iterationInstances = new LinkedList<ITaskInstance>(); 189 190 for (IUserSession session : sessions) { 191 int index = 0; 192 while (index < session.size()) { 193 if (taskComparator.equals(iteratedTask, session.get(index).getTask())) { 194 if (iterationInstance == null) { 195 iterationInstance = taskFactory.createNewTaskInstance(iteration); 196 iterationInstances.add(iterationInstance); 197 taskBuilder.addTaskInstance(session, index, iterationInstance); 198 index++; 199 } 200 201 taskBuilder.addChild(iterationInstance, session.get(index)); 202 taskBuilder.removeTaskInstance(session, index); 203 } 204 else { 205 if (iterationInstance != null) { 206 iterationInstance = null; 207 } 208 index++; 209 } 210 } 211 } 212 213 harmonizeIterationInstancesModel(iteration, iterationInstances); 214 } 215 216 /** 217 * <p> 218 * TODO: comment 219 * </p> 220 * 221 * @param iteratedTaskVariants 222 */ 223 private void harmonizeIterationInstancesModel(IIteration iteration, 224 List<ITaskInstance> iterationInstances) 225 { 226 List<ITask> iteratedTaskVariants = new LinkedList<ITask>(); 227 228 // merge the lexically different variants of iterated task to a unique list 229 for (ITaskInstance iterationInstance : iterationInstances) { 230 for (ITaskInstance executionVariant : iterationInstance) { 231 ITask candidate = executionVariant.getTask(); 232 233 boolean found = false; 234 for (ITask taskVariant : iteratedTaskVariants) { 235 if (taskComparator.areLexicallyEqual(taskVariant, candidate)) { 236 taskBuilder.setTask(executionVariant, taskVariant); 237 found = true; 238 break; 239 } 240 } 241 242 if (!found) { 243 iteratedTaskVariants.add(candidate); 244 } 245 } 246 } 247 248 // if there are more than one lexically different variant of iterated tasks, adapt the 249 // iteration model to be a selection of different variants. In this case also adapt 250 // the generated iteration instances to correctly contain selection instances. If there 251 // is only one variant of an iterated task, simply set this as the marked task of the 252 // iteration. In this case, the instances can be preserved as is 253 if (iteratedTaskVariants.size() > 1) { 254 ISelection selection = taskFactory.createNewSelection(); 255 256 for (ITask variant : iteratedTaskVariants) { 257 taskBuilder.addChild(selection, variant); 258 } 259 260 taskBuilder.setMarkedTask(iteration, selection); 261 262 for (ITaskInstance instance : iterationInstances) { 263 for (int i = 0; i < instance.size(); i++) { 264 ITaskInstance selectionInstance = taskFactory.createNewTaskInstance(selection); 265 taskBuilder.addChild(selectionInstance, instance.get(i)); 266 taskBuilder.setTaskInstance(instance, i, selectionInstance); 267 } 268 } 269 } 270 else { 271 taskBuilder.setMarkedTask(iteration, iteratedTaskVariants.get(0)); 272 } 200 273 } 201 274 … … 226 299 Tasks tasks; 227 300 boolean createNewTrie = (appData.getLastTrie() == null) || 228 appData. getReplacementCounter() > 0; // tree has changed301 appData.detectedAndReplacedTasks(); // tree has changed 229 302 230 303 do { … … 240 313 createNewTrie = false; 241 314 242 for (List<ITask TreeNode> task : tasks) {315 for (List<ITaskInstance> task : tasks) { 243 316 if (task.size() >= appData.getTrainedSequenceLength()) { 244 317 // Trie must be recreated with a longer sequence length to be sure that … … 267 340 268 341 appData.getStopWatch().start("training trie"); 269 appData.setLastTrie(new Trie<ITask TreeNode>(nodeComparator));342 appData.setLastTrie(new Trie<ITaskInstance>(taskComparator)); 270 343 271 List<I Sequence> sessions = appData.getSessions();272 273 for (I Sequencesession : sessions) {344 List<IUserSession> sessions = appData.getSessions(); 345 346 for (IUserSession session : sessions) { 274 347 trainTrie(session, appData); 275 348 } … … 282 355 * @param parent 283 356 */ 284 private void trainTrie(I Sequencesession, RuleApplicationData appData) {285 List<ITask TreeNode> children = session.getChildren();357 private void trainTrie(IUserSession session, RuleApplicationData appData) { 358 List<ITaskInstance> children = session.getExecutedTasks(); 286 359 287 360 if ((children != null) && (children.size() > 0)) { … … 294 367 */ 295 368 private void replaceSequencesOccurringMostOften(RuleApplicationData appData) { 296 appData. resetReplacementCounter();369 appData.detectedAndReplacedTasks(false); 297 370 298 371 if ((appData.getLastFoundTasks().size() > 0) && 299 372 (appData.getLastFoundTasks().getOccurrenceCount() > 1)) 300 373 { 301 System.out.println("replacing tasks occurrences with merged variants of all versions"); 302 303 for (List<ITaskTreeNode> task : appData.getLastFoundTasks()) { 304 String taskId = "task " + RuleUtils.getNewId(); 305 System.out.println("replacing " + taskId + ": " + task); 306 307 appData.clearTaskOccurrences(); 308 determineVariantsOfTaskOccurrences(task, appData.getSessions(), appData); 309 310 appData.getStopWatch().start("merging task nodes"); 311 ITaskTreeNode taskReplacement = mergeVariantsOfTaskOccurrence(taskId, appData); 312 appData.getStopWatch().stop("merging task nodes"); 313 314 appData.resetReplacementCounter(); 315 replaceTaskOccurrences(task, taskReplacement, appData.getSessions(), appData); 316 317 if (appData.getReplacementCounter() > 0) { 318 appData.getResult().addNewlyCreatedParentNode(taskReplacement); 319 } 320 321 if (appData.getReplacementCounter() < 322 appData.getLastFoundTasks().getOccurrenceCount()) 323 { 324 System.out.println(taskId + ": replaced task only " + 325 appData.getReplacementCounter() + 326 " times instead of expected " + 374 System.out.println("replacing tasks occurrences"); 375 376 for (List<ITaskInstance> task : appData.getLastFoundTasks()) { 377 ISequence sequence = taskFactory.createNewSequence(); 378 379 System.out.println("replacing " + sequence.getId() + ": " + task); 380 381 List<ITaskInstance> sequenceInstances = 382 replaceTaskOccurrences(task, appData.getSessions(), sequence); 383 384 harmonizeSequenceInstancesModel(sequence, sequenceInstances,task.size()); 385 appData.detectedAndReplacedTasks(sequenceInstances.size() > 0); 386 387 if (sequenceInstances.size() < appData.getLastFoundTasks().getOccurrenceCount()) { 388 System.out.println(sequence.getId() + ": replaced task only " + 389 sequenceInstances.size() + " times instead of expected " + 327 390 appData.getLastFoundTasks().getOccurrenceCount()); 328 391 } … … 333 396 334 397 /** 335 * @param tree336 */ 337 private void determineVariantsOfTaskOccurrences(List<ITaskTreeNode> task,338 List<ISequence> sessions,339 RuleApplicationData appData)398 * 399 */ 400 private void harmonizeSequenceInstancesModel(ISequence sequence, 401 List<ITaskInstance> sequenceInstances, 402 int sequenceLength) 340 403 { 341 for (ISequence session : sessions) { 342 int index = -1; 343 344 List<ITaskTreeNode> children = session.getChildren(); 345 346 do { 347 index = getSubListIndex(children, task, ++index); 348 349 if (index > -1) { 350 ISequence taskOccurrence = RuleUtils.getSubSequenceInRange 351 (session, index, index + task.size() - 1, null, 352 taskTreeNodeFactory, taskTreeBuilder); 353 354 appData.addTaskOccurrence(taskOccurrence); 355 356 // let the index point to the last element the belongs the identified occurrence 357 index += task.size() - 1; 358 } 359 } 360 while (index > -1); 361 } 362 } 363 364 /** 365 * @param appData 366 * @return 367 */ 368 private ITaskTreeNode mergeVariantsOfTaskOccurrence(String taskId, 369 RuleApplicationData appData) 370 { 371 return mergeVariantsOfTasks(taskId, appData.getTaskOccurrences()); 372 } 373 374 /** 375 * @param appData 376 * @return 377 */ 378 private ITaskTreeNode mergeVariantsOfTasks(String description, List<ITaskTreeNode> variants) { 379 // merge but preserve lexically distinct variants 380 TaskTreeNodeMerger merger = new TaskTreeNodeMerger 381 (taskTreeNodeFactory, taskTreeBuilder, nodeComparator); 382 383 merger.mergeTaskNodes(variants); 384 385 if (variants.size() == 1) { 386 ITaskTreeNode replacement = variants.get(0); 387 taskTreeBuilder.setDescription(replacement, description); 388 return replacement; 389 } 390 else { 391 ISelection selection = taskTreeNodeFactory.createNewSelection(); 392 taskTreeBuilder.setDescription(selection, "variants of task " + description); 393 394 for (ITaskTreeNode variant : variants) { 395 taskTreeBuilder.addChild(selection, variant); 396 } 397 398 return selection; 399 } 400 } 401 402 /** 403 * @param task 404 * @param parent 405 * @param treeBuilder 406 * @param nodeFactory 407 * @param result 408 */ 409 private void replaceTaskOccurrences(List<ITaskTreeNode> task, 410 ITaskTreeNode replacement, 411 List<ISequence> sessions, 412 RuleApplicationData appData) 413 { 414 // now check the children themselves for an occurrence of the task 415 for (int i = 0; i < sessions.size(); i++) { 416 ISequence session = sessions.get(i); 417 418 int index = -1; 419 420 List<ITaskTreeNode> children = session.getChildren(); 421 422 do { 423 index = getSubListIndex(children, task, ++index); 424 425 if (index > -1) { 426 if ((!(replacement instanceof ISequence)) || 427 (task.size() < children.size())) 428 { 429 for (int j = index; j < index + task.size(); j++) { 430 taskTreeBuilder.removeChild(session, index); 431 } 432 433 taskTreeBuilder.addChild(session, index, replacement); 434 appData.incrementReplacementCounter(); 435 436 children = session.getChildren(); 437 } 438 else { 439 // the whole list of children is an occurrence of this task. So ask the 440 // caller of the method to replace the whole node 441 sessions.set(i, (ISequence) replacement); 442 appData.incrementReplacementCounter(); 404 405 // ensure for each subtask that lexically different variants are preserved 406 for (int subTaskIndex = 0; subTaskIndex < sequenceLength; subTaskIndex++) { 407 List<ITask> subTaskVariants = new LinkedList<ITask>(); 408 409 for (ITaskInstance sequenceInstance : sequenceInstances) { 410 ITask candidate = sequenceInstance.get(subTaskIndex).getTask(); 411 412 boolean found = false; 413 414 for (int i = 0; i < subTaskVariants.size(); i++) { 415 if (taskComparator.areLexicallyEqual(subTaskVariants.get(i), candidate)) { 416 taskBuilder.setTask 417 (sequenceInstance.get(subTaskIndex), subTaskVariants.get(i)); 418 419 found = true; 443 420 break; 444 421 } 445 422 } 423 424 if (!found) { 425 subTaskVariants.add(candidate); 426 } 427 } 428 429 // if there are more than one lexically different variant of the sub task at 430 // the considered position, adapt the sequence model at that position to have 431 // a selection of the different variants. In this case also adapt the 432 // generated sequence instances to correctly contain selection instances. If 433 // there is only one variant of sub tasks at the given position, simply set 434 // this variant as the sub task of the selection. In this case, the instances 435 // can be preserved as is 436 if (subTaskVariants.size() > 1) { 437 ISelection selection = taskFactory.createNewSelection(); 438 439 for (ITask variant : subTaskVariants) { 440 taskBuilder.addChild(selection, variant); 441 } 442 443 taskBuilder.addChild(sequence, selection); 444 445 for (ITaskInstance instance : sequenceInstances) { 446 ITaskInstance selectionInstance = 447 taskFactory.createNewTaskInstance(selection); 448 taskBuilder.addChild(selectionInstance, instance.get(subTaskIndex)); 449 taskBuilder.setTaskInstance(instance, subTaskIndex, selectionInstance); 450 } 451 } 452 else if (subTaskVariants.size() == 1) { 453 taskBuilder.addChild(sequence, subTaskVariants.get(0)); 454 } 455 } 456 } 457 458 /** 459 * @param tree 460 */ 461 private List<ITaskInstance> replaceTaskOccurrences(List<ITaskInstance> task, 462 List<IUserSession> sessions, 463 ISequence temporalTaskModel) 464 { 465 List<ITaskInstance> sequenceInstances = new LinkedList<ITaskInstance>(); 466 467 for (IUserSession session : sessions) { 468 int index = -1; 469 470 do { 471 index = getSubListIndex(session, task, ++index); 472 473 if (index > -1) { 474 sequenceInstances.add 475 (RuleUtils.createNewSubSequenceInRange 476 (session, index, index + task.size() - 1, temporalTaskModel, 477 taskFactory, taskBuilder)); 478 } 446 479 } 447 480 while (index > -1); 448 481 } 482 483 return sequenceInstances; 449 484 } 450 485 … … 454 489 * @return 455 490 */ 456 private int getSubListIndex( List<ITaskTreeNode>list,457 List<ITask TreeNode> subList,491 private int getSubListIndex(ITaskInstanceList list, 492 List<ITaskInstance> subList, 458 493 int startIndex) 459 494 { … … 465 500 466 501 for (int j = 0; j < subList.size(); j++) { 467 if (! nodeComparator.equals(list.get(i + j), subList.get(j))) {502 if (!taskComparator.equals(list.get(i + j), subList.get(j))) { 468 503 matchFound = false; 469 504 break; … … 479 514 return result; 480 515 } 516 517 /** 518 * @param trie 519 * @param object 520 * @return 521 */ 522 private int getSubListIndex(List<ITaskInstance> list, 523 List<ITaskInstance> subList, 524 int startIndex) 525 { 526 boolean matchFound; 527 int result = -1; 528 529 for (int i = startIndex; i <= list.size() - subList.size(); i++) { 530 matchFound = true; 531 532 for (int j = 0; j < subList.size(); j++) { 533 if (!taskComparator.equals(list.get(i + j), subList.get(j))) { 534 matchFound = false; 535 break; 536 } 537 } 538 539 if (matchFound) { 540 result = i; 541 break; 542 } 543 } 544 545 return result; 546 } 481 547 482 548 /** 483 549 * @author Patrick Harms 484 550 */ 485 private class MaxCountAndLongestTasksFinder implements TrieProcessor<ITask TreeNode> {551 private class MaxCountAndLongestTasksFinder implements TrieProcessor<ITaskInstance> { 486 552 487 553 /** … … 493 559 * 494 560 */ 495 private List<List<ITask TreeNode>> foundTasks = new LinkedList<List<ITaskTreeNode>>();561 private List<List<ITaskInstance>> foundTasks = new LinkedList<List<ITaskInstance>>(); 496 562 497 563 /** … … 507 573 */ 508 574 @Override 509 public TrieProcessor.Result process(List<ITask TreeNode> task, int count) {510 if ( task.size() < 2) {511 // ignore single nodes575 public TrieProcessor.Result process(List<ITaskInstance> foundTask, int count) { 576 if (foundTask.size() < 2) { 577 // ignore single tasks 512 578 return TrieProcessor.Result.CONTINUE; 513 579 } … … 519 585 520 586 if (this.currentCount > count) { 521 // ignore this children of this node, as they may have only smaller counts than587 // ignore this children of this task, as they may have only smaller counts than 522 588 // the already found tasks 523 589 return TrieProcessor.Result.SKIP_NODE; … … 536 602 boolean added = false; 537 603 for (int i = 0; i < foundTasks.size(); i++) { 538 if (foundTasks.get(i).size() < task.size()) {604 if (foundTasks.get(i).size() < foundTask.size()) { 539 605 // defensive copy 540 foundTasks.add(i, new LinkedList<ITask TreeNode>(task)); // defensive copy606 foundTasks.add(i, new LinkedList<ITaskInstance>(foundTask)); // defensive copy 541 607 added = true; 542 608 break; … … 545 611 546 612 if (!added) { 547 foundTasks.add(new LinkedList<ITask TreeNode>(task)); // defensive copy613 foundTasks.add(new LinkedList<ITaskInstance>(foundTask)); // defensive copy 548 614 } 549 615 } … … 571 637 // found a task that is a potential subtask. Check for this and remove the 572 638 // subtask if needed 573 List<ITask TreeNode> longTask = foundTasks.get(i);574 List<ITask TreeNode> shortTask = foundTasks.get(j);639 List<ITaskInstance> longTask = foundTasks.get(i); 640 List<ITaskInstance> shortTask = foundTasks.get(j); 575 641 576 642 if (getSubListIndex(longTask, shortTask, 0) > -1) { … … 598 664 * 599 665 */ 600 private List<I Sequence> sessions;601 602 /** 603 * 604 */ 605 private Trie<ITask TreeNode> lastTrie;666 private List<IUserSession> sessions; 667 668 /** 669 * 670 */ 671 private Trie<ITaskInstance> lastTrie; 606 672 607 673 /** … … 618 684 * 619 685 */ 620 private List<ITaskTreeNode> taskOccurrences = new LinkedList<ITaskTreeNode>(); 621 622 /** 623 * 624 */ 625 private int replacementCounter; 686 private boolean detectedAndReplacedTasks; 626 687 627 688 /** … … 638 699 * 639 700 */ 640 private RuleApplicationData(List<I Sequence> sessions) {701 private RuleApplicationData(List<IUserSession> sessions) { 641 702 this.sessions = sessions; 642 703 } … … 645 706 * @return the tree 646 707 */ 647 private List<I Sequence> getSessions() {708 private List<IUserSession> getSessions() { 648 709 return sessions; 649 710 } … … 652 713 * @param lastTrie the lastTrie to set 653 714 */ 654 private void setLastTrie(Trie<ITask TreeNode> lastTrie) {715 private void setLastTrie(Trie<ITaskInstance> lastTrie) { 655 716 this.lastTrie = lastTrie; 656 717 } … … 659 720 * @return the lastTrie 660 721 */ 661 private Trie<ITask TreeNode> getLastTrie() {722 private Trie<ITaskInstance> getLastTrie() { 662 723 return lastTrie; 663 724 } … … 692 753 693 754 /** 694 * @return the taskOccurrences695 */696 private void clearTaskOccurrences() {697 taskOccurrences.clear();698 }699 700 /**701 * @return the taskOccurrences702 */703 private void addTaskOccurrence(ITaskTreeNode taskOccurrence) {704 taskOccurrences.add(taskOccurrence);705 }706 707 /**708 * @return the taskOccurrences709 */710 private List<ITaskTreeNode> getTaskOccurrences() {711 return taskOccurrences;712 }713 714 /**715 755 * 716 756 */ 717 private void resetReplacementCounter() {718 replacementCounter = 0;757 private void detectedAndReplacedTasks(boolean detectedAndReplacedTasks) { 758 this.detectedAndReplacedTasks = detectedAndReplacedTasks; 719 759 } 720 760 … … 722 762 * 723 763 */ 724 private void incrementReplacementCounter() { 725 replacementCounter++; 726 } 727 728 /** 729 * 730 */ 731 private int getReplacementCounter() { 732 return replacementCounter; 764 private boolean detectedAndReplacedTasks() { 765 return detectedAndReplacedTasks; 733 766 } 734 767 … … 753 786 * @author Patrick Harms 754 787 */ 755 private static class Tasks implements Iterable<List<ITask TreeNode>> {788 private static class Tasks implements Iterable<List<ITaskInstance>> { 756 789 757 790 /** … … 763 796 * 764 797 */ 765 private List<List<ITask TreeNode>> sequences;798 private List<List<ITaskInstance>> sequences; 766 799 767 800 /** … … 769 802 * @param sequences 770 803 */ 771 private Tasks(int occurrenceCount, List<List<ITask TreeNode>> sequences) {804 private Tasks(int occurrenceCount, List<List<ITaskInstance>> sequences) { 772 805 super(); 773 806 this.occurrenceCount = occurrenceCount; … … 797 830 */ 798 831 @Override 799 public Iterator<List<ITask TreeNode>> iterator() {832 public Iterator<List<ITaskInstance>> iterator() { 800 833 return this.sequences.iterator(); 801 834 } … … 803 836 } 804 837 838 /** 839 * 840 */ 841 private class TaskComparator implements SymbolComparator<ITaskInstance> { 842 843 /** */ 844 private Comparer comparer; 845 846 /** */ 847 private Comparer lexicalComparer; 848 849 /** */ 850 private HashMap<Long, Boolean> equalityBuffer = new HashMap<Long, Boolean>(); 851 852 /** */ 853 private HashMap<Long, Boolean> lexicalEqualityBuffer; 854 855 /** 856 * 857 */ 858 public TaskComparator(TaskEqualityRuleManager taskEqualityRuleManager, 859 TaskEquality minimalNodeEquality) 860 { 861 super(); 862 863 if (minimalNodeEquality == TaskEquality.LEXICALLY_EQUAL) { 864 comparer = new LexicalComparer(taskEqualityRuleManager); 865 } 866 else if (minimalNodeEquality == TaskEquality.SYNTACTICALLY_EQUAL) { 867 comparer = new SyntacticalComparer(taskEqualityRuleManager); 868 } 869 else if (minimalNodeEquality == TaskEquality.SEMANTICALLY_EQUAL) { 870 comparer = new SemanticalComparer(taskEqualityRuleManager); 871 } 872 else { 873 comparer = new DefaultComparer(taskEqualityRuleManager, minimalNodeEquality); 874 } 875 876 if (minimalNodeEquality == TaskEquality.LEXICALLY_EQUAL) { 877 lexicalComparer = comparer; 878 lexicalEqualityBuffer = equalityBuffer; 879 } 880 else { 881 lexicalComparer = new LexicalComparer(taskEqualityRuleManager); 882 lexicalEqualityBuffer = new HashMap<Long, Boolean>(); 883 } 884 } 885 886 /* (non-Javadoc) 887 * @see de.ugoe.cs.autoquest.tasktrees.temporalrelation.SymbolComparator#equals(java.lang.Object, java.lang.Object) 888 */ 889 @Override 890 public boolean equals(ITaskInstance taskInstance1, ITaskInstance taskInstance2) { 891 return equals(taskInstance1.getTask(), taskInstance2.getTask()); 892 } 893 894 /** 895 * 896 */ 897 public boolean equals(ITask task1, ITask task2) { 898 Boolean result; 899 900 if (task1 != task2) { 901 if ((task1 instanceof IEventTask) && (task2 instanceof IEventTask)) { 902 long key = ((long) System.identityHashCode(task1)) << 32; 903 key += System.identityHashCode(task2); 904 905 result = equalityBuffer.get(key); 906 907 if (result == null) { 908 result = comparer.compare(task1, task2); 909 equalityBuffer.put(key, result); 910 } 911 } 912 else { 913 result = false; 914 } 915 } 916 else { 917 result = true; 918 } 919 920 return result; 921 } 922 923 /** 924 * 925 */ 926 public boolean areLexicallyEqual(ITask task1, ITask task2) { 927 Boolean result; 928 929 if (task1 != task2) { 930 long key = ((long) System.identityHashCode(task1)) << 32; 931 key += System.identityHashCode(task2); 932 933 result = lexicalEqualityBuffer.get(key); 934 935 if (result == null) { 936 result = lexicalComparer.compare(task1, task2); 937 lexicalEqualityBuffer.put(key, result); 938 } 939 } 940 else { 941 result = true; 942 } 943 944 return result; 945 } 946 } 947 948 /** 949 * 950 */ 951 private interface Comparer { 952 953 /** 954 * 955 */ 956 boolean compare(ITask task1, ITask task2); 957 } 958 959 /** 960 * 961 */ 962 private class LexicalComparer implements Comparer { 963 964 /** 965 * <p> 966 * the task equality manager needed for comparing tasks with each other 967 * </p> 968 */ 969 private TaskEqualityRuleManager taskEqualityRuleManager; 970 971 /** 972 * 973 */ 974 public LexicalComparer(TaskEqualityRuleManager taskEqualityRuleManager) { 975 this.taskEqualityRuleManager = taskEqualityRuleManager; 976 } 977 978 /** 979 * 980 */ 981 public boolean compare(ITask task1, ITask task2) { 982 return taskEqualityRuleManager.areLexicallyEqual(task1, task2); 983 } 984 } 985 986 /** 987 * 988 */ 989 private class SyntacticalComparer implements Comparer { 990 991 /** 992 * <p> 993 * the task equality manager needed for comparing tasks with each other 994 * </p> 995 */ 996 private TaskEqualityRuleManager taskEqualityRuleManager; 997 998 /** 999 * 1000 */ 1001 public SyntacticalComparer(TaskEqualityRuleManager taskEqualityRuleManager) { 1002 this.taskEqualityRuleManager = taskEqualityRuleManager; 1003 } 1004 1005 /** 1006 * 1007 */ 1008 public boolean compare(ITask task1, ITask task2) { 1009 return taskEqualityRuleManager.areSyntacticallyEqual(task1, task2); 1010 } 1011 } 1012 1013 /** 1014 * 1015 */ 1016 private class SemanticalComparer implements Comparer { 1017 1018 /** 1019 * <p> 1020 * the task equality manager needed for comparing tasks with each other 1021 * </p> 1022 */ 1023 private TaskEqualityRuleManager taskEqualityRuleManager; 1024 1025 /** 1026 * 1027 */ 1028 public SemanticalComparer(TaskEqualityRuleManager taskEqualityRuleManager) { 1029 this.taskEqualityRuleManager = taskEqualityRuleManager; 1030 } 1031 1032 /** 1033 * 1034 */ 1035 public boolean compare(ITask task1, ITask task2) { 1036 return taskEqualityRuleManager.areSemanticallyEqual(task1, task2); 1037 } 1038 } 1039 1040 /** 1041 * 1042 */ 1043 private class DefaultComparer implements Comparer { 1044 1045 /** 1046 * <p> 1047 * the task equality manager needed for comparing tasks with each other 1048 * </p> 1049 */ 1050 private TaskEqualityRuleManager taskEqualityRuleManager; 1051 1052 /** 1053 * <p> 1054 * the minimal task equality two identified sublists need to have to consider them as equal 1055 * </p> 1056 */ 1057 private TaskEquality minimalNodeEquality; 1058 1059 /** 1060 * 1061 */ 1062 public DefaultComparer(TaskEqualityRuleManager taskEqualityRuleManager, 1063 TaskEquality minimalNodeEquality) 1064 { 1065 this.taskEqualityRuleManager = taskEqualityRuleManager; 1066 this.minimalNodeEquality = minimalNodeEquality; 1067 } 1068 1069 /** 1070 * 1071 */ 1072 public boolean compare(ITask task1, ITask task2) { 1073 return taskEqualityRuleManager.areAtLeastEqual(task1, task2, minimalNodeEquality); 1074 } 1075 } 805 1076 }
Note: See TracChangeset
for help on using the changeset viewer.