Changeset 1981
- Timestamp:
- 06/30/15 10:22:55 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/utils/MostSimilarTaskDeterminer.java
r1975 r1981 15 15 package de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils; 16 16 17 import java.util.ArrayList; 18 import java.util.Collections; 19 import java.util.Comparator; 17 20 import java.util.HashMap; 18 21 import java.util.HashSet; … … 58 61 59 62 /** 60 * If this similarity level is exceeded, two tasks are not considered similar anymore. 33means61 * that at most 33% of the elements of both task traversals are not the same.62 */ 63 private static int MAX_DIFF_LEVEL = 33;63 * If this similarity level is exceeded, two tasks are not considered similar anymore. 25 means 64 * that at most 25% of the elements of both task traversals are not the same. 65 */ 66 private static int MAX_DIFF_LEVEL = 25; 64 67 65 68 /** … … 144 147 } 145 148 146 Console.println("smallest diff level is " + smallestDiffLevel); 149 Console.println("smallest diff level is " + smallestDiffLevel + " (max is " + 150 MAX_DIFF_LEVEL + ")"); 147 151 } 148 152 else { … … 200 204 */ 201 205 private void applyFilterForMostCoveredEvents(LinkedList<SimilarTasks> mostSimilarTasksList, 202 ITaskModeltaskModel)206 final ITaskModel taskModel) 203 207 { 204 for (SimilarTasks similarTasks : mostSimilarTasksList) { 205 System.out.println(similarTasks.getLeftHandSide() + " " + similarTasks.getRightHandSide()); 206 } 207 208 // check, if several remaining similar tasks refer to the same task 209 Map<ITask, LinkedList<SimilarTasks>> referredTasks = 210 new HashMap<ITask, LinkedList<SimilarTasks>>(); 211 212 for (SimilarTasks similarTasks : mostSimilarTasksList) { 213 ensureMapping(similarTasks.getLeftHandSide(), similarTasks, referredTasks); 214 ensureMapping(similarTasks.getRightHandSide(), similarTasks, referredTasks); 215 } 216 217 // remove all entries of tasks occurring only once 218 List<ITask> tasksOccuringOnce = new LinkedList<ITask>(); 219 220 for (Map.Entry<ITask, LinkedList<SimilarTasks>> entry : referredTasks.entrySet()) { 221 if (entry.getValue().size() <= 1) { 222 tasksOccuringOnce.add(entry.getKey()); 223 } 224 } 225 226 for (ITask taskToRemove : tasksOccuringOnce) { 227 referredTasks.remove(taskToRemove); 228 } 229 230 // if there are remaining tasks occurring several times, try to extract one similar tasks 231 // object, that should be merged first 232 233 if (referredTasks.size() > 0) { 234 mostSimilarTasksList.clear(); 235 236 Console.traceln(Level.FINEST, "several comparisons for the same task exist with " + 237 "same diff level --> filtering for pair to be merged first"); 238 239 SimilarTasks firstToMerge = null; 240 241 for (LinkedList<SimilarTasks> pairs : referredTasks.values()) { 242 for (SimilarTasks current : pairs) { 243 if (firstToMerge == null) { 244 firstToMerge = current; 208 List<SimilarTasks> sortedList = new ArrayList<>(mostSimilarTasksList); 209 210 // sort the list of similar tasks based on which to merge first 211 Collections.sort(sortedList, new Comparator<SimilarTasks>() { 212 @Override 213 public int compare(SimilarTasks first, SimilarTasks second) { 214 SimilarTasks toMergeFirst = getFirstToMerge(first, second, taskModel); 215 216 if (toMergeFirst == first) { 217 return -1; 218 } 219 else if (toMergeFirst == null) { 220 return 0; 221 } 222 else { 223 return 1; 224 } 225 } 226 }); 227 228 // the first in the ordered list is the first to merge, except there are several 229 // firsts in the lists for which it can not be decided which to merge first 230 231 // now remove all subsequent pairs also referring tasks referred by first pairs 232 Set<ITask> referredTasks = new HashSet<>(); 233 234 int index = 0; 235 while (index < sortedList.size()) { 236 SimilarTasks pair = sortedList.get(index); 237 238 if (referredTasks.contains(pair.getLeftHandSide()) || 239 referredTasks.contains(pair.getRightHandSide())) 240 { 241 // we found a pair that refers to a task already referred by a preceding pair. 242 // The pair can be removed, if the previous pair referring to the same task also 243 // is to be merged first. 244 for (int i = 0; i < index; i++) { 245 SimilarTasks previousPair = sortedList.get(i); 246 if ((previousPair.getLeftHandSide() == pair.getLeftHandSide()) || 247 (previousPair.getLeftHandSide() == pair.getRightHandSide()) || 248 (previousPair.getRightHandSide() == pair.getLeftHandSide()) || 249 (previousPair.getRightHandSide() == pair.getRightHandSide())) 250 { 251 if (getFirstToMerge(previousPair, pair, taskModel) == null) { 252 for (SimilarTasks tmp : sortedList) { 253 tmp.dump(System.out); 254 } 255 256 throw new RuntimeException("several tasks are similar so that it is " + 257 "undecidable which to merge first"); 258 } 245 259 } 246 else if (firstToMerge != current) { 247 firstToMerge = getFirstToMerge(firstToMerge, current, taskModel); 248 } 249 } 250 } 251 252 if (firstToMerge != null) { 253 mostSimilarTasksList.add(firstToMerge); 254 } 255 } 256 260 } 261 262 sortedList.remove(index); 263 } 264 else { 265 referredTasks.add(pair.getLeftHandSide()); 266 referredTasks.add(pair.getRightHandSide()); 267 index++; 268 } 269 } 270 271 // now the list is sorted and contains at most one pair for each task referred multiple 272 // times 273 mostSimilarTasksList.clear(); 274 mostSimilarTasksList.addAll(sortedList); 257 275 } 258 276 … … 327 345 return first; 328 346 } 329 330 first.dump(System.out); 331 second.dump(System.out); 332 333 throw new RuntimeException 334 ("several tasks are similar so that it is undecidable which to merge first"); 335 } 336 337 /** 338 * 339 */ 340 private void ensureMapping(ITask task, 341 SimilarTasks similarTasks, 342 Map<ITask, LinkedList<SimilarTasks>> map) 343 { 344 LinkedList<SimilarTasks> value = map.get(task); 345 346 if (value == null) { 347 value = new LinkedList<SimilarTasks>(); 348 map.put(task, value); 349 } 350 351 value.add(similarTasks); 352 } 353 347 348 // it may be the case that both tasks are event identical. For example, if through a 349 // merge formerly different children became the same. In this case, merging can be 350 // done in any order. Hence, just return any of the given to be merged first. To ensure 351 // to not define a circle of three tasks to be merged, decide using the ids of the 352 // identical tasks. 353 if ((first.getDiffLevel() == 0) && (second.getDiffLevel() == 0)) { 354 ITask taskWithSmallestId = first.getLeftHandSide(); 355 SimilarTasks pairToReturn = first; 356 357 if (taskWithSmallestId.getId() > first.getRightHandSide().getId()) { 358 taskWithSmallestId = first.getRightHandSide(); 359 } 360 361 if (taskWithSmallestId.getId() > second.getLeftHandSide().getId()) { 362 taskWithSmallestId = second.getLeftHandSide(); 363 pairToReturn = second; 364 } 365 366 if (taskWithSmallestId.getId() > second.getRightHandSide().getId()) { 367 taskWithSmallestId = second.getRightHandSide(); 368 pairToReturn = second; 369 } 370 371 return pairToReturn; 372 } 373 374 return null; 375 } 354 376 355 377 /** … … 357 379 */ 358 380 private LinkedList<SimilarTasks> performComparisons(ITaskModel taskModel, List<ITask> tasks) { 381 Set<ITask> mostProminentTasks = getMostProminentTasks(taskModel, tasks); 359 382 LinkedList<SimilarTasks> mostSimilarTasks = new LinkedList<SimilarTasks>(); 360 383 List<Runnable> startedRunnables = new LinkedList<Runnable>(); … … 412 435 Runnable runnable = new CompareRunnable(taskModel, leftHandTraversals, 413 436 rightHandTraversals, 437 mostProminentTasks, 414 438 mostSimilarTasks, startedRunnables); 415 439 … … 468 492 469 493 /** 494 * 495 */ 496 private Set<ITask> getMostProminentTasks(ITaskModel model, List<ITask> tasks) { 497 Map<Integer, List<ITask>> sortedTasks = new HashMap<>(); 498 499 int maxCoverage = 0; 500 501 for (ITask task : tasks) { 502 int coveredEvents = model.getTaskInfo(task).getMeasureValue(TaskMetric.EVENT_COVERAGE); 503 504 List<ITask> tasksWithSameCoverage = sortedTasks.get(coveredEvents); 505 506 if (tasksWithSameCoverage == null) { 507 tasksWithSameCoverage = new LinkedList<>(); 508 sortedTasks.put(coveredEvents, tasksWithSameCoverage); 509 } 510 511 tasksWithSameCoverage.add(task); 512 513 maxCoverage = Math.max(maxCoverage, coveredEvents); 514 } 515 516 Set<ITask> result = new HashSet<>(); 517 518 for (int i = maxCoverage; i > 0; i--) { 519 List<ITask> tasksWithSameCoverage = sortedTasks.get(i); 520 521 if (tasksWithSameCoverage != null) { 522 result.addAll(tasksWithSameCoverage); 523 524 if (result.size() * 5 >= tasks.size()) { 525 break; 526 } 527 } 528 } 529 530 return result; 531 } 532 533 /** 470 534 * convenience method to get the value of a task metric 471 535 */ … … 539 603 540 604 /** */ 605 private Set<ITask> mostProminentTasks; 606 607 /** */ 541 608 private List<SimilarTasks> mostSimilarTasksList; 542 609 … … 550 617 TaskTraversal[] leftHandTraversals, 551 618 TaskTraversal[] rightHandTraversals, 619 Set<ITask> mostProminentTasks, 552 620 List<SimilarTasks> mostSimilarTasksList, 553 621 List<Runnable> unfinishedRunnables) … … 556 624 this.leftHandTraversals = leftHandTraversals; 557 625 this.rightHandTraversals = rightHandTraversals; 626 this.mostProminentTasks = mostProminentTasks; 558 627 this.mostSimilarTasksList = mostSimilarTasksList; 559 628 this.unfinishedRunnables = unfinishedRunnables; … … 585 654 continue LEFT_HAND_TRAVERSAL; 586 655 } 587 656 588 657 counter++; 589 658 … … 598 667 effectiveComparisons++; 599 668 600 SimilarTasks similarTasks 1= SimilarTasks.compareTraversals669 SimilarTasks similarTasks = SimilarTasks.compareTraversals 601 670 (leftHandTraversals[i], rightHandTraversals[j], comparator); 602 671 603 SimilarTasks similarTasks2 = SimilarTasks.compareTraversals 604 (rightHandTraversals[j], leftHandTraversals[i], comparator); 605 606 if ((similarTasks1.getDiffLevel() <= mostSimilarDiffLevel) || 607 (similarTasks2.getDiffLevel() <= mostSimilarDiffLevel)) 672 if (similarTasks.getDiffLevel() > 0) { 673 if (!mostProminentTasks.contains(leftHandTask) || 674 !mostProminentTasks.contains(rightHandTask)) 675 { 676 // the tasks are not fully identical. Hence, we merge them only, 677 // if both are most prominent ones. If they were fully identical, 678 // they may have changed through merging initially different 679 // children which may have become the same. In that case, they 680 // must be merged even if they are not most prominent. 681 continue RIGHT_HAND_TRAVERSAL; 682 } 683 684 SimilarTasks similarTasks2 = SimilarTasks.compareTraversals 685 (rightHandTraversals[j], leftHandTraversals[i], comparator); 686 687 if ((similarTasks.getDiffLevel() <= mostSimilarDiffLevel) || 688 (similarTasks2.getDiffLevel() <= mostSimilarDiffLevel)) { 689 690 similarTasks = getSimilarTasksToPrefer(similarTasks, similarTasks2); 691 } 692 } 693 694 if (similarTasks.isInBetweenDifference() || 695 (similarTasks.getPatch().getDeltas().size() == 0)) 608 696 { 609 SimilarTasks similarTasks = 610 getSimilarTasksToPrefer(similarTasks1, similarTasks2); 611 612 if (similarTasks.isInBetweenDifference() || 613 (similarTasks.getPatch().getDeltas().size() == 0)) 614 { 615 if (similarTasks.getDiffLevel() < mostSimilarDiffLevel) { 616 mostSimilarTasks = similarTasks; 617 mostSimilarDiffLevel = mostSimilarTasks.getDiffLevel(); 618 allMostSimilarTasks.clear(); 619 allMostSimilarTasks.add(similarTasks); 620 } 621 else if (similarTasks.getDiffLevel() == mostSimilarDiffLevel) { 622 allMostSimilarTasks.add(similarTasks); 623 } 697 if (similarTasks.getDiffLevel() < mostSimilarDiffLevel) { 698 mostSimilarTasks = similarTasks; 699 mostSimilarDiffLevel = mostSimilarTasks.getDiffLevel(); 700 allMostSimilarTasks.clear(); 701 allMostSimilarTasks.add(similarTasks); 702 } 703 else if (similarTasks.getDiffLevel() == mostSimilarDiffLevel) { 704 allMostSimilarTasks.add(similarTasks); 624 705 } 625 706 }
Note: See TracChangeset
for help on using the changeset viewer.