- Timestamp:
- 07/12/17 21:59:49 (7 years ago)
- Location:
- stable
- Files:
-
- 2 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
stable
- Property svn:mergeinfo changed
/trunk/sources merged: 14102,14647,14652,14654,14734,14737,14775,15048,15125-15126
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Optimization.Views
- Property svn:mergeinfo changed
/trunk/sources/HeuristicLab.Optimization.Views merged: 14102,14647,14652,14654,14775,15125-15126
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs
r14102 r15220 45 45 private void InitializeComponent() { 46 46 this.components = new System.ComponentModel.Container(); 47 System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea 1= new System.Windows.Forms.DataVisualization.Charting.ChartArea();48 System.Windows.Forms.DataVisualization.Charting.Legend legend 1= new System.Windows.Forms.DataVisualization.Charting.Legend();47 System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); 48 System.Windows.Forms.DataVisualization.Charting.Legend legend2 = new System.Windows.Forms.DataVisualization.Charting.Legend(); 49 49 this.dataTableComboBox = new System.Windows.Forms.ComboBox(); 50 50 this.dataTableLabel = new System.Windows.Forms.Label(); … … 64 64 this.tabControl = new System.Windows.Forms.TabControl(); 65 65 this.byTargetTabPage = new System.Windows.Forms.TabPage(); 66 this.relativeOrAbsoluteComboBox = new System.Windows.Forms.ComboBox(); 66 67 this.targetChart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart(); 68 this.showLabelsCheckBox = new System.Windows.Forms.CheckBox(); 69 this.markerCheckBox = new System.Windows.Forms.CheckBox(); 67 70 this.boundShadingCheckBox = new System.Windows.Forms.CheckBox(); 68 71 this.byCostTabPage = new System.Windows.Forms.TabPage(); 69 72 this.byCostViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost(); 70 73 this.budgetLogScalingCheckBox = new System.Windows.Forms.CheckBox(); 71 this.eachOrAllBudgetsCheckBox = new System.Windows.Forms.CheckBox();72 74 this.generateBudgetsButton = new System.Windows.Forms.Button(); 73 75 this.byTableTabPage = new System.Windows.Forms.TabPage(); … … 143 145 this.targetsTextBox.Location = new System.Drawing.Point(59, 8); 144 146 this.targetsTextBox.Name = "targetsTextBox"; 145 this.targetsTextBox.Size = new System.Drawing.Size(2 87, 20);147 this.targetsTextBox.Size = new System.Drawing.Size(204, 20); 146 148 this.targetsTextBox.TabIndex = 1; 147 149 this.toolTip.SetToolTip(this.targetsTextBox, "The order of the targets is important, first to-hit targets\r\nshould be given firs" + … … 200 202 this.budgetsTextBox.Location = new System.Drawing.Point(59, 8); 201 203 this.budgetsTextBox.Name = "budgetsTextBox"; 202 this.budgetsTextBox.Size = new System.Drawing.Size(3 26, 20);204 this.budgetsTextBox.Size = new System.Drawing.Size(391, 20); 203 205 this.budgetsTextBox.TabIndex = 6; 204 206 this.budgetsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.budgetsTextBox_Validating); … … 221 223 this.aggregateTargetsCheckBox.Checked = true; 222 224 this.aggregateTargetsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; 223 this.aggregateTargetsCheckBox.Location = new System.Drawing.Point(3 52, 10);225 this.aggregateTargetsCheckBox.Location = new System.Drawing.Point(374, 10); 224 226 this.aggregateTargetsCheckBox.Name = "aggregateTargetsCheckBox"; 225 227 this.aggregateTargetsCheckBox.Size = new System.Drawing.Size(74, 17); … … 245 247 // byTargetTabPage 246 248 // 249 this.byTargetTabPage.Controls.Add(this.relativeOrAbsoluteComboBox); 247 250 this.byTargetTabPage.Controls.Add(this.targetChart); 251 this.byTargetTabPage.Controls.Add(this.showLabelsCheckBox); 252 this.byTargetTabPage.Controls.Add(this.markerCheckBox); 248 253 this.byTargetTabPage.Controls.Add(this.boundShadingCheckBox); 249 254 this.byTargetTabPage.Controls.Add(this.targetLogScalingCheckBox); … … 261 266 this.byTargetTabPage.UseVisualStyleBackColor = true; 262 267 // 268 // relativeOrAbsoluteComboBox 269 // 270 this.relativeOrAbsoluteComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 271 this.relativeOrAbsoluteComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 272 this.relativeOrAbsoluteComboBox.FormattingEnabled = true; 273 this.relativeOrAbsoluteComboBox.Items.AddRange(new object[] { 274 "relative", 275 "absolute"}); 276 this.relativeOrAbsoluteComboBox.Location = new System.Drawing.Point(269, 8); 277 this.relativeOrAbsoluteComboBox.Name = "relativeOrAbsoluteComboBox"; 278 this.relativeOrAbsoluteComboBox.Size = new System.Drawing.Size(99, 21); 279 this.relativeOrAbsoluteComboBox.TabIndex = 8; 280 this.relativeOrAbsoluteComboBox.SelectedIndexChanged += new System.EventHandler(this.relativeOrAbsoluteComboBox_SelectedIndexChanged); 281 // 263 282 // targetChart 264 283 // … … 266 285 | System.Windows.Forms.AnchorStyles.Left) 267 286 | System.Windows.Forms.AnchorStyles.Right))); 268 chartArea 1.AxisX.IsStartedFromZero = false;269 chartArea 1.AxisX.MinorGrid.Enabled = true;270 chartArea 1.AxisX.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;271 chartArea 1.AxisX.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;272 chartArea 1.AxisY.Maximum = 1D;273 chartArea 1.AxisY.Minimum = 0D;274 chartArea 1.AxisY.MinorGrid.Enabled = true;275 chartArea 1.AxisY.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;276 chartArea 1.AxisY.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;277 chartArea 1.Name = "ChartArea1";278 this.targetChart.ChartAreas.Add(chartArea 1);279 legend 1.Alignment = System.Drawing.StringAlignment.Center;280 legend 1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;281 legend 1.Name = "Legend1";282 this.targetChart.Legends.Add(legend 1);287 chartArea2.AxisX.IsStartedFromZero = false; 288 chartArea2.AxisX.MinorGrid.Enabled = true; 289 chartArea2.AxisX.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke; 290 chartArea2.AxisX.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash; 291 chartArea2.AxisY.Maximum = 1D; 292 chartArea2.AxisY.Minimum = 0D; 293 chartArea2.AxisY.MinorGrid.Enabled = true; 294 chartArea2.AxisY.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke; 295 chartArea2.AxisY.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash; 296 chartArea2.Name = "ChartArea1"; 297 this.targetChart.ChartAreas.Add(chartArea2); 298 legend2.Alignment = System.Drawing.StringAlignment.Center; 299 legend2.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top; 300 legend2.Name = "Legend1"; 301 this.targetChart.Legends.Add(legend2); 283 302 this.targetChart.Location = new System.Drawing.Point(6, 34); 284 303 this.targetChart.Name = "targetChart"; … … 290 309 this.targetChart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown); 291 310 this.targetChart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove); 311 // 312 // showLabelsCheckBox 313 // 314 this.showLabelsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 315 this.showLabelsCheckBox.AutoSize = true; 316 this.showLabelsCheckBox.Checked = true; 317 this.showLabelsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; 318 this.showLabelsCheckBox.Location = new System.Drawing.Point(329, 364); 319 this.showLabelsCheckBox.Name = "showLabelsCheckBox"; 320 this.showLabelsCheckBox.Size = new System.Drawing.Size(81, 17); 321 this.showLabelsCheckBox.TabIndex = 6; 322 this.showLabelsCheckBox.Text = "show labels"; 323 this.showLabelsCheckBox.UseVisualStyleBackColor = true; 324 this.showLabelsCheckBox.CheckedChanged += new System.EventHandler(this.showLabelsCheckBox_CheckedChanged); 325 // 326 // markerCheckBox 327 // 328 this.markerCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 329 this.markerCheckBox.AutoSize = true; 330 this.markerCheckBox.Location = new System.Drawing.Point(229, 364); 331 this.markerCheckBox.Name = "markerCheckBox"; 332 this.markerCheckBox.Size = new System.Drawing.Size(91, 17); 333 this.markerCheckBox.TabIndex = 6; 334 this.markerCheckBox.Text = "show markers"; 335 this.markerCheckBox.UseVisualStyleBackColor = true; 336 this.markerCheckBox.CheckedChanged += new System.EventHandler(this.markerCheckBox_CheckedChanged); 292 337 // 293 338 // boundShadingCheckBox … … 309 354 this.byCostTabPage.Controls.Add(this.byCostViewHost); 310 355 this.byCostTabPage.Controls.Add(this.budgetLogScalingCheckBox); 311 this.byCostTabPage.Controls.Add(this.eachOrAllBudgetsCheckBox);312 356 this.byCostTabPage.Controls.Add(this.generateBudgetsButton); 313 357 this.byCostTabPage.Controls.Add(this.budgetsLabel); … … 349 393 this.budgetLogScalingCheckBox.UseVisualStyleBackColor = true; 350 394 this.budgetLogScalingCheckBox.CheckedChanged += new System.EventHandler(this.logScalingCheckBox_CheckedChanged); 351 //352 // eachOrAllBudgetsCheckBox353 //354 this.eachOrAllBudgetsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));355 this.eachOrAllBudgetsCheckBox.AutoSize = true;356 this.eachOrAllBudgetsCheckBox.Location = new System.Drawing.Point(414, 10);357 this.eachOrAllBudgetsCheckBox.Name = "eachOrAllBudgetsCheckBox";358 this.eachOrAllBudgetsCheckBox.Size = new System.Drawing.Size(36, 17);359 this.eachOrAllBudgetsCheckBox.TabIndex = 10;360 this.eachOrAllBudgetsCheckBox.Text = "all";361 this.eachOrAllBudgetsCheckBox.UseVisualStyleBackColor = true;362 this.eachOrAllBudgetsCheckBox.CheckedChanged += new System.EventHandler(this.eachOrAllBudgetsCheckBox_CheckedChanged);363 395 // 364 396 // generateBudgetsButton … … 464 496 private System.Windows.Forms.TabPage byCostTabPage; 465 497 private System.Windows.Forms.TabPage byTableTabPage; 466 private System.Windows.Forms.CheckBox eachOrAllBudgetsCheckBox;467 498 private System.Windows.Forms.Button generateBudgetsButton; 468 499 private System.Windows.Forms.CheckBox budgetLogScalingCheckBox; … … 473 504 private MainForm.WindowsForms.ViewHost byCostViewHost; 474 505 private System.Windows.Forms.CheckBox boundShadingCheckBox; 506 private System.Windows.Forms.CheckBox markerCheckBox; 507 private System.Windows.Forms.ComboBox relativeOrAbsoluteComboBox; 508 private System.Windows.Forms.CheckBox showLabelsCheckBox; 475 509 } 476 510 } -
stable/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs
r14102 r15220 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-201 5Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 30 30 using HeuristicLab.Analysis; 31 31 using HeuristicLab.Collections; 32 using HeuristicLab.Core; 32 33 using HeuristicLab.Core.Views; 33 34 using HeuristicLab.Data; … … 41 42 private List<Series> invisibleTargetSeries; 42 43 43 private const string All Runs = "All Runs";44 private const string AllInstances = "All Instances"; 44 45 45 46 private static readonly Color[] colors = new[] { … … 79 80 private double[] targets; 80 81 private double[] budgets; 82 private bool targetsAreRelative = true; 83 private bool showLabelsInTargetChart = true; 84 private readonly BindingList<ProblemInstance> problems; 81 85 82 86 private bool suppressUpdates; … … 93 97 targetChart.ChartAreas[0].CursorX.Interval = 1; 94 98 targetChart.SuppressExceptions = true; 95 byCostDataTable = new IndexedDataTable<double>("ECDF by Cost", "A data table containing the ECDF of each of a number of groups.") {99 byCostDataTable = new IndexedDataTable<double>("ECDF by Cost", "A data table containing the ECDF of function values (relative to best-known).") { 96 100 VisualProperties = { 97 YAxisTitle = "Proportion of unused budgets",101 YAxisTitle = "Proportion of runs", 98 102 YAxisMinimumFixedValue = 0, 99 103 YAxisMinimumAuto = false, … … 103 107 }; 104 108 byCostViewHost.Content = byCostDataTable; 109 suppressUpdates = true; 110 relativeOrAbsoluteComboBox.SelectedItem = targetsAreRelative ? "relative" : "absolute"; 111 problems = new BindingList<ProblemInstance>(); 112 problemComboBox.DataSource = new BindingSource() { DataSource = problems }; 113 problemComboBox.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged; 105 114 suppressUpdates = false; 106 115 } … … 215 224 var groupings = Content.ParameterNames.OrderBy(x => x).ToArray(); 216 225 groupComboBox.Items.Clear(); 217 groupComboBox.Items.Add(All Runs);226 groupComboBox.Items.Add(AllInstances); 218 227 groupComboBox.Items.AddRange(groupings); 219 228 if (selectedGroupItem != null && groupComboBox.Items.Contains(selectedGroupItem)) { … … 223 232 } 224 233 225 var problems = new HashSet<ProblemDescription>(); 226 foreach (var run in Content) { 227 problems.Add(new ProblemDescription(run)); 228 } 229 230 var problemTypesDifferent = problems.Select(x => x.ProblemType).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1; 231 var problemNamesDifferent = problems.Select(x => x.ProblemName).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1; 232 var evaluatorDifferent = problems.Select(x => x.Evaluator).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1; 233 var maximizationDifferent = problems.Select(x => x.Maximization).Distinct().Count() > 1; 234 var table = (string)dataTableComboBox.SelectedItem; 235 var problemDict = CalculateBestTargetPerProblemInstance(table); 236 237 var problemTypesDifferent = problemDict.Keys.Select(x => x.ProblemType).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1; 238 var problemNamesDifferent = problemDict.Keys.Select(x => x.ProblemName).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1; 239 var evaluatorDifferent = problemDict.Keys.Select(x => x.Evaluator).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1; 240 var maximizationDifferent = problemDict.Keys.Select(x => x.Maximization).Distinct().Count() > 1; 234 241 var allEqual = !problemTypesDifferent && !problemNamesDifferent && !evaluatorDifferent && !maximizationDifferent; 235 242 236 var selectedProblemItem = (ProblemDescription)problemComboBox.SelectedItem; 243 var selectedProblemItem = (ProblemInstance)problemComboBox.SelectedItem; 244 problemComboBox.DataSource = null; 237 245 problemComboBox.Items.Clear(); 238 problemComboBox.Items.Add(ProblemDescription.MatchAll); 239 if (selectedProblemItem == null || selectedProblemItem == ProblemDescription.MatchAll) 240 problemComboBox.SelectedIndex = 0; 241 foreach (var prob in problems.OrderBy(x => x.ToString()).ToList()) { 242 prob.DisplayProblemType = problemTypesDifferent; 243 prob.DisplayProblemName = problemNamesDifferent || allEqual; 244 prob.DisplayEvaluator = evaluatorDifferent; 245 prob.DisplayMaximization = maximizationDifferent; 246 problemComboBox.Items.Add(prob); 247 if (prob.Equals(selectedProblemItem)) problemComboBox.SelectedItem = prob; 246 problems.Clear(); 247 problems.Add(ProblemInstance.MatchAll); 248 problemComboBox.DataSource = new BindingSource() { DataSource = problems }; 249 problemComboBox.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged; 250 if (problems[0].Equals(selectedProblemItem)) problemComboBox.SelectedItem = problems[0]; 251 foreach (var p in problemDict.ToList()) { 252 p.Key.BestKnownQuality = p.Value; 253 p.Key.DisplayProblemType = problemTypesDifferent; 254 p.Key.DisplayProblemName = problemNamesDifferent || allEqual; 255 p.Key.DisplayEvaluator = evaluatorDifferent; 256 p.Key.DisplayMaximization = maximizationDifferent; 257 problems.Add(p.Key); 258 if (p.Key.Equals(selectedProblemItem)) problemComboBox.SelectedItem = p.Key; 248 259 } 249 260 SetEnabledStateOfControls(); … … 274 285 addTargetsAsResultButton.Enabled = Content != null && targets != null && dataTableComboBox.SelectedIndex >= 0; 275 286 addBudgetsAsResultButton.Enabled = Content != null && budgets != null && dataTableComboBox.SelectedIndex >= 0; 276 } 277 278 private Dictionary<string, Dictionary<ProblemDescription, Tuple<double, List<IRun>>>> GroupRuns() { 279 var groupedRuns = new Dictionary<string, Dictionary<ProblemDescription, Tuple<double, List<IRun>>>>(); 280 287 generateTargetsButton.Enabled = targets != null; 288 } 289 290 private IEnumerable<AlgorithmInstance> GroupRuns() { 281 291 var table = (string)dataTableComboBox.SelectedItem; 282 if (string.IsNullOrEmpty(table)) return groupedRuns;292 if (string.IsNullOrEmpty(table)) yield break; 283 293 284 294 var selectedGroup = (string)groupComboBox.SelectedItem; 285 if (string.IsNullOrEmpty(selectedGroup)) return groupedRuns; 286 287 var selectedProblem = (ProblemDescription)problemComboBox.SelectedItem; 288 if (selectedProblem == null) return groupedRuns; 289 290 var targetsPerProblem = CalculateBestTargetPerProblemInstance(table); 291 295 if (string.IsNullOrEmpty(selectedGroup)) yield break; 296 297 var selectedProblem = (ProblemInstance)problemComboBox.SelectedItem; 298 if (selectedProblem == null) yield break; 299 292 300 foreach (var x in (from r in Content 293 where (selectedGroup == All Runs || r.Parameters.ContainsKey(selectedGroup))301 where (selectedGroup == AllInstances || r.Parameters.ContainsKey(selectedGroup)) 294 302 && selectedProblem.Match(r) 295 303 && r.Results.ContainsKey(table) 296 304 && r.Visible 297 group r by selectedGroup == AllRuns ? AllRuns : r.Parameters[selectedGroup].ToString() into g 298 select Tuple.Create(g.Key, g.ToList()))) { 299 var pDict = new Dictionary<ProblemDescription, Tuple<double, List<IRun>>>(); 300 foreach (var y in (from r in x.Item2 301 let pd = new ProblemDescription(r) 302 group r by pd into g 303 select Tuple.Create(g.Key, g.ToList()))) { 304 pDict[y.Item1] = Tuple.Create(targetsPerProblem[y.Item1], y.Item2); 305 } 306 groupedRuns[x.Item1] = pDict; 307 } 308 309 return groupedRuns; 305 let key = selectedGroup == AllInstances ? AllInstances : r.Parameters[selectedGroup].ToString() 306 group r by key into g 307 select new AlgorithmInstance(g.Key, g, problems))) { 308 yield return x; 309 } 310 310 } 311 311 … … 316 316 targetChart.Series.Clear(); 317 317 invisibleTargetSeries.Clear(); 318 318 319 319 var table = (string)dataTableComboBox.SelectedItem; 320 320 if (string.IsNullOrEmpty(table)) return; … … 322 322 if (targets == null) GenerateDefaultTargets(); 323 323 324 var groupedRuns = GroupRuns();325 if ( groupedRuns.Count == 0) return;324 var algInstances = GroupRuns().ToList(); 325 if (algInstances.Count == 0) return; 326 326 327 327 var xAxisTitles = new HashSet<string>(); 328 329 // hits describes the number of target hits at a certain time for a certain group 330 var hits = new Dictionary<string, SortedList<double, int>>(); 331 // misses describes the number of target misses after a certain time for a certain group 332 // for instance when a run ends, but has not achieved all targets, misses describes 333 // how many targets have been left open at the point when the run ended 334 var misses = new Dictionary<string, SortedList<double, int>>(); 335 var totalRuns = new Dictionary<string, int>(); 336 337 var aggregate = aggregateTargetsCheckBox.Checked; 338 double minEff = double.MaxValue, maxEff = double.MinValue; 339 foreach (var alg in algInstances) { 340 var noRuns = 0; 341 SortedList<double, int> epdfHits = null, epdfMisses = null; 342 if (aggregate) { 343 hits[alg.Name] = epdfHits = new SortedList<double, int>(); 344 misses[alg.Name] = epdfMisses = new SortedList<double, int>(); 345 } 346 foreach (var problem in alg.GetProblemInstances()) { 347 var max = problem.IsMaximization(); 348 var absTargets = GetAbsoluteTargets(problem).ToArray(); 349 foreach (var run in alg.GetRuns(problem)) { 350 noRuns++; 351 var resultsTable = (IndexedDataTable<double>)run.Results[table]; 352 xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle); 353 354 var efforts = absTargets.Select(t => GetEffortToHitTarget(resultsTable.Rows.First().Values, t, max)).ToArray(); 355 minEff = Math.Min(minEff, efforts.Min(x => x.Item2)); 356 maxEff = Math.Max(maxEff, efforts.Max(x => x.Item2)); 357 for (var idx = 0; idx < efforts.Length; idx++) { 358 var e = efforts[idx]; 359 if (!aggregate) { 360 var key = alg.Name + "@" + (targetsAreRelative 361 ? (targets[idx] * 100).ToString(CultureInfo.CurrentCulture.NumberFormat) + "%" 362 : targets[idx].ToString(CultureInfo.CurrentCulture.NumberFormat)); 363 if (!hits.TryGetValue(key, out epdfHits)) 364 hits[key] = epdfHits = new SortedList<double, int>(); 365 if (!misses.TryGetValue(key, out epdfMisses)) 366 misses[key] = epdfMisses = new SortedList<double, int>(); 367 totalRuns[key] = noRuns; 368 }; 369 var list = e.Item1 ? epdfHits : epdfMisses; 370 int v; 371 if (list.TryGetValue(e.Item2, out v)) 372 list[e.Item2] = v + 1; 373 else list[e.Item2] = 1; 374 } 375 } 376 } 377 if (aggregate) totalRuns[alg.Name] = noRuns; 378 } 379 380 UpdateTargetChartAxisXBounds(minEff, maxEff); 381 382 DrawTargetsEcdf(hits, misses, totalRuns); 383 384 if (targets.Length == 1) { 385 if (targetsAreRelative) 386 targetChart.ChartAreas[0].AxisY.Title = "Probability to be " + (targets[0] * 100) + "% worse than best"; 387 else targetChart.ChartAreas[0].AxisY.Title = "Probability to reach at least a fitness of " + targets[0]; 388 } else targetChart.ChartAreas[0].AxisY.Title = "Proportion of reached targets"; 389 targetChart.ChartAreas[0].AxisX.Title = string.Join(" / ", xAxisTitles); 390 targetChart.ChartAreas[0].AxisX.IsLogarithmic = CanDisplayLogarithmic(); 391 targetChart.ChartAreas[0].CursorY.Interval = 0.05; 392 393 UpdateErtTables(algInstances); 394 } 395 396 private void DrawTargetsEcdf(Dictionary<string, SortedList<double, int>> hits, Dictionary<string, SortedList<double, int>> misses, Dictionary<string, int> noRuns) { 328 397 var colorCount = 0; 329 398 var lineStyleCount = 0; 330 331 // if the group contains multiple different problem instances we want to use the 332 // minimal maximal observed effort otherwise we run into situations where we don't 333 // have data for a certain problem instance anymore this is a special case when 334 // aggregating over multiple problem instances 335 var maxEfforts = new Dictionary<ProblemDescription, double>(); 336 double minEff = double.MaxValue, maxEff = double.MinValue; 337 foreach (var group in groupedRuns) { 338 foreach (var problem in group.Value) { 339 double problemSpecificMaxEff; 340 if (!maxEfforts.TryGetValue(problem.Key, out problemSpecificMaxEff)) { 341 problemSpecificMaxEff = 0; 342 } 343 var bestKnownTarget = problem.Value.Item1; 344 var max = problem.Key.IsMaximization(); 345 var worstTarget = (max ? (1 - targets.Max()) : (1 + targets.Max())) * bestKnownTarget; 346 var bestTarget = (max ? (1 - targets.Min()) : (1 + targets.Min())) * bestKnownTarget; 347 foreach (var run in problem.Value.Item2) { 348 var row = ((IndexedDataTable<double>)run.Results[table]).Rows.First().Values; 349 var a = row.FirstOrDefault(x => max ? x.Item2 >= worstTarget : x.Item2 <= worstTarget); 350 var b = row.FirstOrDefault(x => max ? x.Item2 >= bestTarget : x.Item2 <= bestTarget); 351 var firstEff = (a == default(Tuple<double, double>)) ? row.Last().Item1 : a.Item1; 352 var lastEff = (b == default(Tuple<double, double>)) ? row.Last().Item1 : b.Item1; 353 if (minEff > firstEff) minEff = firstEff; 354 if (maxEff < lastEff) maxEff = lastEff; 355 if (problemSpecificMaxEff < lastEff) problemSpecificMaxEff = lastEff; 356 } 357 maxEfforts[problem.Key] = problemSpecificMaxEff; 358 } 359 } 360 maxEff = Math.Min(maxEff, maxEfforts.Values.Min()); 361 399 400 var showMarkers = markerCheckBox.Checked; 401 foreach (var list in hits) { 402 var row = new Series(list.Key) { 403 ChartType = SeriesChartType.StepLine, 404 BorderWidth = 3, 405 Color = colors[colorCount], 406 BorderDashStyle = lineStyles[lineStyleCount], 407 }; 408 var rowShade = new Series(list.Key + "-range") { 409 IsVisibleInLegend = false, 410 ChartType = SeriesChartType.Range, 411 Color = Color.FromArgb(32, colors[colorCount]), 412 YValuesPerPoint = 2 413 }; 414 415 var ecdf = 0.0; 416 var missedecdf = 0.0; 417 var iter = misses[list.Key].GetEnumerator(); 418 var moreMisses = iter.MoveNext(); 419 var totalTargets = noRuns[list.Key]; 420 if (aggregateTargetsCheckBox.Checked) totalTargets *= targets.Length; 421 var movingTargets = totalTargets; 422 var labelPrinted = false; 423 foreach (var h in list.Value) { 424 var prevmissedecdf = missedecdf; 425 while (moreMisses && iter.Current.Key <= h.Key) { 426 if (!labelPrinted && row.Points.Count > 0) { 427 var point = row.Points.Last(); 428 if (showLabelsInTargetChart) 429 point.Label = row.Name; 430 point.MarkerStyle = MarkerStyle.Cross; 431 point.MarkerBorderWidth = 1; 432 point.MarkerSize = 10; 433 labelPrinted = true; 434 rowShade.Points.Add(new DataPoint(point.XValue, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets})); 435 } 436 missedecdf += iter.Current.Value; 437 movingTargets -= iter.Current.Value; 438 if (row.Points.Count > 0 && row.Points.Last().XValue == iter.Current.Key) { 439 row.Points.Last().SetValueY(ecdf / movingTargets); 440 row.Points.Last().Color = Color.FromArgb(255 - (int)Math.Floor(255 * (prevmissedecdf / totalTargets)), colors[colorCount]); 441 } else { 442 var dp = new DataPoint(iter.Current.Key, ecdf / movingTargets) { 443 Color = Color.FromArgb(255 - (int)Math.Floor(255 * (prevmissedecdf / totalTargets)), colors[colorCount]) 444 }; 445 if (showMarkers) { 446 dp.MarkerStyle = MarkerStyle.Circle; 447 dp.MarkerBorderWidth = 1; 448 dp.MarkerSize = 5; 449 } 450 row.Points.Add(dp); 451 prevmissedecdf = missedecdf; 452 } 453 if (boundShadingCheckBox.Checked) { 454 if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == iter.Current.Key) 455 rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets); 456 else rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets})); 457 } 458 moreMisses = iter.MoveNext(); 459 if (!labelPrinted) { 460 var point = row.Points.Last(); 461 if (showLabelsInTargetChart) 462 point.Label = row.Name; 463 point.MarkerStyle = MarkerStyle.Cross; 464 point.MarkerBorderWidth = 1; 465 point.MarkerSize = 10; 466 labelPrinted = true; 467 } 468 } 469 ecdf += h.Value; 470 if (row.Points.Count > 0 && row.Points.Last().XValue == h.Key) { 471 row.Points.Last().SetValueY(ecdf / movingTargets); 472 row.Points.Last().Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount]); 473 } else { 474 var dp = new DataPoint(h.Key, ecdf / movingTargets) { 475 Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount]) 476 }; 477 if (showMarkers) { 478 dp.MarkerStyle = MarkerStyle.Circle; 479 dp.MarkerBorderWidth = 1; 480 dp.MarkerSize = 5; 481 } 482 row.Points.Add(dp); 483 } 484 if (missedecdf > 0 && boundShadingCheckBox.Checked) { 485 if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == h.Key) 486 rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets); 487 else rowShade.Points.Add(new DataPoint(h.Key, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets})); 488 } 489 } 490 491 while (moreMisses) { 492 // if there are misses beyond the last hit we extend the shaded area 493 missedecdf += iter.Current.Value; 494 var dp = new DataPoint(iter.Current.Key, ecdf / movingTargets) { 495 Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount]) 496 }; 497 if (showMarkers) { 498 dp.MarkerStyle = MarkerStyle.Circle; 499 dp.MarkerBorderWidth = 1; 500 dp.MarkerSize = 5; 501 } 502 row.Points.Add(dp); 503 if (boundShadingCheckBox.Checked) { 504 rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets})); 505 } 506 moreMisses = iter.MoveNext(); 507 508 if (!labelPrinted && row.Points.Count > 0) { 509 var point = row.Points.Last(); 510 if (showLabelsInTargetChart) 511 point.Label = row.Name; 512 point.MarkerStyle = MarkerStyle.Cross; 513 point.MarkerBorderWidth = 1; 514 point.MarkerSize = 10; 515 labelPrinted = true; 516 } 517 } 518 519 if (!labelPrinted) { 520 var point = row.Points.Last(); 521 if (showLabelsInTargetChart) 522 point.Label = row.Name; 523 point.MarkerStyle = MarkerStyle.Cross; 524 point.MarkerBorderWidth = 1; 525 point.MarkerSize = 10; 526 rowShade.Points.Add(new DataPoint(point.XValue, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets})); 527 labelPrinted = true; 528 } 529 530 ConfigureSeries(row); 531 targetChart.Series.Add(rowShade); 532 targetChart.Series.Add(row); 533 534 colorCount = (colorCount + 1) % colors.Length; 535 if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length; 536 } 537 } 538 539 private void UpdateTargetChartAxisXBounds(double minEff, double maxEff) { 362 540 var minZeros = (int)Math.Floor(Math.Log10(minEff)); 363 541 var maxZeros = (int)Math.Floor(Math.Log10(maxEff)); … … 372 550 targetChart.ChartAreas[0].AxisX.Minimum = (double)axisMin; 373 551 targetChart.ChartAreas[0].AxisX.Maximum = (double)axisMax; 374 375 foreach (var group in groupedRuns) { 376 // hits describes the number of target hits at a certain time for a certain group 377 var hits = new Dictionary<string, SortedList<double, int>>(); 378 // misses describes the number of target misses after a certain time for a certain group 379 // for instance when a run ends, but has not achieved all targets, misses describes 380 // how many targets have been left open at the point when the run ended 381 var misses = new Dictionary<string, SortedList<double, int>>(); 382 var maxLength = 0.0; 383 384 var noRuns = 0; 385 foreach (var problem in group.Value) { 386 foreach (var run in problem.Value.Item2) { 387 var resultsTable = (IndexedDataTable<double>)run.Results[table]; 388 xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle); 389 390 if (aggregateTargetsCheckBox.Checked) { 391 var length = CalculateHitsForAllTargets(hits, misses, resultsTable.Rows.First(), problem.Key, group.Key, problem.Value.Item1, maxEff); 392 maxLength = Math.Max(length, maxLength); 393 } else { 394 CalculateHitsForEachTarget(hits, misses, resultsTable.Rows.First(), problem.Key, group.Key, problem.Value.Item1, maxEff); 395 } 396 noRuns++; 397 } 398 } 399 foreach (var list in hits) { 400 var row = new Series(list.Key) { 401 ChartType = SeriesChartType.StepLine, 402 BorderWidth = 2, 403 Color = colors[colorCount], 404 BorderDashStyle = lineStyles[lineStyleCount], 405 }; 406 var rowShade = new Series(list.Key + "-range") { 407 IsVisibleInLegend = false, 408 ChartType = SeriesChartType.Range, 409 Color = Color.FromArgb(32, colors[colorCount]) 410 }; 411 412 var ecdf = 0.0; 413 var missedecdf = 0.0; 414 var iter = misses[list.Key].GetEnumerator(); 415 var moreMisses = iter.MoveNext(); 416 var totalTargets = noRuns; 417 if (aggregateTargetsCheckBox.Checked) totalTargets *= targets.Length; 418 var movingTargets = totalTargets; 419 foreach (var h in list.Value) { 420 while (moreMisses && iter.Current.Key <= h.Key) { 421 missedecdf += iter.Current.Value; 422 movingTargets -= iter.Current.Value; 423 if (row.Points.Count > 0 && row.Points.Last().XValue == iter.Current.Key) 424 row.Points.Last().SetValueY(ecdf / movingTargets); 425 else row.Points.AddXY(iter.Current.Key, ecdf / movingTargets); 426 if (boundShadingCheckBox.Checked) { 427 if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == iter.Current.Key) 428 rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets); 429 else rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] { ecdf / totalTargets, (ecdf + missedecdf) / totalTargets })); 430 } 431 moreMisses = iter.MoveNext(); 432 } 433 ecdf += h.Value; 434 if (row.Points.Count > 0 && row.Points.Last().XValue == h.Key) 435 row.Points.Last().SetValueY(ecdf / movingTargets); 436 else row.Points.AddXY(h.Key, ecdf / movingTargets); 437 if (missedecdf > 0 && boundShadingCheckBox.Checked) { 438 if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == h.Key) 439 rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets); 440 else rowShade.Points.Add(new DataPoint(h.Key, new[] { ecdf / totalTargets, (ecdf + missedecdf) / totalTargets })); 441 } 442 } 443 444 while (moreMisses) { 445 // if there are misses beyond the last hit we extend the shaded area 446 missedecdf += iter.Current.Value; 447 //movingTargets -= iter.Current.Value; 448 if (row.Points.Count > 0 && row.Points.Last().XValue == iter.Current.Key) 449 row.Points.Last().SetValueY(ecdf / movingTargets); 450 else row.Points.AddXY(iter.Current.Key, ecdf / movingTargets); 451 if (boundShadingCheckBox.Checked) { 452 if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == iter.Current.Key) 453 rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets); 454 else rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] { ecdf / totalTargets, (ecdf + missedecdf) / totalTargets })); 455 } 456 moreMisses = iter.MoveNext(); 457 } 458 459 if (maxLength > 0 && (row.Points.Count == 0 || row.Points.Last().XValue < maxLength)) 460 row.Points.AddXY(maxLength, ecdf / movingTargets); 461 462 if (row.Points.Count > 0) { 463 var point = row.Points.Last(); 464 point.Label = row.Name; 465 point.MarkerStyle = MarkerStyle.Cross; 466 point.MarkerBorderWidth = 1; 467 } 468 469 ConfigureSeries(row); 470 targetChart.Series.Add(rowShade); 471 targetChart.Series.Add(row); 472 } 473 colorCount = (colorCount + 1) % colors.Length; 474 if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length; 475 } 476 477 if (targets.Length == 1) 478 targetChart.ChartAreas[0].AxisY.Title = "Probability to be " + (targets[0] * 100) + "% worse than best"; 479 else targetChart.ChartAreas[0].AxisY.Title = "Proportion of reached targets"; 480 targetChart.ChartAreas[0].AxisX.Title = string.Join(" / ", xAxisTitles); 481 targetChart.ChartAreas[0].AxisX.IsLogarithmic = CanDisplayLogarithmic(); 482 targetChart.ChartAreas[0].CursorY.Interval = 0.05; 483 UpdateErtTables(groupedRuns); 552 } 553 554 private IEnumerable<double> GetAbsoluteTargets(ProblemInstance pInstance) { 555 if (!targetsAreRelative) return targets; 556 var maximization = pInstance.IsMaximization(); 557 var bestKnown = pInstance.BestKnownQuality; 558 if (double.IsNaN(bestKnown)) throw new ArgumentException("Problem instance does not have a defined best - known quality."); 559 IEnumerable<double> tmp = null; 560 if (bestKnown > 0) { 561 tmp = targets.Select(x => (maximization ? (1 - x) : (1 + x)) * bestKnown); 562 } else if (bestKnown < 0) { 563 tmp = targets.Select(x => (!maximization ? (1 - x) : (1 + x)) * bestKnown); 564 } else { 565 // relative to 0 is impossible 566 tmp = targets; 567 } 568 return tmp; 569 } 570 571 private double[] GetAbsoluteTargetsWorstToBest(ProblemInstance pInstance) { 572 if (double.IsNaN(pInstance.BestKnownQuality)) throw new ArgumentException("Problem instance does not have a defined best-known quality."); 573 var absTargets = GetAbsoluteTargets(pInstance); 574 return (pInstance.IsMaximization() 575 ? absTargets.OrderBy(x => x) : absTargets.OrderByDescending(x => x)).ToArray(); 484 576 } 485 577 486 578 private void GenerateDefaultTargets() { 487 targets = new[] { 0.1, 0.05, 0.02, 0.01, 0 }; 488 suppressTargetsEvents = true; 489 targetsTextBox.Text = string.Join("% ; ", targets.Select(x => x * 100)) + "%"; 490 suppressTargetsEvents = false; 491 } 492 493 private void CalculateHitsForEachTarget(Dictionary<string, SortedList<double, int>> hits, 494 Dictionary<string, SortedList<double, int>> misses, 495 IndexedDataRow<double> row, ProblemDescription problem, 496 string group, double bestTarget, double maxEffort) { 497 foreach (var t in targets.Select(x => Tuple.Create((problem.IsMaximization() ? (1 - x) : (1 + x)) * bestTarget, x))) { 498 var l = t.Item1; 499 var key = group + "_" + (t.Item2 * 100) + "%_" + l; 500 if (!hits.ContainsKey(key)) { 501 hits.Add(key, new SortedList<double, int>()); 502 misses.Add(key, new SortedList<double, int>()); 503 } 504 var hit = false; 505 foreach (var v in row.Values) { 506 if (v.Item1 > maxEffort) break; 507 if (problem.IsMaximization() && v.Item2 >= l || !problem.IsMaximization() && v.Item2 <= l) { 508 if (hits[key].ContainsKey(v.Item1)) 509 hits[key][v.Item1]++; 510 else hits[key][v.Item1] = 1; 511 hit = true; 512 break; 513 } 514 } 515 if (!hit) { 516 var max = Math.Min(row.Values.Last().Item1, maxEffort); 517 if (misses[key].ContainsKey(max)) 518 misses[key][max]++; 519 else misses[key][max] = 1; 520 } 521 } 522 } 523 524 private double CalculateHitsForAllTargets(Dictionary<string, SortedList<double, int>> hits, 525 Dictionary<string, SortedList<double, int>> misses, 526 IndexedDataRow<double> row, ProblemDescription problem, 527 string group, double bestTarget, double maxEffort) { 528 var values = row.Values; 529 if (!hits.ContainsKey(group)) { 530 hits.Add(group, new SortedList<double, int>()); 531 misses.Add(group, new SortedList<double, int>()); 532 } 533 534 var i = 0; 535 var j = 0; 536 while (i < targets.Length && j < values.Count) { 537 var target = (problem.IsMaximization() ? (1 - targets[i]) : (1 + targets[i])) * bestTarget; 538 var current = values[j]; 539 if (current.Item1 > maxEffort) break; 540 if (problem.IsMaximization() && current.Item2 >= target 541 || !problem.IsMaximization() && current.Item2 <= target) { 542 if (hits[group].ContainsKey(current.Item1)) hits[group][current.Item1]++; 543 else hits[group][current.Item1] = 1; 544 i++; 545 } else { 546 j++; 547 } 548 } 549 if (j == values.Count) j--; 550 var effort = Math.Min(values[j].Item1, maxEffort); 551 if (i < targets.Length) { 552 if (misses[group].ContainsKey(effort)) 553 misses[group][effort] += targets.Length - i; 554 else misses[group][effort] = targets.Length - i; 555 } 556 return effort; 557 } 558 559 private void UpdateErtTables(Dictionary<string, Dictionary<ProblemDescription, Tuple<double, List<IRun>>>> groupedRuns) { 579 targets = new[] { 0.1, 0.095, 0.09, 0.085, 0.08, 0.075, 0.07, 0.065, 0.06, 0.055, 0.05, 0.045, 0.04, 0.035, 0.03, 0.025, 0.02, 0.015, 0.01, 0.005, 0 }; 580 SynchronizeTargetTextBox(); 581 } 582 583 private Tuple<bool, double> GetEffortToHitTarget( 584 ObservableList<Tuple<double, double>> convergenceGraph, 585 double absTarget, bool maximization) { 586 if (convergenceGraph.Count == 0) 587 throw new ArgumentException("Convergence graph is empty.", "convergenceGraph"); 588 589 var index = convergenceGraph.BinarySearch(Tuple.Create(0.0, absTarget), new TargetComparer(maximization)); 590 if (index >= 0) { 591 return Tuple.Create(true, convergenceGraph[index].Item1); 592 } else { 593 index = ~index; 594 if (index >= convergenceGraph.Count) 595 return Tuple.Create(false, convergenceGraph.Last().Item1); 596 return Tuple.Create(true, convergenceGraph[index].Item1); 597 } 598 } 599 600 private void UpdateErtTables(List<AlgorithmInstance> algorithmInstances) { 560 601 ertTableView.Content = null; 561 var columns = 1 + targets.Length + 1; 562 var matrix = new string[groupedRuns.Count * groupedRuns.Max(x => x.Value.Count) + groupedRuns.Max(x => x.Value.Count), columns]; 602 var columns = targets.Length + 1; 603 var totalRows = algorithmInstances.Count * algorithmInstances.Max(x => x.GetNumberOfProblemInstances()) + algorithmInstances.Max(x => x.GetNumberOfProblemInstances()); 604 var matrix = new StringMatrix(totalRows, columns); 605 var rowNames = new List<string>(); 606 matrix.ColumnNames = targets.Select(x => targetsAreRelative ? (100 * x).ToString() + "%" : x.ToString()) 607 .Concat(new[] { "#succ" }).ToList(); 563 608 var rowCount = 0; 564 609 565 610 var tableName = (string)dataTableComboBox.SelectedItem; 566 611 if (string.IsNullOrEmpty(tableName)) return; 567 568 var targetsPerProblem = CalculateBestTargetPerProblemInstance(tableName); 569 570 var colNames = new string[columns]; 571 colNames[0] = colNames[colNames.Length - 1] = string.Empty; 572 for (var i = 0; i < targets.Length; i++) { 573 colNames[i + 1] = targets[i].ToString("0.0%"); 574 } 575 var problems = groupedRuns.SelectMany(x => x.Value.Keys).Distinct().ToList(); 612 613 var problems = algorithmInstances.SelectMany(x => x.GetProblemInstances()).Distinct().ToList(); 576 614 577 615 foreach (var problem in problems) { 578 matrix[rowCount, 0] = problem.ToString(); 579 for (var i = 0; i < targets.Length; i++) { 580 matrix[rowCount, i + 1] = (targetsPerProblem[problem] * (problem.IsMaximization() ? (1 - targets[i]) : (1 + targets[i]))).ToString(CultureInfo.CurrentCulture.NumberFormat); 581 } 582 matrix[rowCount, columns - 1] = "#succ"; 616 var max = problem.IsMaximization(); 617 rowNames.Add(problem.ToString()); 618 var absTargets = GetAbsoluteTargetsWorstToBest(problem); 619 if (targetsAreRelative) { 620 // print out the absolute target values 621 for (var i = 0; i < absTargets.Length; i++) { 622 matrix[rowCount, i] = absTargets[i].ToString("##,0.0", CultureInfo.CurrentCulture.NumberFormat); 623 } 624 } 583 625 rowCount++; 584 626 585 foreach (var group in groupedRuns) { 586 matrix[rowCount, 0] = group.Key; 587 if (!group.Value.ContainsKey(problem)) { 627 foreach (var alg in algorithmInstances) { 628 rowNames.Add(alg.Name); 629 var runs = alg.GetRuns(problem).ToList(); 630 if (runs.Count == 0) { 588 631 matrix[rowCount, columns - 1] = "N/A"; 589 632 rowCount++; 590 633 continue; 591 634 } 592 var runs = group.Value[problem].Item2; 593 ErtCalculationResult result = default(ErtCalculationResult); 594 for (var i = 0; i < targets.Length; i++) { 595 result = ExpectedRuntimeHelper.CalculateErt(runs, tableName, (problem.IsMaximization() ? (1 - targets[i]) : (1 + targets[i])) * group.Value[problem].Item1, problem.IsMaximization()); 596 matrix[rowCount, i + 1] = result.ToString(); 635 var result = default(ErtCalculationResult); 636 for (var i = 0; i < absTargets.Length; i++) { 637 result = ExpectedRuntimeHelper.CalculateErt(runs, tableName, absTargets[i], max); 638 matrix[rowCount, i] = result.ToString(); 597 639 } 598 640 matrix[rowCount, columns - 1] = targets.Length > 0 ? result.SuccessfulRuns + "/" + result.TotalRuns : "-"; … … 600 642 } 601 643 } 602 ertTableView.Content = new StringMatrix(matrix) { ColumnNames = colNames }; 644 matrix.RowNames = rowNames; 645 ertTableView.Content = matrix; 603 646 ertTableView.DataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); 604 647 } … … 616 659 if (budgets == null) GenerateDefaultBudgets(table); 617 660 618 var groupedRuns = GroupRuns();619 if ( groupedRuns.Count == 0) return;661 var algInstances = GroupRuns().ToList(); 662 if (algInstances.Count == 0) return; 620 663 621 664 var colorCount = 0; 622 665 var lineStyleCount = 0; 623 624 var targetsPerProblem = CalculateBestTargetPerProblemInstance((string)dataTableComboBox.SelectedItem); 625 626 foreach (var group in groupedRuns) { 666 667 foreach (var alg in algInstances) { 627 668 var hits = new Dictionary<string, SortedList<double, double>>(); 628 669 629 foreach (var problem in group.Value) {630 foreach (var run in problem.Value.Item2) {670 foreach (var problem in alg.GetProblemInstances()) { 671 foreach (var run in alg.GetRuns(problem)) { 631 672 var resultsTable = (IndexedDataTable<double>)run.Results[table]; 632 673 633 if (eachOrAllBudgetsCheckBox.Checked) { 634 CalculateHitsForEachBudget(hits, resultsTable.Rows.First(), group.Value.Count, problem.Key, group.Key, problem.Value.Item2.Count, targetsPerProblem[problem.Key]); 635 } else { 636 CalculateHitsForAllBudgets(hits, resultsTable.Rows.First(), group.Value.Count, problem.Key, group.Key, problem.Value.Item2.Count, targetsPerProblem[problem.Key]); 637 } 674 CalculateHitsForEachBudget(hits, resultsTable.Rows.First(), problem, alg.Name); 638 675 } 639 676 } … … 651 688 652 689 var total = 0.0; 690 var count = list.Value.Count; 653 691 foreach (var h in list.Value) { 654 692 total += h.Value; 655 row.Values.Add(Tuple.Create(h.Key, total ));693 row.Values.Add(Tuple.Create(h.Key, total / (double)count)); 656 694 } 657 695 … … 667 705 668 706 private void GenerateDefaultBudgets(string table) { 669 var runs = GroupRuns().SelectMany(x => x.Value.Values).SelectMany(x => x.Item2).ToList();707 var runs = Content; 670 708 var min = runs.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Min()).Min(); 671 709 var max = runs.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Max()).Max(); 672 673 var maxMagnitude = (int)Math.Ceiling(Math.Log10(max)); 674 var minMagnitude = (int)Math.Floor(Math.Log10(min)); 675 if (maxMagnitude - minMagnitude >= 3) { 676 budgets = new double[maxMagnitude - minMagnitude]; 677 for (var i = minMagnitude; i < maxMagnitude; i++) { 678 budgets[i - minMagnitude] = Math.Pow(10, i); 679 } 680 } else { 681 var range = max - min; 682 budgets = Enumerable.Range(0, 6).Select(x => min + (x / 5.0) * range).ToArray(); 683 } 710 var points = 3; 711 budgets = Enumerable.Range(1, points).Select(x => min + (x / (double)points) * (max - min)).ToArray(); 684 712 suppressBudgetsEvents = true; 685 713 budgetsTextBox.Text = string.Join(" ; ", budgets); … … 687 715 } 688 716 689 private void CalculateHitsForEachBudget(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, int groupCount, ProblemDescription problem, string groupName, int problemCount, double bestTarget) { 717 private void CalculateHitsForEachBudget(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, ProblemInstance problem, string groupName) { 718 var max = problem.IsMaximization(); 719 var prevIndex = 0; 690 720 foreach (var b in budgets) { 691 721 var key = groupName + "-" + b; 722 var index = row.Values.BinarySearch(prevIndex, row.Values.Count - prevIndex, Tuple.Create(b, 0.0), new CostComparer()); 723 if (index < 0) { 724 index = ~index; 725 if (index >= row.Values.Count) break; // the run wasn't long enough to use up budget b (or any subsequent larger one) 726 } 692 727 if (!hits.ContainsKey(key)) hits.Add(key, new SortedList<double, double>()); 693 Tuple<double, double> prev = null; 694 foreach (var v in row.Values) { 695 if (v.Item1 >= b) { 696 // the budget may be too low to achieve any target 697 if (prev == null && v.Item1 != b) break; 698 var tgt = ((prev == null || v.Item1 == b) ? v.Item2 : prev.Item2); 699 tgt = problem.IsMaximization() ? bestTarget / tgt : tgt / bestTarget; 700 if (hits[key].ContainsKey(tgt)) 701 hits[key][tgt] += 1.0 / (groupCount * problemCount); 702 else hits[key][tgt] = 1.0 / (groupCount * problemCount); 703 break; 704 } 705 prev = v; 706 } 707 if (hits[key].Count == 0) hits.Remove(key); 708 } 709 } 710 711 private void CalculateHitsForAllBudgets(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, int groupCount, ProblemDescription problem, string groupName, int problemCount, double bestTarget) { 712 var values = row.Values; 713 if (!hits.ContainsKey(groupName)) hits.Add(groupName, new SortedList<double, double>()); 714 715 var i = 0; 716 var j = 0; 717 Tuple<double, double> prev = null; 718 while (i < budgets.Length && j < values.Count) { 719 var current = values[j]; 720 if (current.Item1 >= budgets[i]) { 721 if (prev != null || current.Item1 == budgets[i]) { 722 var tgt = (prev == null || current.Item1 == budgets[i]) ? current.Item2 : prev.Item2; 723 tgt = problem.IsMaximization() ? bestTarget / tgt : tgt / bestTarget; 724 if (!hits[groupName].ContainsKey(tgt)) hits[groupName][tgt] = 0; 725 hits[groupName][tgt] += 1.0 / (groupCount * problemCount * budgets.Length); 726 } 727 i++; 728 } else { 729 j++; 730 prev = current; 731 } 732 } 733 var lastTgt = values.Last().Item2; 734 lastTgt = problem.IsMaximization() ? bestTarget / lastTgt : lastTgt / bestTarget; 735 if (i < budgets.Length && !hits[groupName].ContainsKey(lastTgt)) hits[groupName][lastTgt] = 0; 736 while (i < budgets.Length) { 737 hits[groupName][lastTgt] += 1.0 / (groupCount * problemCount * budgets.Length); 738 i++; 728 var v = row.Values[index]; 729 var relTgt = CalculateRelativeDifference(max, problem.BestKnownQuality, v.Item2) + 1; 730 if (hits[key].ContainsKey(relTgt)) 731 hits[key][relTgt]++; 732 else hits[key][relTgt] = 1.0; 733 prevIndex = index; 739 734 } 740 735 } … … 743 738 private void UpdateCaption() { 744 739 Caption = Content != null ? Content.OptimizerName + " RLD View" : ViewAttribute.GetViewName(GetType()); 740 } 741 742 private void SynchronizeTargetTextBox() { 743 if (InvokeRequired) Invoke((Action)SynchronizeTargetTextBox); 744 else { 745 suppressTargetsEvents = true; 746 try { 747 if (targetsAreRelative) 748 targetsTextBox.Text = string.Join("% ; ", targets.Select(x => x * 100)) + "%"; 749 else targetsTextBox.Text = string.Join(" ; ", targets); 750 } finally { suppressTargetsEvents = false; } 751 } 745 752 } 746 753 … … 756 763 if (dataTableComboBox.SelectedIndex >= 0) 757 764 GenerateDefaultBudgets((string)dataTableComboBox.SelectedItem); 765 UpdateBestKnownQualities(); 758 766 UpdateRuns(); 759 767 SetEnabledStateOfControls(); … … 782 790 return; 783 791 } 784 targetList.Add(t / 100); 792 if (targetsAreRelative) 793 targetList.Add(t / 100); 794 else targetList.Add(t); 785 795 } 786 796 if (targetList.Count == 0) { … … 791 801 e.Cancel = false; 792 802 errorProvider.SetError(targetsTextBox, null); 793 targets = targetList.Select(x => (double)x).OrderByDescending(x => x).ToArray(); 794 suppressTargetsEvents = true; 795 try { targetsTextBox.Text = string.Join("% ; ", targets.Select(x => x * 100)) + "%"; } finally { suppressTargetsEvents = false; } 796 803 targets = targetsAreRelative ? targetList.Select(x => (double)x).OrderByDescending(x => x).ToArray() : targetList.Select(x => (double)x).ToArray(); 804 805 SynchronizeTargetTextBox(); 797 806 UpdateResultsByTarget(); 798 807 SetEnabledStateOfControls(); … … 806 815 } 807 816 817 private void relativeOrAbsoluteComboBox_SelectedIndexChanged(object sender, EventArgs e) { 818 if (suppressUpdates) return; 819 var pd = (ProblemInstance)problemComboBox.SelectedItem; 820 if (!double.IsNaN(pd.BestKnownQuality)) { 821 var max = pd.IsMaximization(); 822 if (targetsAreRelative) targets = GetAbsoluteTargets(pd).ToArray(); 823 else { 824 // Rounding to 5 digits since it's certainly appropriate for this application 825 if (pd.BestKnownQuality > 0) { 826 targets = targets.Select(x => Math.Round(max ? 1.0 - (x / pd.BestKnownQuality) : (x / pd.BestKnownQuality) - 1.0, 5)).ToArray(); 827 } else if (pd.BestKnownQuality < 0) { 828 targets = targets.Select(x => Math.Round(!max ? 1.0 - (x / pd.BestKnownQuality) : (x / pd.BestKnownQuality) - 1.0, 5)).ToArray(); 829 } 830 } 831 } 832 targetsAreRelative = (string)relativeOrAbsoluteComboBox.SelectedItem == "relative"; 833 SynchronizeTargetTextBox(); 834 835 try { 836 SuspendRepaint(); 837 UpdateResultsByTarget(); 838 } finally { ResumeRepaint(true); } 839 } 840 808 841 private void generateTargetsButton_Click(object sender, EventArgs e) { 809 decimal max = 1, min = 0, count = 10; 810 if (targets != null) { 811 max = (decimal)targets.Max(); 812 min = (decimal)targets.Min(); 813 count = targets.Length; 814 } else if (Content.Count > 0 && dataTableComboBox.SelectedIndex >= 0) { 815 var table = (string)dataTableComboBox.SelectedItem; 816 max = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item2)).Max(); 817 min = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item2)).Min(); 818 count = 6; 842 if (targets == null) return; 843 decimal max = 10, min = 0, count = 10; 844 max = (decimal)targets.Max(); 845 min = (decimal)targets.Min(); 846 count = targets.Length - 1; 847 if (targetsAreRelative) { 848 max *= 100; 849 min *= 100; 819 850 } 820 851 using (var dialog = new DefineArithmeticProgressionDialog(false, min, max, (max - min) / count)) { 821 852 if (dialog.ShowDialog() == DialogResult.OK) { 822 853 if (dialog.Values.Any()) { 823 targets = dialog.Values.Select(x => (double)x).ToArray();824 suppressTargetsEvents = true;825 targetsTextBox.Text = string.Join("% ; ", targets);826 suppressTargetsEvents = false; 827 854 targets = targetsAreRelative 855 ? dialog.Values.OrderByDescending(x => x).Select(x => (double)x / 100.0).ToArray() 856 : dialog.Values.Select(x => (double)x).ToArray(); 857 858 SynchronizeTargetTextBox(); 828 859 UpdateResultsByTarget(); 829 860 SetEnabledStateOfControls(); … … 835 866 private void addTargetsAsResultButton_Click(object sender, EventArgs e) { 836 867 var table = (string)dataTableComboBox.SelectedItem; 837 838 var targetsPerProblem = CalculateBestTargetPerProblemInstance(table); 839 868 if (string.IsNullOrEmpty(table)) return; 869 840 870 foreach (var run in Content) { 841 871 if (!run.Results.ContainsKey(table)) continue; 842 872 var resultsTable = (IndexedDataTable<double>)run.Results[table]; 843 873 var values = resultsTable.Rows.First().Values; 844 var i = 0; 845 var j = 0; 846 var pd = new ProblemDescription(run); 847 while (i < targets.Length && j < values.Count) { 848 var target = (pd.IsMaximization() ? (1 - targets[i]) : (1 + targets[i])) * targetsPerProblem[pd]; 849 var current = values[j]; 850 if (pd.IsMaximization() && current.Item2 >= target 851 || !pd.IsMaximization() && current.Item2 <= target) { 852 run.Results[table + ".Target" + target] = new DoubleValue(current.Item1); 853 i++; 854 } else { 855 j++; 856 } 857 } 858 } 874 var pd = new ProblemInstance(run); 875 pd = problems.Single(x => x.Equals(pd)); 876 var max = pd.IsMaximization(); 877 var absTargets = GetAbsoluteTargetsWorstToBest(pd); 878 879 var prevIndex = 0; 880 for (var i = 0; i < absTargets.Length; i++) { 881 var absTarget = absTargets[i]; 882 var index = values.BinarySearch(prevIndex, values.Count - prevIndex, Tuple.Create(0.0, absTarget), new TargetComparer(max)); 883 if (index < 0) { 884 index = ~index; 885 if (index >= values.Count) break; // the target (and subsequent ones) wasn't achieved 886 } 887 var target = targetsAreRelative ? (targets[i] * 100) : absTarget; 888 run.Results[table + (targetsAreRelative ? ".RelTarget " : ".AbsTarget ") + target + (targetsAreRelative ? "%" : string.Empty)] = new DoubleValue(values[index].Item1); 889 prevIndex = index; 890 } 891 } 892 } 893 894 private void markerCheckBox_CheckedChanged(object sender, EventArgs e) { 895 SuspendRepaint(); 896 try { 897 UpdateResultsByTarget(); 898 } finally { ResumeRepaint(true); } 899 } 900 901 private void showLabelsCheckBox_CheckedChanged(object sender, EventArgs e) { 902 showLabelsInTargetChart = showLabelsCheckBox.Checked; 903 SuspendRepaint(); 904 try { 905 UpdateResultsByTarget(); 906 } finally { ResumeRepaint(true); } 859 907 } 860 908 #endregion … … 869 917 double b; 870 918 if (!double.TryParse(ts, out b)) { 871 errorProvider.SetError(budgetsTextBox, "Not all targets can be parsed: " + ts);919 errorProvider.SetError(budgetsTextBox, "Not all budgets can be parsed: " + ts); 872 920 e.Cancel = true; 873 921 return; … … 876 924 } 877 925 if (budgetList.Count == 0) { 878 errorProvider.SetError(budgetsTextBox, "Give at least one target value!");926 errorProvider.SetError(budgetsTextBox, "Give at least one budget value!"); 879 927 e.Cancel = true; 880 928 return; … … 882 930 e.Cancel = false; 883 931 errorProvider.SetError(budgetsTextBox, null); 884 budgets = budgetList.ToArray(); 932 budgets = budgetList.OrderBy(x => x).ToArray(); 933 try { 934 suppressBudgetsEvents = true; 935 budgetsTextBox.Text = string.Join(" ; ", budgets); 936 } finally { suppressBudgetsEvents = false; } 885 937 UpdateResultsByCost(); 886 938 SetEnabledStateOfControls(); 887 }888 889 private void eachOrAllBudgetsCheckBox_CheckedChanged(object sender, EventArgs e) {890 var each = eachOrAllBudgetsCheckBox.Checked;891 eachOrAllBudgetsCheckBox.Text = each ? "each" : "all";892 SuspendRepaint();893 try {894 UpdateResultsByCost();895 } finally { ResumeRepaint(true); }896 939 } 897 940 … … 906 949 min = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item1)).Min(); 907 950 max = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item1)).Max(); 908 count = 6;951 count = 3; 909 952 } 910 953 using (var dialog = new DefineArithmeticProgressionDialog(false, min, max, (max - min) / count)) { … … 913 956 budgets = dialog.Values.OrderBy(x => x).Select(x => (double)x).ToArray(); 914 957 915 suppressBudgetsEvents = true; 916 budgetsTextBox.Text = string.Join(" ; ", budgets); 917 suppressBudgetsEvents = false; 958 try { 959 suppressBudgetsEvents = true; 960 budgetsTextBox.Text = string.Join(" ; ", budgets); 961 } finally { suppressBudgetsEvents = false; } 918 962 919 963 UpdateResultsByCost(); … … 926 970 private void addBudgetsAsResultButton_Click(object sender, EventArgs e) { 927 971 var table = (string)dataTableComboBox.SelectedItem; 928 var budgetStrings = budgetsTextBox.Text.Split(new[] { ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries);929 if (budgetStrings.Length == 0) {930 MessageBox.Show("Define a number of budgets.");931 return;932 }933 var budgetList = new List<double>();934 foreach (var bs in budgetStrings) {935 double v;936 if (!double.TryParse(bs, out v)) {937 MessageBox.Show("Budgets must be a valid number: " + bs);938 return;939 }940 budgetList.Add(v);941 }942 budgetList.Sort();943 972 944 973 foreach (var run in Content) { … … 946 975 var resultsTable = (IndexedDataTable<double>)run.Results[table]; 947 976 var values = resultsTable.Rows.First().Values; 948 var i = 0; 949 var j = 0; 950 Tuple<double, double> prev = null; 951 while (i < budgetList.Count && j < values.Count) { 952 var current = values[j]; 953 if (current.Item1 >= budgetList[i]) { 954 if (prev != null || current.Item1 == budgetList[i]) { 955 var tgt = (prev == null || current.Item1 == budgetList[i]) ? current.Item2 : prev.Item2; 956 run.Results[table + ".Cost" + budgetList[i]] = new DoubleValue(tgt); 957 } 958 i++; 959 } else { 960 j++; 961 prev = current; 962 } 977 var pd = new ProblemInstance(run); 978 pd = problems.Single(x => x.Equals(pd)); 979 980 var prevIndex = 0; 981 foreach (var b in budgets) { 982 var index = values.BinarySearch(prevIndex, values.Count - prevIndex, Tuple.Create(b, 0.0), new CostComparer()); 983 if (index < 0) { 984 index = ~index; 985 if (index >= values.Count) break; // the run wasn't long enough to use up budget b (or any subsequent larger one) 986 } 987 var v = values[index]; 988 var tgt = targetsAreRelative ? CalculateRelativeDifference(pd.IsMaximization(), pd.BestKnownQuality, v.Item2) : v.Item2; 989 run.Results[table + (targetsAreRelative ? ".CostForRelTarget " : ".CostForAbsTarget ") + b] = new DoubleValue(tgt); 990 prevIndex = index; 963 991 } 964 992 } … … 967 995 968 996 #region Helpers 969 private Dictionary<ProblemDescription, double> CalculateBestTargetPerProblemInstance(string table) { 997 private double CalculateRelativeDifference(bool maximization, double bestKnown, double fit) { 998 if (bestKnown == 0) { 999 // no relative difference with respect to bestKnown possible 1000 return maximization ? -fit : fit; 1001 } 1002 var absDiff = (fit - bestKnown); 1003 var relDiff = absDiff / bestKnown; 1004 if (maximization) { 1005 return bestKnown > 0 ? -relDiff : relDiff; 1006 } else { 1007 return bestKnown > 0 ? relDiff : -relDiff; 1008 } 1009 } 1010 1011 private Dictionary<ProblemInstance, double> CalculateBestTargetPerProblemInstance(string table) { 1012 if (table == null) table = string.Empty; 970 1013 return (from r in Content 971 1014 where r.Visible 972 let pd = new Problem Description(r)1015 let pd = new ProblemInstance(r) 973 1016 let target = r.Parameters.ContainsKey("BestKnownQuality") 974 1017 && r.Parameters["BestKnownQuality"] is DoubleValue 975 1018 ? ((DoubleValue)r.Parameters["BestKnownQuality"]).Value 976 : ((IndexedDataTable<double>)r.Results[table]).Rows.First().Values.Last().Item2 1019 : (r.Results.ContainsKey(table) && r.Results[table] is IndexedDataTable<double> 1020 ? ((IndexedDataTable<double>)r.Results[table]).Rows.First().Values.Last().Item2 1021 : double.NaN) 977 1022 group target by pd into g 978 select new { Problem = g.Key, Target = g. Key.IsMaximization() ? g.Max() : g.Min()})1023 select new { Problem = g.Key, Target = g.Any(x => !double.IsNaN(x)) ? (g.Key.IsMaximization() ? g.Max() : g.Where(x => !double.IsNaN(x)).Min()) : double.NaN }) 979 1024 .ToDictionary(x => x.Problem, x => x.Target); 980 1025 } … … 991 1036 } finally { ResumeRepaint(true); } 992 1037 } 1038 1039 private void UpdateBestKnownQualities() { 1040 var table = (string)dataTableComboBox.SelectedItem; 1041 if (string.IsNullOrEmpty(table)) return; 1042 1043 var targetsPerProblem = CalculateBestTargetPerProblemInstance(table); 1044 foreach (var pd in problems) { 1045 double bkq; 1046 if (targetsPerProblem.TryGetValue(pd, out bkq)) 1047 pd.BestKnownQuality = bkq; 1048 else pd.BestKnownQuality = double.NaN; 1049 } 1050 } 993 1051 #endregion 994 1052 995 1053 private void ConfigureSeries(Series series) { 996 series.SmartLabelStyle.Enabled = true;1054 series.SmartLabelStyle.Enabled = showLabelsInTargetChart; 997 1055 series.SmartLabelStyle.AllowOutsidePlotArea = LabelOutsidePlotAreaStyle.No; 998 1056 series.SmartLabelStyle.CalloutLineAnchorCapStyle = LineAnchorCapStyle.None; … … 1078 1136 } 1079 1137 1080 private class ProblemDescription { 1138 private class AlgorithmInstance : INotifyPropertyChanged { 1139 private string name; 1140 public string Name { 1141 get { return name; } 1142 set { 1143 if (name == value) return; 1144 name = value; 1145 OnPropertyChanged("Name"); 1146 } 1147 } 1148 1149 private Dictionary<ProblemInstance, List<IRun>> performanceData; 1150 1151 public int GetNumberOfProblemInstances() { 1152 return performanceData.Count; 1153 } 1154 1155 public IEnumerable<ProblemInstance> GetProblemInstances() { 1156 return performanceData.Keys; 1157 } 1158 1159 public int GetNumberOfRuns(ProblemInstance p) { 1160 if (p == ProblemInstance.MatchAll) return performanceData.Select(x => x.Value.Count).Sum(); 1161 List<IRun> runs; 1162 if (performanceData.TryGetValue(p, out runs)) 1163 return runs.Count; 1164 1165 return 0; 1166 } 1167 1168 public IEnumerable<IRun> GetRuns(ProblemInstance p) { 1169 if (p == ProblemInstance.MatchAll) return performanceData.SelectMany(x => x.Value); 1170 List<IRun> runs; 1171 if (performanceData.TryGetValue(p, out runs)) 1172 return runs; 1173 1174 return Enumerable.Empty<IRun>(); 1175 } 1176 1177 public AlgorithmInstance(string name, IEnumerable<IRun> runs, IEnumerable<ProblemInstance> problems) { 1178 this.name = name; 1179 1180 var pDict = problems.ToDictionary(r => r, _ => new List<IRun>()); 1181 foreach (var y in runs) { 1182 var pd = new ProblemInstance(y); 1183 List<IRun> l; 1184 if (pDict.TryGetValue(pd, out l)) l.Add(y); 1185 } 1186 performanceData = pDict.Where(x => x.Value.Count > 0).ToDictionary(x => x.Key, x => x.Value); 1187 } 1188 1189 public override bool Equals(object obj) { 1190 var other = obj as AlgorithmInstance; 1191 if (other == null) return false; 1192 return name == other.name; 1193 } 1194 1195 public override int GetHashCode() { 1196 return name.GetHashCode(); 1197 } 1198 1199 public event PropertyChangedEventHandler PropertyChanged; 1200 protected virtual void OnPropertyChanged(string propertyName = null) { 1201 var handler = PropertyChanged; 1202 if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 1203 } 1204 } 1205 1206 private class ProblemInstance : INotifyPropertyChanged { 1081 1207 private readonly bool matchAll; 1082 public static readonly Problem Description MatchAll = new ProblemDescription() {1208 public static readonly ProblemInstance MatchAll = new ProblemInstance() { 1083 1209 ProblemName = "All with Best-Known" 1084 1210 }; 1085 1211 1086 private Problem Description() {1212 private ProblemInstance() { 1087 1213 ProblemType = string.Empty; 1088 1214 ProblemName = string.Empty; … … 1094 1220 DisplayMaximization = false; 1095 1221 matchAll = true; 1096 } 1097 1098 public ProblemDescription(IRun run) { 1222 BestKnownQuality = double.NaN; 1223 } 1224 1225 public ProblemInstance(IRun run) { 1099 1226 ProblemType = GetStringValueOrEmpty(run, "Problem Type"); 1100 1227 ProblemName = GetStringValueOrEmpty(run, "Problem Name"); … … 1106 1233 DisplayMaximization = !string.IsNullOrEmpty(Maximization); 1107 1234 matchAll = false; 1108 } 1109 1110 public bool DisplayProblemType { get; set; } 1111 public string ProblemType { get; set; } 1112 public bool DisplayProblemName { get; set; } 1113 public string ProblemName { get; set; } 1114 public bool DisplayEvaluator { get; set; } 1115 public string Evaluator { get; set; } 1116 public bool DisplayMaximization { get; set; } 1117 public string Maximization { get; set; } 1235 BestKnownQuality = GetDoubleValueOrNaN(run, "BestKnownQuality"); 1236 } 1237 1238 private bool displayProblemType; 1239 public bool DisplayProblemType { 1240 get { return displayProblemType; } 1241 set { 1242 if (displayProblemType == value) return; 1243 displayProblemType = value; 1244 OnPropertyChanged("DisplayProblemType"); 1245 } 1246 } 1247 private string problemType; 1248 public string ProblemType { 1249 get { return problemType; } 1250 set { 1251 if (problemType == value) return; 1252 problemType = value; 1253 OnPropertyChanged("ProblemType"); 1254 } 1255 } 1256 private bool displayProblemName; 1257 public bool DisplayProblemName { 1258 get { return displayProblemName; } 1259 set { 1260 if (displayProblemName == value) return; 1261 displayProblemName = value; 1262 OnPropertyChanged("DisplayProblemName"); 1263 } 1264 } 1265 private string problemName; 1266 public string ProblemName { 1267 get { return problemName; } 1268 set { 1269 if (problemName == value) return; 1270 problemName = value; 1271 OnPropertyChanged("ProblemName"); 1272 } 1273 } 1274 private bool displayEvaluator; 1275 public bool DisplayEvaluator { 1276 get { return displayEvaluator; } 1277 set { 1278 if (displayEvaluator == value) return; 1279 displayEvaluator = value; 1280 OnPropertyChanged("DisplayEvaluator"); 1281 } 1282 } 1283 private string evaluator; 1284 public string Evaluator { 1285 get { return evaluator; } 1286 set { 1287 if (evaluator == value) return; 1288 evaluator = value; 1289 OnPropertyChanged("Evaluator"); 1290 } 1291 } 1292 private bool displayMaximization; 1293 public bool DisplayMaximization { 1294 get { return displayMaximization; } 1295 set { 1296 if (displayMaximization == value) return; 1297 displayMaximization = value; 1298 OnPropertyChanged("DisplayMaximization"); 1299 } 1300 } 1301 private string maximization; 1302 public string Maximization { 1303 get { return maximization; } 1304 set { 1305 if (maximization == value) return; 1306 maximization = value; 1307 OnPropertyChanged("Maximization"); 1308 } 1309 } 1310 private double bestKnownQuality; 1311 public double BestKnownQuality { 1312 get { return bestKnownQuality; } 1313 set { 1314 if (bestKnownQuality == value) return; 1315 bestKnownQuality = value; 1316 OnPropertyChanged("BestKnownQuality"); 1317 } 1318 } 1118 1319 1119 1320 public bool IsMaximization() { … … 1129 1330 } 1130 1331 1332 private double GetDoubleValueOrNaN(IRun run, string key) { 1333 IItem param; 1334 if (run.Parameters.TryGetValue(key, out param)) { 1335 var dv = param as DoubleValue; 1336 return dv != null ? dv.Value : double.NaN; 1337 } 1338 return double.NaN; 1339 } 1340 1131 1341 private string GetStringValueOrEmpty(IRun run, string key) { 1132 return run.Parameters.ContainsKey(key) ? ((StringValue)run.Parameters[key]).Value : string.Empty; 1342 IItem param; 1343 if (run.Parameters.TryGetValue(key, out param)) { 1344 var sv = param as StringValue; 1345 return sv != null ? sv.Value : string.Empty; 1346 } 1347 return string.Empty; 1133 1348 } 1134 1349 1135 1350 private string GetMaximizationValueOrEmpty(IRun run, string key) { 1136 return run.Parameters.ContainsKey(key) ? (((BoolValue)run.Parameters[key]).Value ? "MAX" : "MIN") : string.Empty; 1351 IItem param; 1352 if (run.Parameters.TryGetValue(key, out param)) { 1353 var bv = param as BoolValue; 1354 return bv != null ? (bv.Value ? "MAX" : "MIN") : string.Empty; 1355 } 1356 return string.Empty; 1137 1357 } 1138 1358 1139 1359 public override bool Equals(object obj) { 1140 var other = obj as Problem Description;1360 var other = obj as ProblemInstance; 1141 1361 if (other == null) return false; 1142 1362 return ProblemType == other.ProblemType … … 1155 1375 (DisplayProblemName ? ProblemName : string.Empty), 1156 1376 (DisplayEvaluator ? Evaluator : string.Empty), 1157 (DisplayMaximization ? Maximization : string.Empty)}.Where(x => !string.IsNullOrEmpty(x))); 1377 (DisplayMaximization ? Maximization : string.Empty), 1378 !double.IsNaN(BestKnownQuality) ? BestKnownQuality.ToString(CultureInfo.CurrentCulture.NumberFormat) : string.Empty }.Where(x => !string.IsNullOrEmpty(x))); 1379 } 1380 1381 public event PropertyChangedEventHandler PropertyChanged; 1382 protected virtual void OnPropertyChanged(string propertyName = null) { 1383 var handler = PropertyChanged; 1384 if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 1385 } 1386 } 1387 1388 private class CostComparer : Comparer<Tuple<double, double>> { 1389 public override int Compare(Tuple<double, double> x, Tuple<double, double> y) { 1390 return x.Item1.CompareTo(y.Item1); 1391 } 1392 } 1393 1394 private class TargetComparer : Comparer<Tuple<double, double>> { 1395 public bool Maximization { get; private set; } 1396 public TargetComparer(bool maximization) { 1397 Maximization = maximization; 1398 } 1399 1400 public override int Compare(Tuple<double, double> x, Tuple<double, double> y) { 1401 return Maximization ? x.Item2.CompareTo(y.Item2) : y.Item2.CompareTo(x.Item2); 1158 1402 } 1159 1403 }
Note: See TracChangeset
for help on using the changeset viewer.