Changeset 1981


Ignore:
Timestamp:
06/30/15 10:22:55 (9 years ago)
Author:
pharms
Message:
  • corrected filter for most covered events to decide which task pair to merge first
  • merging of identical sequences can be done in any order --> adapted selection of pair to merge first to handle identical sequences based on their smallest id
  • merging only most prominent tasks (except identical tasks) --> otherwise too many mergings of noise
  • new maximum diff level is 25
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  
    1515package de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils; 
    1616 
     17import java.util.ArrayList; 
     18import java.util.Collections; 
     19import java.util.Comparator; 
    1720import java.util.HashMap; 
    1821import java.util.HashSet; 
     
    5861 
    5962    /** 
    60      * If this similarity level is exceeded, two tasks are not considered similar anymore. 33 means 
    61      * 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; 
    6467     
    6568    /** 
     
    144147            } 
    145148             
    146             Console.println("smallest diff level is " + smallestDiffLevel); 
     149            Console.println("smallest diff level is " + smallestDiffLevel + " (max is " + 
     150                            MAX_DIFF_LEVEL + ")"); 
    147151        } 
    148152        else { 
     
    200204     */ 
    201205    private void applyFilterForMostCoveredEvents(LinkedList<SimilarTasks> mostSimilarTasksList, 
    202                                                  ITaskModel               taskModel) 
     206                                                 final ITaskModel         taskModel) 
    203207    { 
    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                        } 
    245259                    } 
    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); 
    257275    } 
    258276 
     
    327345            return first; 
    328346        } 
    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    } 
    354376 
    355377    /** 
     
    357379     */ 
    358380    private LinkedList<SimilarTasks> performComparisons(ITaskModel taskModel, List<ITask> tasks) { 
     381        Set<ITask> mostProminentTasks = getMostProminentTasks(taskModel, tasks); 
    359382        LinkedList<SimilarTasks> mostSimilarTasks = new LinkedList<SimilarTasks>(); 
    360383        List<Runnable> startedRunnables = new LinkedList<Runnable>(); 
     
    412435                    Runnable runnable = new CompareRunnable(taskModel, leftHandTraversals, 
    413436                                                            rightHandTraversals, 
     437                                                            mostProminentTasks, 
    414438                                                            mostSimilarTasks, startedRunnables); 
    415439                     
     
    468492 
    469493    /** 
     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    /** 
    470534     * convenience method to get the value of a task metric 
    471535     */ 
     
    539603         
    540604        /** */ 
     605        private Set<ITask> mostProminentTasks; 
     606         
     607        /** */ 
    541608        private List<SimilarTasks> mostSimilarTasksList; 
    542609 
     
    550617                               TaskTraversal[]    leftHandTraversals, 
    551618                               TaskTraversal[]    rightHandTraversals, 
     619                               Set<ITask>         mostProminentTasks, 
    552620                               List<SimilarTasks> mostSimilarTasksList, 
    553621                               List<Runnable>     unfinishedRunnables) 
     
    556624            this.leftHandTraversals = leftHandTraversals; 
    557625            this.rightHandTraversals = rightHandTraversals; 
     626            this.mostProminentTasks = mostProminentTasks; 
    558627            this.mostSimilarTasksList = mostSimilarTasksList; 
    559628            this.unfinishedRunnables = unfinishedRunnables; 
     
    585654                            continue LEFT_HAND_TRAVERSAL; 
    586655                        } 
    587  
     656                         
    588657                        counter++; 
    589658 
     
    598667                        effectiveComparisons++; 
    599668 
    600                         SimilarTasks similarTasks1 = SimilarTasks.compareTraversals 
     669                        SimilarTasks similarTasks = SimilarTasks.compareTraversals 
    601670                            (leftHandTraversals[i], rightHandTraversals[j], comparator); 
    602671 
    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)) 
    608696                        { 
    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); 
    624705                            } 
    625706                        } 
Note: See TracChangeset for help on using the changeset viewer.