Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs	(revision 13735)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs	(revision 13736)
@@ -325,7 +325,13 @@
 
       foreach (var group in groupedRuns) {
-        var hits = new Dictionary<string, SortedList<double, double>>();
+        // hits describes the number of target hits at a certain time for a certain group
+        var hits = new Dictionary<string, SortedList<double, int>>();
+        // misses describes the number of target misses after a certain time for a certain group
+        // for instance when a run ends, but has not achieved all targets, misses describes
+        // how many targets have been left open at the point when the run ended
+        var misses = new Dictionary<string, SortedList<double, int>>();
         var maxLength = 0.0;
 
+        var noRuns = 0;
         foreach (var problem in group.Value) {
           foreach (var run in problem.Value.Item2) {
@@ -334,7 +340,11 @@
 
             if (eachOrAllTargetCheckBox.Checked) {
-              CalculateHitsForEachTarget(hits, resultsTable.Rows.First(), problem.Key, group.Key, group.Value.Count, problem.Value.Item1, problem.Value.Item2.Count);
+              CalculateHitsForEachTarget(hits, misses, resultsTable.Rows.First(), problem.Key, group.Key, problem.Value.Item1);
+              // achiving each target can be seen as a separate run for that target only
+              noRuns += targets.Length;
             } else {
-              maxLength = CalculateHitsForAllTargets(hits, resultsTable.Rows.First(), problem.Key, group.Key, group.Value.Count, problem.Value.Item1, problem.Value.Item2.Count);
+              var length = CalculateHitsForAllTargets(hits, misses, resultsTable.Rows.First(), problem.Key, group.Key, problem.Value.Item1);
+              maxLength = Math.Max(length, maxLength);
+              noRuns++;
             }
           }
@@ -351,12 +361,19 @@
           };
 
-          var total = 0.0;
+          var ecdf = 0.0;
+          var iter = misses[list.Key].GetEnumerator();
+          iter.MoveNext();
+          var sumTargets = noRuns * targets.Length;
           foreach (var h in list.Value) {
-            total += h.Value;
-            row.Values.Add(Tuple.Create(h.Key, total));
+            ecdf += h.Value;
+            while (iter.Current.Key < h.Key) {
+              sumTargets -= iter.Current.Value;
+              if (!iter.MoveNext()) break;
+            }
+            row.Values.Add(Tuple.Create(h.Key, ecdf / sumTargets));
           }
 
           if (maxLength > 0 && (row.Values.Count == 0 || row.Values.Last().Item1 < maxLength))
-            row.Values.Add(Tuple.Create(maxLength, total));
+            row.Values.Add(Tuple.Create(maxLength, ecdf / sumTargets));
 
           byTargetDataTable.Rows.Add(row);
@@ -382,22 +399,42 @@
     }
 
-    private void CalculateHitsForEachTarget(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, ProblemDescription problem, string group, int groupCount, double bestTarget, int problemCount) {
+    private void CalculateHitsForEachTarget(Dictionary<string, SortedList<double, int>> hits,
+                                            Dictionary<string, SortedList<double, int>> misses,
+                                            IndexedDataRow<double> row, ProblemDescription problem,
+                                            string group, double bestTarget) {
       foreach (var l in targets.Select(x => (problem.IsMaximization() ? (1 - x) : (1 + x)) * bestTarget)) {
         var key = group + "-" + l;
-        if (!hits.ContainsKey(key)) hits.Add(key, new SortedList<double, double>());
+        if (!hits.ContainsKey(key)) {
+          hits.Add(key, new SortedList<double, int>());
+          misses.Add(key, new SortedList<double, int>());
+        }
+        var hit = false;
         foreach (var v in row.Values) {
           if (problem.IsMaximization() && v.Item2 >= l || !problem.IsMaximization() && v.Item2 <= l) {
             if (hits[key].ContainsKey(v.Item1))
-              hits[key][v.Item1] += 1.0 / (groupCount * problemCount);
-            else hits[key][v.Item1] = 1.0 / (groupCount * problemCount);
+              hits[key][v.Item1]++;
+            else hits[key][v.Item1] = 1;
+            hit = true;
             break;
           }
         }
-      }
-    }
-
-    private double CalculateHitsForAllTargets(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, ProblemDescription problem, string group, int groupCount, double bestTarget, int problemCount) {
+        if (!hit) {
+          var max = row.Values.Last();
+          if (misses[key].ContainsKey(max.Item1))
+            misses[key][max.Item1]++;
+          else misses[key][max.Item1] = 1;
+        }
+      }
+    }
+
+    private double CalculateHitsForAllTargets(Dictionary<string, SortedList<double, int>> hits,
+                                              Dictionary<string, SortedList<double, int>> misses,
+                                              IndexedDataRow<double> row, ProblemDescription problem,
+                                              string group, double bestTarget) {
       var values = row.Values;
-      if (!hits.ContainsKey(group)) hits.Add(group, new SortedList<double, double>());
+      if (!hits.ContainsKey(group)) {
+        hits.Add(group, new SortedList<double, int>());
+        misses.Add(group, new SortedList<double, int>());
+      }
 
       var i = 0;
@@ -408,6 +445,6 @@
         if (problem.IsMaximization() && current.Item2 >= target
           || !problem.IsMaximization() && current.Item2 <= target) {
-          if (!hits[group].ContainsKey(current.Item1)) hits[group][current.Item1] = 0;
-          hits[group][current.Item1] += 1.0 / (groupCount * problemCount * targets.Length);
+          if (hits[group].ContainsKey(current.Item1)) hits[group][current.Item1]++;
+          else hits[group][current.Item1] = 1;
           i++;
         } else {
@@ -416,4 +453,9 @@
       }
       if (j == values.Count) j--;
+      if (i < targets.Length) {
+        if (misses[group].ContainsKey(values[j].Item1))
+          misses[group][values[j].Item1] += targets.Length - i;
+        else misses[group][values[j].Item1] = targets.Length - i;
+      }
       return values[j].Item1;
     }
