Changeset 14654 for trunk/sources/HeuristicLab.Optimization.Views/3.3
- Timestamp:
- 02/08/17 22:49:12 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs
r14652 r14654 299 299 && r.Results.ContainsKey(table) 300 300 && r.Visible 301 group r by selectedGroup == AllRuns ? AllRuns : r.Parameters[selectedGroup].ToString() into g 301 let key = selectedGroup == AllRuns ? AllRuns : r.Parameters[selectedGroup].ToString() 302 group r by key into g 302 303 select Tuple.Create(g.Key, g.ToList()))) { 303 304 var pDict = problems.ToDictionary(r => r, _ => new List<IRun>()); … … 329 330 330 331 var xAxisTitles = new HashSet<string>(); 332 333 // hits describes the number of target hits at a certain time for a certain group 334 var hits = new Dictionary<string, SortedList<double, int>>(); 335 // misses describes the number of target misses after a certain time for a certain group 336 // for instance when a run ends, but has not achieved all targets, misses describes 337 // how many targets have been left open at the point when the run ended 338 var misses = new Dictionary<string, SortedList<double, int>>(); 339 340 var aggregate = aggregateTargetsCheckBox.Checked; 341 double minEff = double.MaxValue, maxEff = double.MinValue; 342 var noRuns = 0; 343 foreach (var group in groupedRuns) { 344 SortedList<double, int> epdfHits = null, epdfMisses = null; 345 if (aggregate) { 346 hits[group.Key] = epdfHits = new SortedList<double, int>(); 347 misses[group.Key] = epdfMisses = new SortedList<double, int>(); 348 } 349 foreach (var problem in group.Value) { 350 var max = problem.Key.IsMaximization(); 351 var absTargets = GetAbsoluteTargets(problem.Key).ToArray(); 352 foreach (var run in problem.Value) { 353 noRuns++; 354 var resultsTable = (IndexedDataTable<double>)run.Results[table]; 355 xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle); 356 357 var efforts = absTargets.Select(t => GetEffortToHitTarget(resultsTable.Rows.First().Values, t, max)).ToArray(); 358 minEff = Math.Min(minEff, efforts.Min(x => x.Item2)); 359 maxEff = Math.Max(maxEff, efforts.Max(x => x.Item2)); 360 for (var idx = 0; idx < efforts.Length; idx++) { 361 var e = efforts[idx]; 362 if (!aggregate) { 363 var key = group.Key + "@" + (targetsAreRelative 364 ? (targets[idx] * 100).ToString(CultureInfo.CurrentCulture.NumberFormat) + "%" 365 : targets[idx].ToString(CultureInfo.CurrentCulture.NumberFormat)); 366 if (!hits.TryGetValue(key, out epdfHits)) 367 hits[key] = epdfHits = new SortedList<double, int>(); 368 if (!misses.TryGetValue(key, out epdfMisses)) 369 misses[key] = epdfMisses = new SortedList<double, int>(); 370 } 371 var list = e.Item1 ? epdfHits : epdfMisses; 372 int v; 373 if (list.TryGetValue(e.Item2, out v)) 374 list[e.Item2] = v + 1; 375 else list[e.Item2] = 1; 376 } 377 } 378 } 379 } 380 381 UpdateTargetChartAxisXBounds(minEff, maxEff); 382 383 DrawTargetsEcdf(hits, misses, noRuns); 384 385 if (targets.Length == 1) { 386 if (targetsAreRelative) 387 targetChart.ChartAreas[0].AxisY.Title = "Probability to be " + (targets[0] * 100) + "% worse than best"; 388 else targetChart.ChartAreas[0].AxisY.Title = "Probability to reach at least a fitness of " + targets[0]; 389 } else targetChart.ChartAreas[0].AxisY.Title = "Proportion of reached targets"; 390 targetChart.ChartAreas[0].AxisX.Title = string.Join(" / ", xAxisTitles); 391 targetChart.ChartAreas[0].AxisX.IsLogarithmic = CanDisplayLogarithmic(); 392 targetChart.ChartAreas[0].CursorY.Interval = 0.05; 393 394 UpdateErtTables(groupedRuns); 395 } 396 397 private void DrawTargetsEcdf(Dictionary<string, SortedList<double, int>> hits, Dictionary<string, SortedList<double, int>> misses, int noRuns) { 331 398 var colorCount = 0; 332 399 var lineStyleCount = 0; 333 334 // if the group contains multiple different problem instances we want to use the 335 // minimal maximal observed effort otherwise we run into situations where we don't 336 // have data for a certain problem instance anymore this is a special case when 337 // aggregating over multiple problem instances 338 var maxEfforts = new Dictionary<ProblemInstance, double>(); 339 double minEff = double.MaxValue, maxEff = double.MinValue; 340 foreach (var group in groupedRuns) { 341 foreach (var problem in group.Value) { 342 double problemSpecificMaxEff; 343 if (!maxEfforts.TryGetValue(problem.Key, out problemSpecificMaxEff)) { 344 problemSpecificMaxEff = 0; 345 } 346 var max = problem.Key.IsMaximization(); 347 var absTargets = GetAbsoluteTargetsWorstToBest(max, problem.Key.BestKnownQuality); 348 var worstTarget = absTargets.First(); 349 var bestTarget = absTargets.Last(); 350 foreach (var run in problem.Value) { 351 var row = ((IndexedDataTable<double>)run.Results[table]).Rows.First().Values; 352 var a = row.FirstOrDefault(x => max ? x.Item2 >= worstTarget : x.Item2 <= worstTarget); 353 var b = row.FirstOrDefault(x => max ? x.Item2 >= bestTarget : x.Item2 <= bestTarget); 354 var firstEff = (a == default(Tuple<double, double>)) ? row.Last().Item1 : a.Item1; 355 var lastEff = (b == default(Tuple<double, double>)) ? row.Last().Item1 : b.Item1; 356 if (minEff > firstEff) minEff = firstEff; 357 if (maxEff < lastEff) maxEff = lastEff; 358 if (problemSpecificMaxEff < lastEff) problemSpecificMaxEff = lastEff; 359 } 360 maxEfforts[problem.Key] = problemSpecificMaxEff; 361 } 362 } 363 maxEff = Math.Min(maxEff, maxEfforts.Values.Min()); 364 400 401 var showMarkers = markerCheckBox.Checked; 402 foreach (var list in hits) { 403 var row = new Series(list.Key) { 404 ChartType = SeriesChartType.StepLine, 405 BorderWidth = 3, 406 Color = colors[colorCount], 407 BorderDashStyle = lineStyles[lineStyleCount], 408 }; 409 var rowShade = new Series(list.Key + "-range") { 410 IsVisibleInLegend = false, 411 ChartType = SeriesChartType.Range, 412 Color = Color.FromArgb(32, colors[colorCount]), 413 YValuesPerPoint = 2 414 }; 415 416 var ecdf = 0.0; 417 var missedecdf = 0.0; 418 var iter = misses[list.Key].GetEnumerator(); 419 var moreMisses = iter.MoveNext(); 420 var totalTargets = noRuns; 421 if (aggregateTargetsCheckBox.Checked) totalTargets *= targets.Length; 422 var movingTargets = totalTargets; 423 var labelPrinted = false; 424 foreach (var h in list.Value) { 425 var prevmissedecdf = missedecdf; 426 while (moreMisses && iter.Current.Key <= h.Key) { 427 if (!labelPrinted && row.Points.Count > 0) { 428 var point = row.Points.Last(); 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 point.Label = row.Name; 462 point.MarkerStyle = MarkerStyle.Cross; 463 point.MarkerBorderWidth = 1; 464 point.MarkerSize = 10; 465 labelPrinted = true; 466 } 467 } 468 ecdf += h.Value; 469 if (row.Points.Count > 0 && row.Points.Last().XValue == h.Key) { 470 row.Points.Last().SetValueY(ecdf / movingTargets); 471 row.Points.Last().Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount]); 472 } else { 473 var dp = new DataPoint(h.Key, ecdf / movingTargets) { 474 Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount]) 475 }; 476 if (showMarkers) { 477 dp.MarkerStyle = MarkerStyle.Circle; 478 dp.MarkerBorderWidth = 1; 479 dp.MarkerSize = 5; 480 } 481 row.Points.Add(dp); 482 } 483 if (missedecdf > 0 && boundShadingCheckBox.Checked) { 484 if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == h.Key) 485 rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets); 486 else rowShade.Points.Add(new DataPoint(h.Key, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets})); 487 } 488 } 489 490 while (moreMisses) { 491 // if there are misses beyond the last hit we extend the shaded area 492 missedecdf += iter.Current.Value; 493 var dp = new DataPoint(iter.Current.Key, ecdf / movingTargets) { 494 Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount]) 495 }; 496 if (showMarkers) { 497 dp.MarkerStyle = MarkerStyle.Circle; 498 dp.MarkerBorderWidth = 1; 499 dp.MarkerSize = 5; 500 } 501 row.Points.Add(dp); 502 if (boundShadingCheckBox.Checked) { 503 rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets})); 504 } 505 moreMisses = iter.MoveNext(); 506 507 if (!labelPrinted && row.Points.Count > 0) { 508 var point = row.Points.Last(); 509 point.Label = row.Name; 510 point.MarkerStyle = MarkerStyle.Cross; 511 point.MarkerBorderWidth = 1; 512 point.MarkerSize = 10; 513 labelPrinted = true; 514 } 515 } 516 517 if (!labelPrinted) { 518 var point = row.Points.Last(); 519 point.Label = row.Name; 520 point.MarkerStyle = MarkerStyle.Cross; 521 point.MarkerBorderWidth = 1; 522 point.MarkerSize = 10; 523 rowShade.Points.Add(new DataPoint(point.XValue, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets})); 524 labelPrinted = true; 525 } 526 527 ConfigureSeries(row); 528 targetChart.Series.Add(rowShade); 529 targetChart.Series.Add(row); 530 531 colorCount = (colorCount + 1) % colors.Length; 532 if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length; 533 } 534 } 535 536 private void UpdateTargetChartAxisXBounds(double minEff, double maxEff) { 365 537 var minZeros = (int)Math.Floor(Math.Log10(minEff)); 366 538 var maxZeros = (int)Math.Floor(Math.Log10(maxEff)); … … 375 547 targetChart.ChartAreas[0].AxisX.Minimum = (double)axisMin; 376 548 targetChart.ChartAreas[0].AxisX.Maximum = (double)axisMax; 377 378 foreach (var group in groupedRuns) { 379 // hits describes the number of target hits at a certain time for a certain group 380 var hits = new Dictionary<string, SortedList<double, int>>(); 381 // misses describes the number of target misses after a certain time for a certain group 382 // for instance when a run ends, but has not achieved all targets, misses describes 383 // how many targets have been left open at the point when the run ended 384 var misses = new Dictionary<string, SortedList<double, int>>(); 385 var maxLength = 0.0; 386 387 var noRuns = 0; 388 foreach (var problem in group.Value) { 389 foreach (var run in problem.Value) { 390 var resultsTable = (IndexedDataTable<double>)run.Results[table]; 391 xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle); 392 393 if (aggregateTargetsCheckBox.Checked) { 394 var length = CalculateHitsForAllTargets(hits, misses, resultsTable.Rows.First(), problem.Key, group.Key, problem.Key.BestKnownQuality, maxEff); 395 maxLength = Math.Max(length, maxLength); 396 } else { 397 CalculateHitsForEachTarget(hits, misses, resultsTable.Rows.First(), problem.Key, group.Key, problem.Key.BestKnownQuality, maxEff); 398 } 399 noRuns++; 400 } 401 } 402 var showMarkers = markerCheckBox.Checked; 403 foreach (var list in hits) { 404 var row = new Series(list.Key) { 405 ChartType = SeriesChartType.StepLine, 406 BorderWidth = 3, 407 Color = colors[colorCount], 408 BorderDashStyle = lineStyles[lineStyleCount], 409 }; 410 var rowShade = new Series(list.Key + "-range") { 411 IsVisibleInLegend = false, 412 ChartType = SeriesChartType.Range, 413 Color = Color.FromArgb(32, colors[colorCount]), 414 YValuesPerPoint = 2 415 }; 416 417 var ecdf = 0.0; 418 var missedecdf = 0.0; 419 var iter = misses[list.Key].GetEnumerator(); 420 var moreMisses = iter.MoveNext(); 421 var totalTargets = noRuns; 422 if (aggregateTargetsCheckBox.Checked) totalTargets *= targets.Length; 423 var movingTargets = totalTargets; 424 var labelPrinted = false; 425 foreach (var h in list.Value) { 426 var prevmissedecdf = missedecdf; 427 while (moreMisses && iter.Current.Key <= h.Key) { 428 if (!labelPrinted && row.Points.Count > 0) { 429 var point = row.Points.Last(); 430 point.Label = row.Name; 431 point.MarkerStyle = MarkerStyle.Cross; 432 point.MarkerBorderWidth = 1; 433 point.MarkerSize = 10; 434 labelPrinted = true; 435 rowShade.Points.Add(new DataPoint(point.XValue, new[] { ecdf / totalTargets, (ecdf + missedecdf) / totalTargets })); 436 } 437 missedecdf += iter.Current.Value; 438 movingTargets -= iter.Current.Value; 439 if (row.Points.Count > 0 && row.Points.Last().XValue == iter.Current.Key) { 440 row.Points.Last().SetValueY(ecdf / movingTargets); 441 row.Points.Last().Color = Color.FromArgb(255 - (int)Math.Floor(255 * (prevmissedecdf / totalTargets)), colors[colorCount]); 442 } else { 443 var dp = new DataPoint(iter.Current.Key, ecdf / movingTargets) { 444 Color = Color.FromArgb(255 - (int)Math.Floor(255 * (prevmissedecdf / totalTargets)), colors[colorCount]) 445 }; 446 if (showMarkers) { 447 dp.MarkerStyle = MarkerStyle.Circle; 448 dp.MarkerBorderWidth = 1; 449 dp.MarkerSize = 5; 450 } 451 row.Points.Add(dp); 452 prevmissedecdf = missedecdf; 453 } 454 if (boundShadingCheckBox.Checked) { 455 if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == iter.Current.Key) 456 rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets); 457 else rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] { ecdf / totalTargets, (ecdf + missedecdf) / totalTargets })); 458 } 459 moreMisses = iter.MoveNext(); 460 if (!labelPrinted) { 461 var point = row.Points.Last(); 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 if (!labelPrinted && row.Points.Count > 0) { 492 var point = row.Points.Last(); 493 point.Label = row.Name; 494 point.MarkerStyle = MarkerStyle.Cross; 495 point.MarkerBorderWidth = 1; 496 point.MarkerSize = 10; 497 rowShade.Points.Add(new DataPoint(point.XValue, new[] { ecdf / totalTargets, (ecdf + missedecdf) / totalTargets })); 498 } 499 500 while (moreMisses) { 501 // if there are misses beyond the last hit we extend the shaded area 502 missedecdf += iter.Current.Value; 503 //movingTargets -= iter.Current.Value; 504 if (row.Points.Count > 0 && row.Points.Last().XValue == iter.Current.Key) { 505 row.Points.Last().SetValueY(ecdf / movingTargets); 506 row.Points.Last().Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount]); 507 } else { 508 var dp = new DataPoint(iter.Current.Key, ecdf / movingTargets) { 509 Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount]) 510 }; 511 if (showMarkers) { 512 dp.MarkerStyle = MarkerStyle.Circle; 513 dp.MarkerBorderWidth = 1; 514 dp.MarkerSize = 5; 515 } 516 row.Points.Add(dp); 517 } 518 if (boundShadingCheckBox.Checked) { 519 if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == iter.Current.Key) 520 rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets); 521 else rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] { ecdf / totalTargets, (ecdf + missedecdf) / totalTargets })); 522 } 523 moreMisses = iter.MoveNext(); 524 } 525 526 if (maxLength > 0 && (row.Points.Count == 0 || row.Points.Last().XValue < maxLength)) { 527 var dp = new DataPoint(maxLength, ecdf / movingTargets) { 528 Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount]) 529 }; 530 if (showMarkers) { 531 dp.MarkerStyle = MarkerStyle.Circle; 532 dp.MarkerBorderWidth = 1; 533 dp.MarkerSize = 5; 534 } 535 row.Points.Add(dp); 536 } 537 538 ConfigureSeries(row); 539 targetChart.Series.Add(rowShade); 540 targetChart.Series.Add(row); 541 } 542 colorCount = (colorCount + 1) % colors.Length; 543 if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length; 544 } 545 546 if (targets.Length == 1) { 547 if (targetsAreRelative) 548 targetChart.ChartAreas[0].AxisY.Title = "Probability to be " + (targets[0] * 100) + "% worse than best"; 549 else targetChart.ChartAreas[0].AxisY.Title = "Probability to reach at least a fitness of " + targets[0]; 550 } else targetChart.ChartAreas[0].AxisY.Title = "Proportion of reached targets"; 551 targetChart.ChartAreas[0].AxisX.Title = string.Join(" / ", xAxisTitles); 552 targetChart.ChartAreas[0].AxisX.IsLogarithmic = CanDisplayLogarithmic(); 553 targetChart.ChartAreas[0].CursorY.Interval = 0.05; 554 UpdateErtTables(groupedRuns); 555 } 556 557 private IEnumerable<double> GetAbsoluteTargets(bool maximization, double bestKnown) { 549 } 550 551 private IEnumerable<double> GetAbsoluteTargets(ProblemInstance pInstance) { 558 552 if (!targetsAreRelative) return targets; 553 var maximization = pInstance.IsMaximization(); 554 var bestKnown = pInstance.BestKnownQuality; 555 if (double.IsNaN(bestKnown)) throw new ArgumentException("Problem instance does not have a defined best - known quality."); 559 556 IEnumerable<double> tmp = null; 560 557 if (bestKnown > 0) { … … 569 566 } 570 567 571 private double[] GetAbsoluteTargetsWorstToBest(bool maximization, double bestKnown) { 572 var absTargets = GetAbsoluteTargets(maximization, bestKnown); 573 return maximization ? absTargets.OrderBy(x => x).ToArray() : absTargets.OrderByDescending(x => x).ToArray(); 568 private double[] GetAbsoluteTargetsWorstToBest(ProblemInstance pInstance) { 569 if (double.IsNaN(pInstance.BestKnownQuality)) throw new ArgumentException("Problem instance does not have a defined best-known quality."); 570 var absTargets = GetAbsoluteTargets(pInstance); 571 return (pInstance.IsMaximization() 572 ? absTargets.OrderBy(x => x) : absTargets.OrderByDescending(x => x)).ToArray(); 574 573 } 575 574 576 575 private void GenerateDefaultTargets() { 577 targets = new[] { 0.1, 0.0 5, 0.02, 0.01, 0 };576 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 }; 578 577 suppressTargetsEvents = true; 579 578 targetsTextBox.Text = string.Join("% ; ", targets.Select(x => x * 100)) + "%"; … … 581 580 } 582 581 583 private void CalculateHitsForEachTarget(Dictionary<string, SortedList<double, int>> hits, 584 Dictionary<string, SortedList<double, int>> misses, 585 IndexedDataRow<double> row, ProblemInstance problem, 586 string group, double bestTarget, double maxEffort) { 587 var maximization = problem.IsMaximization(); 588 foreach (var t in targets.Zip(GetAbsoluteTargets(maximization, bestTarget), (rt, at) => Tuple.Create(at, rt))) { 589 var l = t.Item1; 590 var key = group + "_" + (targetsAreRelative ? (t.Item2 * 100) + "%_" + l : l.ToString()); 591 if (!hits.ContainsKey(key)) { 592 hits.Add(key, new SortedList<double, int>()); 593 misses.Add(key, new SortedList<double, int>()); 594 } 595 var hit = false; 596 foreach (var v in row.Values) { 597 if (v.Item1 > maxEffort) break; 598 if (maximization && v.Item2 >= l || !maximization && v.Item2 <= l) { 599 if (hits[key].ContainsKey(v.Item1)) 600 hits[key][v.Item1]++; 601 else hits[key][v.Item1] = 1; 602 hit = true; 603 break; 604 } 605 } 606 if (!hit) { 607 var max = Math.Min(row.Values.Last().Item1, maxEffort); 608 if (misses[key].ContainsKey(max)) 609 misses[key][max]++; 610 else misses[key][max] = 1; 611 } 612 } 613 } 614 615 private double CalculateHitsForAllTargets(Dictionary<string, SortedList<double, int>> hits, 616 Dictionary<string, SortedList<double, int>> misses, 617 IndexedDataRow<double> row, ProblemInstance problem, 618 string group, double bestTarget, double maxEffort) { 619 var values = row.Values; 620 if (!hits.ContainsKey(group)) { 621 hits.Add(group, new SortedList<double, int>()); 622 misses.Add(group, new SortedList<double, int>()); 623 } 624 625 var i = 0; 626 var j = 0; 627 var max = problem.IsMaximization(); 628 var absTargets = GetAbsoluteTargetsWorstToBest(max, bestTarget); 629 while (i < absTargets.Length && j < values.Count) { 630 var target = absTargets[i]; 631 var current = values[j]; 632 if (current.Item1 > maxEffort) break; 633 if (problem.IsMaximization() && current.Item2 >= target 634 || !problem.IsMaximization() && current.Item2 <= target) { 635 if (hits[group].ContainsKey(current.Item1)) hits[group][current.Item1]++; 636 else hits[group][current.Item1] = 1; 637 i++; 638 } else { 639 j++; 640 } 641 } 642 if (j == values.Count) j--; 643 var effort = Math.Min(values[j].Item1, maxEffort); 644 if (i < absTargets.Length) { 645 if (misses[group].ContainsKey(effort)) 646 misses[group][effort] += absTargets.Length - i; 647 else misses[group][effort] = absTargets.Length - i; 648 } 649 return effort; 582 private Tuple<bool, double> GetEffortToHitTarget( 583 IEnumerable<Tuple<double, double>> convergenceGraph, 584 double absTarget, bool maximization) { 585 var hit = false; 586 var effort = double.NaN; 587 foreach (var dent in convergenceGraph) { 588 effort = dent.Item1; 589 hit = maximization && dent.Item2 >= absTarget || !maximization && dent.Item2 <= absTarget; 590 if (hit) break; 591 } 592 if (double.IsNaN(effort)) throw new ArgumentException("Convergence graph is empty.", "convergenceGraph"); 593 return Tuple.Create(hit, effort); 650 594 } 651 595 … … 664 608 var max = problem.IsMaximization(); 665 609 matrix[rowCount, 0] = problem.ToString(); 666 var absTargets = GetAbsoluteTargetsWorstToBest( max, problem.BestKnownQuality);610 var absTargets = GetAbsoluteTargetsWorstToBest(problem); 667 611 for (var i = 0; i < absTargets.Length; i++) { 668 612 matrix[rowCount, i + 1] = absTargets[i].ToString(CultureInfo.CurrentCulture.NumberFormat); … … 756 700 var min = runs.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Min()).Min(); 757 701 var max = runs.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Max()).Max(); 758 759 var maxMagnitude = (int)Math.Ceiling(Math.Log10(max)); 760 var minMagnitude = (int)Math.Floor(Math.Log10(min)); 761 if (maxMagnitude - minMagnitude >= 3) { 762 budgets = new double[maxMagnitude - minMagnitude]; 763 for (var i = minMagnitude; i < maxMagnitude; i++) { 764 budgets[i - minMagnitude] = Math.Pow(10, i); 765 } 766 } else { 767 var range = max - min; 768 budgets = Enumerable.Range(0, 6).Select(x => min + (x / 5.0) * range).ToArray(); 769 } 702 var points = 20; 703 budgets = Enumerable.Range(1, points).Select(x => min + (x / (double)points) * (max - min)).ToArray(); 770 704 suppressBudgetsEvents = true; 771 705 budgetsTextBox.Text = string.Join(" ; ", budgets); … … 784 718 if (prev == null && v.Item1 != b) break; 785 719 var tgt = ((prev == null || v.Item1 == b) ? v.Item2 : prev.Item2); 786 var relTgt = CalculateRelativeDifference(max, problem.BestKnownQuality, tgt) ;720 var relTgt = CalculateRelativeDifference(max, problem.BestKnownQuality, tgt) + 1; 787 721 if (hits[key].ContainsKey(relTgt)) 788 722 hits[key][relTgt] += 1.0 / (groupCount * problemCount); … … 809 743 if (prev != null || current.Item1 == budgets[i]) { 810 744 var tgt = (prev == null || current.Item1 == budgets[i]) ? current.Item2 : prev.Item2; 811 var relTgt = CalculateRelativeDifference(max, problem.BestKnownQuality, tgt) ;745 var relTgt = CalculateRelativeDifference(max, problem.BestKnownQuality, tgt) + 1; 812 746 if (!hits[groupName].ContainsKey(relTgt)) hits[groupName][relTgt] = 0; 813 747 hits[groupName][relTgt] += 1.0 / (groupCount * problemCount * budgets.Length); … … 820 754 } 821 755 var lastTgt = values.Last().Item2; 822 var lastRelTgt = CalculateRelativeDifference(max, problem.BestKnownQuality, lastTgt) ;756 var lastRelTgt = CalculateRelativeDifference(max, problem.BestKnownQuality, lastTgt) + 1; 823 757 if (i < budgets.Length && !hits[groupName].ContainsKey(lastRelTgt)) hits[groupName][lastRelTgt] = 0; 824 758 while (i < budgets.Length) { … … 906 840 if (!double.IsNaN(pd.BestKnownQuality)) { 907 841 var max = pd.IsMaximization(); 908 if (targetsAreRelative) targets = GetAbsoluteTargets( max, pd.BestKnownQuality).ToArray();842 if (targetsAreRelative) targets = GetAbsoluteTargets(pd).ToArray(); 909 843 else { 910 844 // Rounding to 5 digits since it's certainly appropriate for this application … … 960 894 var table = (string)dataTableComboBox.SelectedItem; 961 895 if (string.IsNullOrEmpty(table)) return; 962 963 var targetsPerProblem = problems.ToDictionary(x => x, x => x.BestKnownQuality); 964 896 965 897 foreach (var run in Content) { 966 898 if (!run.Results.ContainsKey(table)) continue; … … 971 903 var pd = new ProblemInstance(run); 972 904 var max = pd.IsMaximization(); 973 var absTargets = GetAbsoluteTargetsWorstToBest( max, targetsPerProblem[pd]);905 var absTargets = GetAbsoluteTargetsWorstToBest(problems.Single(x => x.Equals(pd))); 974 906 while (i < absTargets.Length && j < values.Count) { 975 907 var target = absTargets[i];
Note: See TracChangeset
for help on using the changeset viewer.