Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/05/15 00:06:45 (9 years ago)
Author:
abeham
Message:

#2431: updated RLD analysis view

  • Added analysis by cost
  • Prepared tab for output of ERT tables
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs

    r12822 r12838  
    4040
    4141    private static readonly Color[] colors = new[] {
    42       Color.FromArgb(0x20, 0x4A, 0x87),
    43       Color.FromArgb(0xC1, 0x7D, 0x11),
    44       Color.FromArgb(0x4E, 0x9A, 0x06),
     42      Color.FromArgb(0x40, 0x6A, 0xB7),
     43      Color.FromArgb(0xB1, 0x6D, 0x01),
     44      Color.FromArgb(0x4E, 0x8A, 0x06),
    4545      Color.FromArgb(0x75, 0x50, 0x7B),
    4646      Color.FromArgb(0x72, 0x9F, 0xCF),
    4747      Color.FromArgb(0xA4, 0x00, 0x00),
    4848      Color.FromArgb(0xAD, 0x7F, 0xA8),
    49       Color.FromArgb(0xF5, 0x79, 0x00),
     49      Color.FromArgb(0x29, 0x50, 0xCF),
     50      Color.FromArgb(0x90, 0xB0, 0x60),
     51      Color.FromArgb(0xF5, 0x89, 0x30),
    5052      Color.FromArgb(0x55, 0x57, 0x53),
    51       Color.FromArgb(0xEF, 0x29, 0x29),
    52       Color.FromArgb(0xED, 0xD4, 0x00),
    53       Color.FromArgb(0x73, 0xD2, 0x16),
     53      Color.FromArgb(0xEF, 0x59, 0x59),
     54      Color.FromArgb(0xED, 0xD4, 0x30),
     55      Color.FromArgb(0x63, 0xC2, 0x16),
     56    };
     57    private static readonly DataRowVisualProperties.DataRowLineStyle[] lineStyles = new[] {
     58      DataRowVisualProperties.DataRowLineStyle.Solid,
     59      DataRowVisualProperties.DataRowLineStyle.Dash,
     60      DataRowVisualProperties.DataRowLineStyle.DashDot,
     61      DataRowVisualProperties.DataRowLineStyle.Dot
    5462    };
    5563
     
    5967    }
    6068
    61     private double[] levels;
     69    private double[] targets;
     70    private double[] budgets;
    6271
    6372    private bool suppressUpdates;
    64     private readonly IndexedDataTable<double> combinedDataTable;
    65     public IndexedDataTable<double> CombinedDataTable {
    66       get { return combinedDataTable; }
     73    private readonly IndexedDataTable<double> byTargetDataTable;
     74    public IndexedDataTable<double> ByTargetDataTable {
     75      get { return byTargetDataTable; }
     76    }
     77    private readonly IndexedDataTable<double> byCostDataTable;
     78    public IndexedDataTable<double> ByCostDataTable {
     79      get { return byCostDataTable; }
    6780    }
    6881
    6982    public RunCollectionRLDView() {
    7083      InitializeComponent();
    71       combinedDataTable = new IndexedDataTable<double>("Combined DataTable", "A data table containing the ECDF of each of a number of groups.") {
     84      byTargetDataTable = new IndexedDataTable<double>("ECDF by Target", "A data table containing the ECDF of each of a number of groups.") {
    7285        VisualProperties = {
    7386          YAxisTitle = "Proportion of reached targets",
     
    7689        }
    7790      };
    78       viewHost.Content = combinedDataTable;
     91      byTargetViewHost.Content = byTargetDataTable;
     92      byCostDataTable = new IndexedDataTable<double>("ECDF by Cost", "A data table containing the ECDF of each of a number of groups.") {
     93        VisualProperties = {
     94          YAxisTitle = "Proportion of required budgets",
     95          YAxisMinimumFixedValue = 0, YAxisMinimumAuto = false,
     96          YAxisMaximumFixedValue = 1, YAxisMaximumAuto = false
     97        }
     98      };
     99      byCostViewHost.Content = byCostDataTable;
    79100      suppressUpdates = false;
    80101    }
     
    170191      dataTableComboBox.Items.Clear();
    171192      groupComboBox.Items.Clear();
    172       combinedDataTable.Rows.Clear();
     193      byTargetDataTable.Rows.Clear();
    173194
    174195      UpdateCaption();
     
    179200    }
    180201
    181     protected override void SetEnabledStateOfControls() {
    182       base.SetEnabledStateOfControls();
    183       groupComboBox.Enabled = Content != null;
    184       dataTableComboBox.Enabled = Content != null;
    185       fixedTargetButton.Enabled = Content != null && levels != null && dataTableComboBox.SelectedIndex >= 0;
    186     }
    187 
    188     private void UpdateRuns() {
    189       if (InvokeRequired) {
    190         Invoke((Action)UpdateRuns);
    191         return;
    192       }
    193       SuspendRepaint();
    194       try {
    195         combinedDataTable.VisualProperties.XAxisLogScale = false;
    196         combinedDataTable.Rows.Clear();
    197         var table = (string)dataTableComboBox.SelectedItem;
    198         if (string.IsNullOrEmpty(table)) return;
    199         if (levels == null) {
    200           var worstMin = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.First().Item2).Min();
    201           var worstMax = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.First().Item2).Max();
    202           var bestMin = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Last().Item2).Min();
    203           var bestMax = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Last().Item2).Max();
    204           double worst, best;
    205           if (Math.Abs(bestMax - worstMin) > Math.Abs(bestMin - worstMax)) {
    206             worst = worstMin;
    207             best = bestMax;
    208           } else {
    209             worst = worstMax;
    210             best = bestMin;
    211           }
    212           levels = Enumerable.Range(0, 11).Select(x => worst + (x / 10.0) * (best - worst)).ToArray();
    213           suppressTargetsEvents = true;
    214           targetsTextBox.Text = string.Join(" ; ", levels);
    215           suppressTargetsEvents = false;
    216         }
    217         var selectedGroup = (string)groupComboBox.SelectedItem;
    218         if (string.IsNullOrEmpty(selectedGroup)) return;
    219         List<Tuple<string, List<IRun>>> groupedRuns;
    220         if (selectedGroup == AllRuns)
    221           groupedRuns = new List<Tuple<string, List<IRun>>> { Tuple.Create(AllRuns, Content.ToList()) };
    222         else groupedRuns = (from r in Content
    223                             group r by r.Parameters[selectedGroup].ToString() into g
    224                             select Tuple.Create(g.Key, g.ToList())).ToList();
    225         var xAxisTitles = new HashSet<string>();
    226         var colorCount = 0;
    227         var lineStyles = new[] {
    228           DataRowVisualProperties.DataRowLineStyle.Solid,
    229           DataRowVisualProperties.DataRowLineStyle.Dash,
    230           DataRowVisualProperties.DataRowLineStyle.DashDot,
    231           DataRowVisualProperties.DataRowLineStyle.Dot
    232         };
    233         var lineStyleCount = 0;
    234         foreach (var group in groupedRuns) {
    235           var hits = new Dictionary<string, SortedList<double, double>>();
    236           foreach (var run in group.Item2) {
    237             if (!run.Results.ContainsKey(table)) continue;
    238             var resultsTable = (IndexedDataTable<double>)run.Results[table];
    239             xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle);
    240             var values = resultsTable.Rows.First().Values;
    241             var maximization = values.First().Item2 < values.Last().Item2;
    242             if (allOrEachTargetCheckBox.Checked) {
    243               // each
    244               foreach (double l in levels) {
    245                 var key = "-" + l.ToString();
    246                 if (!hits.ContainsKey(key)) hits.Add(key, new SortedList<double, double>());
    247                 foreach (var v in values) {
    248                   if (maximization && v.Item2 >= l || !maximization && v.Item2 <= l) {
    249                     if (hits[key].ContainsKey(v.Item1))
    250                       hits[key][v.Item1] += 1.0 / group.Item2.Count;
    251                     else hits[key][v.Item1] = 1.0 / group.Item2.Count;
    252                     break;
    253                   }
    254                 }
    255               }
    256             } else {
    257               if (!hits.ContainsKey("all")) hits.Add("all", new SortedList<double, double>());
    258               // all
    259               var i = 0;
    260               var j = 0;
    261               var current = values[j];
    262               var prev = Tuple.Create(-1.0, double.NaN);
    263               while (i < levels.Length) {
    264                 if ((double.IsNaN(prev.Item2) || prev.Item2 != current.Item2)
    265                     && (maximization && current.Item2 >= levels[i]
    266                         || !maximization && current.Item2 <= levels[i])) {
    267                   if (hits["all"].ContainsKey(current.Item1))
    268                     hits["all"][current.Item1] += 1.0 / (group.Item2.Count * levels.Length);
    269                   else hits["all"][current.Item1] = 1.0 / (group.Item2.Count * levels.Length);
    270                   i++;
    271                 } else {
    272                   j++;
    273                   if (j >= values.Count) break;
    274                   prev = current;
    275                   current = values[j];
    276                 }
    277               }
    278             }
    279           }
    280           foreach (var list in hits) {
    281             var row = new IndexedDataRow<double>(group.Item1 + (list.Key != "all" ? list.Key : string.Empty)) {
    282               VisualProperties = {
    283                 ChartType = DataRowVisualProperties.DataRowChartType.StepLine,
    284                 LineWidth = 2,
    285                 Color = colors[colorCount],
    286                 LineStyle = lineStyles[lineStyleCount]
    287               }
    288             };
    289             var total = 0.0;
    290             foreach (var h in list.Value) {
    291               total += h.Value;
    292               row.Values.Add(Tuple.Create(h.Key, total));
    293             }
    294             combinedDataTable.Rows.Add(row);
    295           }
    296           colorCount = (colorCount + 1) % colors.Length;
    297           if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length;
    298         }
    299         combinedDataTable.VisualProperties.XAxisTitle = string.Join(" / ", xAxisTitles);
    300         combinedDataTable.VisualProperties.XAxisLogScale = combinedDataTable.Rows.Count > 0 && logScalingCheckBox.Checked;
    301       } finally { ResumeRepaint(true); }
    302     }
    303202
    304203    private void UpdateGroupComboBox() {
     
    333232    }
    334233
     234    protected override void SetEnabledStateOfControls() {
     235      base.SetEnabledStateOfControls();
     236      groupComboBox.Enabled = Content != null;
     237      dataTableComboBox.Enabled = Content != null;
     238      addTargetsAsResultButton.Enabled = Content != null && targets != null && dataTableComboBox.SelectedIndex >= 0;
     239      addBudgetsAsResultButton.Enabled = Content != null && budgets != null && dataTableComboBox.SelectedIndex >= 0;
     240    }
     241
     242    private void UpdateRuns() {
     243      if (InvokeRequired) {
     244        Invoke((Action)UpdateRuns);
     245        return;
     246      }
     247      SuspendRepaint();
     248      try {
     249        UpdateResultsByTarget();
     250        UpdateResultsByCost();
     251      } finally { ResumeRepaint(true); }
     252    }
     253
     254    #region Performance analysis by (multiple) target(s)
     255    private void UpdateResultsByTarget() {
     256      // necessary to reset log scale -> empty chart cannot use log scaling
     257      byTargetDataTable.VisualProperties.XAxisLogScale = false;
     258      byTargetDataTable.Rows.Clear();
     259
     260      var table = (string)dataTableComboBox.SelectedItem;
     261      if (string.IsNullOrEmpty(table)) return;
     262
     263      var selectedGroup = (string)groupComboBox.SelectedItem;
     264      if (string.IsNullOrEmpty(selectedGroup)) return;
     265
     266      if (targets == null) GenerateDefaultTargets(table);
     267
     268      List<Tuple<string, List<IRun>>> groupedRuns;
     269      if (selectedGroup == AllRuns)
     270        groupedRuns = new List<Tuple<string, List<IRun>>> {
     271          Tuple.Create(AllRuns, Content.Where(r => r.Results.ContainsKey(table) && r.Visible).ToList())
     272        };
     273      else groupedRuns = (from r in Content
     274                          where r.Results.ContainsKey(table) && r.Visible
     275                          group r by r.Parameters[selectedGroup].ToString() into g
     276                          select Tuple.Create(g.Key, g.ToList())).ToList();
     277
     278      var xAxisTitles = new HashSet<string>();
     279      var colorCount = 0;
     280      var lineStyleCount = 0;
     281      var maximization = IsMaximization();
     282
     283      foreach (var group in groupedRuns) {
     284        var hits = new Dictionary<string, SortedList<double, double>>();
     285        var maxLength = 0.0;
     286
     287        foreach (var run in group.Item2) {
     288          var resultsTable = (IndexedDataTable<double>)run.Results[table];
     289          xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle);
     290
     291          if (eachOrAllTargetCheckBox.Checked) {
     292            CalculateHitsForEachTarget(hits, resultsTable.Rows.First(), maximization, group.Item2.Count, group.Item1);
     293          } else {
     294            maxLength = CalculateHitsForAllTargets(hits, resultsTable.Rows.First(), maximization, group.Item2.Count, group.Item1);
     295          }
     296        }
     297
     298        foreach (var list in hits) {
     299          var row = new IndexedDataRow<double>(list.Key) {
     300            VisualProperties = {
     301              ChartType = DataRowVisualProperties.DataRowChartType.StepLine,
     302              LineWidth = 2,
     303              Color = colors[colorCount],
     304              LineStyle = lineStyles[lineStyleCount]
     305            }
     306          };
     307
     308          var total = 0.0;
     309          foreach (var h in list.Value) {
     310            total += h.Value;
     311            row.Values.Add(Tuple.Create(h.Key, total));
     312          }
     313
     314          if (maxLength > 0 && (row.Values.Count == 0 || row.Values.Last().Item1 < maxLength))
     315            row.Values.Add(Tuple.Create(maxLength, total));
     316
     317          byTargetDataTable.Rows.Add(row);
     318        }
     319        colorCount = (colorCount + 1) % colors.Length;
     320        if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length;
     321      }
     322
     323      byTargetDataTable.VisualProperties.XAxisTitle = string.Join(" / ", xAxisTitles);
     324      byTargetDataTable.VisualProperties.XAxisLogScale = byTargetDataTable.Rows.Count > 0 && targetLogScalingCheckBox.Checked;
     325    }
     326
     327    private void GenerateDefaultTargets(string table) {
     328      var worst = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item2).Min()).Min();
     329      var best = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item2).Max()).Max();
     330      var maximization = IsMaximization();
     331      if (!maximization) {
     332        var h = worst;
     333        worst = best;
     334        best = h;
     335      }
     336
     337      if (best == 0 || Math.Abs(best - worst) < Math.Abs(best * 2))
     338        targets = Enumerable.Range(0, 11).Select(x => worst + (x / 10.0) * (best - worst)).ToArray();
     339      else if (best > 0) targets = Enumerable.Range(0, 11).Select(x => best * (1.0 + (10 - x) / 10.0)).ToArray();
     340      else if (best < 0) targets = Enumerable.Range(0, 11).Select(x => best / (1.0 + (10 - x) / 10.0)).ToArray();
     341
     342      suppressTargetsEvents = true;
     343      targetsTextBox.Text = string.Join(" ; ", targets);
     344      suppressTargetsEvents = false;
     345    }
     346
     347    private void CalculateHitsForEachTarget(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, bool maximization, int groupCount, string groupName) {
     348      foreach (var l in targets) {
     349        var key = groupName + "-" + l;
     350        if (!hits.ContainsKey(key)) hits.Add(key, new SortedList<double, double>());
     351        foreach (var v in row.Values) {
     352          if (maximization && v.Item2 >= l || !maximization && v.Item2 <= l) {
     353            if (hits[key].ContainsKey(v.Item1))
     354              hits[key][v.Item1] += 1.0 / groupCount;
     355            else hits[key][v.Item1] = 1.0 / groupCount;
     356            break;
     357          }
     358        }
     359      }
     360    }
     361
     362    private double CalculateHitsForAllTargets(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, bool maximization, int groupCount, string groupName) {
     363      var values = row.Values;
     364      if (!hits.ContainsKey(groupName)) hits.Add(groupName, new SortedList<double, double>());
     365
     366      var i = 0;
     367      var j = 0;
     368      while (i < targets.Length && j < values.Count) {
     369        var current = values[j];
     370        if (maximization && current.Item2 >= targets[i]
     371          || !maximization && current.Item2 <= targets[i]) {
     372          if (!hits[groupName].ContainsKey(current.Item1)) hits[groupName][current.Item1] = 0;
     373          hits[groupName][current.Item1] += 1.0 / (groupCount * targets.Length);
     374          i++;
     375        } else {
     376          j++;
     377        }
     378      }
     379      if (j == values.Count) j--;
     380      return values[j].Item1;
     381    }
     382    #endregion
     383
     384    #region Performance analysis by (multiple) budget(s)
     385    private void UpdateResultsByCost() {
     386      // necessary to reset log scale -> empty chart cannot use log scaling
     387      byCostDataTable.VisualProperties.XAxisLogScale = false;
     388      byCostDataTable.Rows.Clear();
     389
     390      var table = (string)dataTableComboBox.SelectedItem;
     391      if (string.IsNullOrEmpty(table)) return;
     392
     393      var selectedGroup = (string)groupComboBox.SelectedItem;
     394      if (string.IsNullOrEmpty(selectedGroup)) return;
     395
     396      if (budgets == null) GenerateDefaultBudgets(table);
     397
     398      List<Tuple<string, List<IRun>>> groupedRuns;
     399      if (selectedGroup == AllRuns)
     400        groupedRuns = new List<Tuple<string, List<IRun>>> {
     401          Tuple.Create(AllRuns, Content.Where(r => r.Results.ContainsKey(table) && r.Visible).ToList())
     402        };
     403      else groupedRuns = (from r in Content
     404                          where r.Results.ContainsKey(table) && r.Visible
     405                          group r by r.Parameters[selectedGroup].ToString() into g
     406                          select Tuple.Create(g.Key, g.ToList())).ToList();
     407
     408      var colorCount = 0;
     409      var lineStyleCount = 0;
     410      var maximization = IsMaximization();
     411
     412      foreach (var group in groupedRuns) {
     413        var hits = new Dictionary<string, SortedList<double, double>>();
     414
     415        foreach (var run in group.Item2) {
     416          var resultsTable = (IndexedDataTable<double>)run.Results[table];
     417
     418          if (eachOrAllBudgetsCheckBox.Checked) {
     419            CalculateHitsForEachBudget(hits, resultsTable.Rows.First(), maximization, group.Item2.Count, group.Item1);
     420          } else {
     421            CalculateHitsForAllBudgets(hits, resultsTable.Rows.First(), maximization, group.Item2.Count, group.Item1);
     422          }
     423        }
     424
     425        foreach (var list in hits) {
     426          var row = new IndexedDataRow<double>(list.Key) {
     427            VisualProperties = {
     428              ChartType = DataRowVisualProperties.DataRowChartType.StepLine,
     429              LineWidth = 2,
     430              Color = colors[colorCount],
     431              LineStyle = lineStyles[lineStyleCount]
     432            }
     433          };
     434
     435          var total = 0.0;
     436          foreach (var h in list.Value) {
     437            total += h.Value;
     438            row.Values.Add(Tuple.Create(h.Key, total));
     439          }
     440
     441          byCostDataTable.Rows.Add(row);
     442        }
     443        colorCount = (colorCount + 1) % colors.Length;
     444        if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length;
     445      }
     446
     447      byCostDataTable.VisualProperties.XAxisTitle = "Targets";
     448      byCostDataTable.VisualProperties.XAxisLogScale = byCostDataTable.Rows.Count > 0 && budgetLogScalingCheckBox.Checked;
     449    }
     450
     451    private void GenerateDefaultBudgets(string table) {
     452      var min = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Min()).Min();
     453      var max = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Max()).Max();
     454
     455      var maxMagnitude = (int)Math.Ceiling(Math.Log10(max));
     456      var minMagnitude = (int)Math.Floor(Math.Log10(min));
     457      if (maxMagnitude - minMagnitude >= 3) {
     458        budgets = new double[maxMagnitude - minMagnitude];
     459        for (var i = minMagnitude; i < maxMagnitude; i++) {
     460          budgets[i - minMagnitude] = Math.Pow(10, i);
     461        }
     462      } else {
     463        var range = max - min;
     464        budgets = Enumerable.Range(0, 6).Select(x => min + (x / 5.0) * range).ToArray();
     465      }
     466      suppressBudgetsEvents = true;
     467      budgetsTextBox.Text = string.Join(" ; ", budgets);
     468      suppressBudgetsEvents = false;
     469    }
     470
     471    private void CalculateHitsForEachBudget(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, bool maximization, int groupCount, string groupName) {
     472      foreach (var b in budgets) {
     473        var key = groupName + "-" + b;
     474        if (!hits.ContainsKey(key)) hits.Add(key, new SortedList<double, double>());
     475        Tuple<double, double> prev = null;
     476        foreach (var v in row.Values) {
     477          if (v.Item1 >= b) {
     478            // the budget may be too low to achieve any target
     479            if (prev == null && v.Item1 != b) break;
     480            var tgt = (prev == null || v.Item1 == b) ? v.Item2 : prev.Item2;
     481            if (hits[key].ContainsKey(tgt))
     482              hits[key][tgt] += 1.0 / groupCount;
     483            else hits[key][tgt] = 1.0 / groupCount;
     484            break;
     485          }
     486          prev = v;
     487        }
     488        if (hits[key].Count == 0) hits.Remove(key);
     489      }
     490    }
     491
     492    private void CalculateHitsForAllBudgets(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, bool maximization, int groupCount, string groupName) {
     493      var values = row.Values;
     494      if (!hits.ContainsKey(groupName)) hits.Add(groupName, new SortedList<double, double>());
     495
     496      var i = 0;
     497      var j = 0;
     498      Tuple<double, double> prev = null;
     499      while (i < budgets.Length && j < values.Count) {
     500        var current = values[j];
     501        if (current.Item1 >= budgets[i]) {
     502          if (prev != null || current.Item1 == budgets[i]) {
     503            var tgt = (prev == null || current.Item1 == budgets[i]) ? current.Item2 : prev.Item2;
     504            if (!hits[groupName].ContainsKey(tgt)) hits[groupName][tgt] = 0;
     505            hits[groupName][tgt] += 1.0 / (groupCount * budgets.Length);
     506          }
     507          i++;
     508        } else {
     509          j++;
     510          prev = current;
     511        }
     512      }
     513      var lastTgt = values.Last().Item2;
     514      if (i < budgets.Length && !hits[groupName].ContainsKey(lastTgt)) hits[groupName][lastTgt] = 0;
     515      while (i < budgets.Length) {
     516        hits[groupName][lastTgt] += 1.0 / (groupCount * budgets.Length);
     517        i++;
     518      }
     519    }
     520    #endregion
     521
    335522    private void UpdateCaption() {
    336523      Caption = Content != null ? Content.OptimizerName + " RLD View" : ViewAttribute.GetViewName(GetType());
     
    342529    }
    343530    private void dataTableComboBox_SelectedIndexChanged(object sender, EventArgs e) {
     531      if (dataTableComboBox.SelectedIndex >= 0)
     532        GenerateDefaultBudgets((string)dataTableComboBox.SelectedItem);
    344533      UpdateRuns();
    345534      SetEnabledStateOfControls();
     
    347536
    348537    private void logScalingCheckBox_CheckedChanged(object sender, EventArgs e) {
    349       combinedDataTable.VisualProperties.XAxisLogScale = logScalingCheckBox.Checked;
    350     }
    351 
     538      byTargetDataTable.VisualProperties.XAxisLogScale = byTargetDataTable.Rows.Count > 0 && targetLogScalingCheckBox.Checked;
     539      byCostDataTable.VisualProperties.XAxisLogScale = byCostDataTable.Rows.Count > 0 && budgetLogScalingCheckBox.Checked;
     540    }
     541
     542    #region Event handlers for target analysis
    352543    private bool suppressTargetsEvents;
    353544    private void targetsTextBox_Validating(object sender, CancelEventArgs e) {
     
    371562      e.Cancel = false;
    372563      errorProvider.SetError(targetsTextBox, null);
    373       levels = targetList.ToArray();
    374       UpdateRuns();
     564      targets = targetList.ToArray();
     565      UpdateResultsByTarget();
    375566      SetEnabledStateOfControls();
    376567    }
    377568
     569    private void eachOrAllTargetCheckBox_CheckedChanged(object sender, EventArgs e) {
     570      var each = eachOrAllTargetCheckBox.Checked;
     571      eachOrAllTargetCheckBox.Text = each ? "each" : "all";
     572      SuspendRepaint();
     573      try {
     574        UpdateResultsByTarget();
     575      } finally { ResumeRepaint(true); }
     576    }
     577
    378578    private void generateTargetsButton_Click(object sender, EventArgs e) {
     579      var maximization = IsMaximization();
    379580      decimal max = 1, min = 0, count = 10;
    380       if (levels != null) {
    381         max = (decimal)Math.Max(levels.First(), levels.Last());
    382         min = (decimal)Math.Min(levels.First(), levels.Last());
    383         count = levels.Length;
     581      if (targets != null) {
     582        max = (decimal)targets.Max();
     583        min = (decimal)targets.Min();
     584        count = targets.Length;
    384585      } else if (Content.Count > 0 && dataTableComboBox.SelectedIndex >= 0) {
    385586        var table = (string)dataTableComboBox.SelectedItem;
    386         var worst = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item2)).First();
    387         var best = Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item2)).Last();
    388         max = (decimal)Math.Max(best, worst);
    389         min = (decimal)Math.Min(best, worst);
    390         count = 10;
     587        max = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item2)).Max();
     588        min = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item2)).Min();
     589        count = 6;
    391590      }
    392591      using (var dialog = new DefineArithmeticProgressionDialog(false, min, max, (max - min) / count)) {
    393592        if (dialog.ShowDialog() == DialogResult.OK) {
    394593          if (dialog.Values.Any()) {
    395             var maximization = true;
    396             if (Content.Count > 0 && Content.First().Parameters.ContainsKey("Maximization"))
    397               maximization = ((BoolValue)Content.First().Parameters["Maximization"]).Value;
    398 
    399             levels = maximization ? dialog.Values.Select(x => (double)x).ToArray()
     594            targets = maximization ? dialog.Values.Select(x => (double)x).ToArray()
    400595                                  : dialog.Values.Reverse().Select(x => (double)x).ToArray();
    401596            suppressTargetsEvents = true;
    402             targetsTextBox.Text = string.Join(" ; ", levels);
     597            targetsTextBox.Text = string.Join(" ; ", targets);
    403598            suppressTargetsEvents = false;
    404599
    405             UpdateRuns();
     600            UpdateResultsByTarget();
    406601            SetEnabledStateOfControls();
    407602          }
     
    410605    }
    411606
    412     private void fixedTargetButton_Click(object sender, EventArgs e) {
     607    private void addTargetsAsResultButton_Click(object sender, EventArgs e) {
    413608      var table = (string)dataTableComboBox.SelectedItem;
     609      var maximization = IsMaximization();
    414610      foreach (var run in Content) {
    415611        if (!run.Results.ContainsKey(table)) continue;
    416612        var resultsTable = (IndexedDataTable<double>)run.Results[table];
    417613        var values = resultsTable.Rows.First().Values;
    418         var maximization = values.First().Item2 < values.Last().Item2;
    419614        var i = 0;
    420615        var j = 0;
    421         var current = values[j];
    422         var prev = Tuple.Create(-1.0, double.NaN);
    423         while (i < levels.Length) {
    424           if (prev.Item2 != current.Item2
    425               && (maximization && current.Item2 >= levels[i]
    426               || !maximization && current.Item2 <= levels[i])) {
    427             run.Results[table + ".Target" + levels[i]] = new DoubleValue(current.Item1);
     616        while (i < targets.Length && j < values.Count) {
     617          var current = values[j];
     618          if (maximization && current.Item2 >= targets[i]
     619              || !maximization && current.Item2 <= targets[i]) {
     620            run.Results[table + ".Target" + targets[i]] = new DoubleValue(current.Item1);
    428621            i++;
    429622          } else {
    430623            j++;
    431             if (j >= values.Count) break;
    432             prev = current;
    433             current = values[j];
    434           }
    435         }
    436       }
    437     }
    438 
    439     private void fixedCostButton_Click(object sender, EventArgs e) {
     624          }
     625        }
     626      }
     627    }
     628    #endregion
     629
     630    #region Event handlers for cost analysis
     631    private bool suppressBudgetsEvents;
     632    private void budgetsTextBox_Validating(object sender, CancelEventArgs e) {
     633      if (suppressBudgetsEvents) return;
     634      var budgetStrings = budgetsTextBox.Text.Split(new[] { ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries);
     635      var budgetList = new List<double>();
     636      foreach (var ts in budgetStrings) {
     637        double b;
     638        if (!double.TryParse(ts, out b)) {
     639          errorProvider.SetError(budgetsTextBox, "Not all targets can be parsed: " + ts);
     640          e.Cancel = true;
     641          return;
     642        }
     643        budgetList.Add(b);
     644      }
     645      if (budgetList.Count == 0) {
     646        errorProvider.SetError(budgetsTextBox, "Give at least one target value!");
     647        e.Cancel = true;
     648        return;
     649      }
     650      e.Cancel = false;
     651      errorProvider.SetError(budgetsTextBox, null);
     652      budgets = budgetList.ToArray();
     653      UpdateResultsByCost();
     654      SetEnabledStateOfControls();
     655    }
     656
     657    private void eachOrAllBudgetsCheckBox_CheckedChanged(object sender, EventArgs e) {
     658      var each = eachOrAllBudgetsCheckBox.Checked;
     659      eachOrAllBudgetsCheckBox.Text = each ? "each" : "all";
     660      SuspendRepaint();
     661      try {
     662        UpdateResultsByCost();
     663      } finally { ResumeRepaint(true); }
     664    }
     665
     666    private void generateBudgetsButton_Click(object sender, EventArgs e) {
     667      decimal max = 1, min = 0, count = 10;
     668      if (budgets != null) {
     669        max = (decimal)budgets.Max();
     670        min = (decimal)budgets.Min();
     671        count = budgets.Length;
     672      } else if (Content.Count > 0 && dataTableComboBox.SelectedIndex >= 0) {
     673        var table = (string)dataTableComboBox.SelectedItem;
     674        min = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item1)).Min();
     675        max = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item1)).Max();
     676        count = 6;
     677      }
     678      using (var dialog = new DefineArithmeticProgressionDialog(false, min, max, (max - min) / count)) {
     679        if (dialog.ShowDialog() == DialogResult.OK) {
     680          if (dialog.Values.Any()) {
     681            budgets = dialog.Values.OrderBy(x => x).Select(x => (double)x).ToArray();
     682
     683            suppressBudgetsEvents = true;
     684            budgetsTextBox.Text = string.Join(" ; ", budgets);
     685            suppressBudgetsEvents = false;
     686
     687            UpdateResultsByCost();
     688            SetEnabledStateOfControls();
     689          }
     690        }
     691      }
     692    }
     693
     694    private void addBudgetsAsResultButton_Click(object sender, EventArgs e) {
    440695      var table = (string)dataTableComboBox.SelectedItem;
    441696      var budgetStrings = budgetsTextBox.Text.Split(new[] { ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries);
     
    461716        var i = 0;
    462717        var j = 0;
    463         var current = values[j];
    464         var prev = Tuple.Create(-1.0, double.NaN);
    465         while (i < budgetList.Count) {
    466           if (prev.Item2 != current.Item2 && current.Item1 >= budgetList[i]) {
    467             run.Results[table + ".Cost" + budgetList[i]] = new DoubleValue(double.IsNaN(prev.Item2) || current.Item1 == budgetList[i] ? current.Item2 : prev.Item2);
     718        Tuple<double, double> prev = null;
     719        while (i < budgetList.Count && j < values.Count) {
     720          var current = values[j];
     721          if (current.Item1 >= budgetList[i]) {
     722            if (prev != null || current.Item1 == budgetList[i]) {
     723              var tgt = (prev == null || current.Item1 == budgetList[i]) ? current.Item2 : prev.Item2;
     724              run.Results[table + ".Cost" + budgetList[i]] = new DoubleValue(tgt);
     725            }
    468726            i++;
    469727          } else {
    470728            j++;
    471             if (j >= values.Count) break;
    472729            prev = current;
    473             current = values[j];
    474           }
    475         }
    476       }
    477     }
    478 
    479     private void allOrEachTargetCheckBox_CheckedChanged(object sender, EventArgs e) {
    480       var each = allOrEachTargetCheckBox.Checked;
    481       allOrEachTargetCheckBox.Text = each ? "each" : "all";
    482       UpdateRuns();
    483     }
     730          }
     731        }
     732      }
     733    }
     734    #endregion
     735
     736    #region Helpers
     737    // Determines if the RunCollection contains maximization or minimization runs
     738    private bool IsMaximization() {
     739      if (Content == null) return false;
     740      if (Content.Count > 0) {
     741        foreach (var run in Content.Where(x => x.Parameters.ContainsKey("Maximization")
     742                                            && x.Parameters["Maximization"] is BoolValue)) {
     743          if (((BoolValue)run.Parameters["Maximization"]).Value) {
     744            return true;
     745          } else {
     746            return false;
     747          }
     748        }
     749        if (dataTableComboBox.SelectedIndex >= 0) {
     750          var selectedTable = (string)dataTableComboBox.SelectedItem;
     751          foreach (var run in Content.Where(x => x.Results.ContainsKey(selectedTable))) {
     752            var table = run.Results[selectedTable] as IndexedDataTable<double>;
     753            if (table == null) continue;
     754            var firstRowValues = table.Rows.First().Values;
     755            if (firstRowValues.Count < 2) continue;
     756            return firstRowValues[0].Item2 < firstRowValues[firstRowValues.Count - 1].Item2;
     757          }
     758        }
     759      }
     760      // assume minimization by default
     761      return false;
     762    }
     763    #endregion
    484764  }
    485765}
Note: See TracChangeset for help on using the changeset viewer.