Changeset 15701
- Timestamp:
- 01/31/18 18:15:42 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/1614_GeneralizedQAP/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs
r15699 r15701 87 87 private readonly BindingList<ProblemInstance> problems; 88 88 89 private bool suppressUpdates; 89 private bool updateInProgress; 90 private bool suppressContentEvents; 90 91 private readonly IndexedDataTable<double> byCostDataTable; 91 92 public IndexedDataTable<double> ByCostDataTable { … … 97 98 invisibleTargetSeries = new List<Series>(); 98 99 99 targetChart.CustomizeAllChartAreas(); 100 targetChart.ChartAreas[0].CursorX.Interval = 1; 101 targetChart.SuppressExceptions = true; 102 byCostDataTable = new IndexedDataTable<double>("ECDF by Cost", "A data table containing the ECDF of function values (relative to best-known).") { 103 VisualProperties = { 104 YAxisTitle = "Proportion of runs", 105 YAxisMinimumFixedValue = 0, 106 YAxisMinimumAuto = false, 107 YAxisMaximumFixedValue = 1, 108 YAxisMaximumAuto = false 109 } 110 }; 111 byCostViewHost.Content = byCostDataTable; 112 suppressUpdates = true; 113 relativeOrAbsoluteComboBox.SelectedItem = targetsAreRelative ? "relative" : "absolute"; 114 problems = new BindingList<ProblemInstance>(); 115 problemComboBox.DataSource = new BindingSource() { DataSource = problems }; 116 problemComboBox.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged; 117 suppressUpdates = false; 100 try { 101 updateInProgress = true; 102 targetChart.CustomizeAllChartAreas(); 103 targetChart.ChartAreas[0].CursorX.Interval = 1; 104 targetChart.SuppressExceptions = true; 105 byCostDataTable = new IndexedDataTable<double>("ECDF by Cost", "A data table containing the ECDF of function values (relative to best-known).") { 106 VisualProperties = { 107 YAxisTitle = "Proportion of runs", 108 YAxisMinimumFixedValue = 0, 109 YAxisMinimumAuto = false, 110 YAxisMaximumFixedValue = 1, 111 YAxisMaximumAuto = false 112 } 113 }; 114 byCostViewHost.Content = byCostDataTable; 115 116 relativeOrAbsoluteComboBox.SelectedItem = targetsAreRelative ? "relative" : "absolute"; 117 problems = new BindingList<ProblemInstance>(); 118 problemComboBox.DataSource = new BindingSource() { DataSource = problems }; 119 problemComboBox.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged; 120 } finally { updateInProgress = false; } 118 121 } 119 122 … … 137 140 138 141 private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) { 139 if (suppressUpdates) return; 142 foreach (var run in e.Items) RegisterRunEvents(run); 143 if (suppressContentEvents) return; 140 144 if (InvokeRequired) { 141 145 Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e); 142 146 return; 143 147 } 144 UpdateGroupAndProblemComboBox(); 145 UpdateDataTableComboBox(); 146 GroupRuns(); 147 foreach (var run in e.Items) 148 RegisterRunEvents(run); 148 try { 149 updateInProgress = true; 150 UpdateGroupAndProblemComboBox(); 151 UpdateDataTableComboBox(); 152 GroupRuns(); 153 } finally { updateInProgress = false; } 149 154 } 150 155 private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) { 151 if (suppressUpdates) return; 156 foreach (var run in e.Items) DeregisterRunEvents(run); 157 if (suppressContentEvents) return; 152 158 if (InvokeRequired) { 153 159 Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved), sender, e); 154 160 return; 155 161 } 156 UpdateGroupAndProblemComboBox(); 157 UpdateDataTableComboBox(); 158 GroupRuns(); 159 foreach (var run in e.Items) 160 DeregisterRunEvents(run); 162 try { 163 updateInProgress = true; 164 UpdateGroupAndProblemComboBox(); 165 UpdateDataTableComboBox(); 166 GroupRuns(); 167 } finally { updateInProgress = false; } 161 168 } 162 169 private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) { 163 if (suppressUpdates) return; 170 foreach (var run in e.OldItems) DeregisterRunEvents(run); 171 foreach (var run in e.Items) RegisterRunEvents(run); 172 if (suppressContentEvents) return; 164 173 if (InvokeRequired) { 165 174 Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset), sender, e); 166 175 return; 167 176 } 168 UpdateGroupAndProblemComboBox(); 169 UpdateDataTableComboBox(); 170 GroupRuns(); 171 foreach (var run in e.OldItems) 172 DeregisterRunEvents(run); 177 try { 178 updateInProgress = true; 179 UpdateGroupAndProblemComboBox(); 180 UpdateDataTableComboBox(); 181 GroupRuns(); 182 } finally { updateInProgress = false; } 173 183 } 174 184 private void Content_AlgorithmNameChanged(object sender, EventArgs e) { … … 182 192 return; 183 193 } 184 suppressUpdates = Content.UpdateOfRunsInProgress; 185 if (!suppressUpdates) { 186 UpdateDataTableComboBox(); 187 UpdateGroupAndProblemComboBox(); 188 UpdateRuns(); 194 suppressContentEvents = Content.UpdateOfRunsInProgress; 195 if (!suppressContentEvents) { 196 try { 197 updateInProgress = true; 198 UpdateGroupAndProblemComboBox(); 199 UpdateDataTableComboBox(); 200 GroupRuns(); 201 } finally { updateInProgress = false; } 189 202 } 190 203 } … … 197 210 } 198 211 private void run_PropertyChanged(object sender, PropertyChangedEventArgs e) { 199 if (suppress Updates) return;212 if (suppressContentEvents) return; 200 213 if (InvokeRequired) { 201 214 Invoke((Action<object, PropertyChangedEventArgs>)run_PropertyChanged, sender, e); 202 215 } else { 203 if (e.PropertyName == "Visible") 204 UpdateRuns(); 216 if (e.PropertyName == "Visible") { 217 try { 218 updateInProgress = true; 219 UpdateRuns(); 220 } finally { updateInProgress = false; } 221 } 205 222 } 206 223 } … … 219 236 UpdateCaption(); 220 237 if (Content != null) { 221 UpdateGroupAndProblemComboBox(); 222 UpdateDataTableComboBox(); 223 GroupRuns(); 238 try { 239 updateInProgress = true; 240 UpdateGroupAndProblemComboBox(); 241 UpdateDataTableComboBox(); 242 UpdateRuns(); 243 } finally { updateInProgress = false; } 224 244 } 225 245 } … … 239 259 } 240 260 241 var table = (string)dataTableComboBox.SelectedItem;242 var problemDict = CalculateBestTargetPerProblemInstance(table);243 244 var problemTypesDifferent = problemDict.Keys.Select(x => x.ProblemType).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1;245 var problemNamesDifferent = problemDict.Keys.Select(x => x.ProblemName).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1;246 var evaluatorDifferent = problemDict.Keys.Select(x => x.Evaluator).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1;247 var maximizationDifferent = problemDict.Keys.Select(x => x.Maximization).Distinct().Count() > 1;248 var allEqual = !problemTypesDifferent && !problemNamesDifferent && !evaluatorDifferent && !maximizationDifferent;249 250 261 var selectedProblemItem = (ProblemInstance)problemComboBox.SelectedItem; 251 problemComboBox.DataSource = null; 252 problemComboBox.Items.Clear(); 253 problems.Clear(); 254 problems.Add(ProblemInstance.MatchAll); 255 problemComboBox.DataSource = new BindingSource() { DataSource = problems }; 256 problemComboBox.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged; 257 if (problems[0].Equals(selectedProblemItem)) problemComboBox.SelectedItem = problems[0]; 258 foreach (var p in problemDict.ToList()) { 259 p.Key.BestKnownQuality = p.Value; 260 p.Key.DisplayProblemType = problemTypesDifferent; 261 p.Key.DisplayProblemName = problemNamesDifferent || allEqual; 262 p.Key.DisplayEvaluator = evaluatorDifferent; 263 p.Key.DisplayMaximization = maximizationDifferent; 264 problems.Add(p.Key); 265 if (p.Key.Equals(selectedProblemItem)) problemComboBox.SelectedItem = p.Key; 266 } 262 263 UpdateProblemInstances(); 264 265 foreach (var p in problems) { 266 if (p.Equals(selectedProblemItem)) 267 problemComboBox.SelectedItem = p; 268 } 269 270 if (selectedProblemItem == null && problems.Count > 1) problemComboBox.SelectedItem = problems[1]; 267 271 268 272 SetEnabledStateOfControls(); … … 284 288 dataTableComboBox.SelectedItem = dataTableComboBox.Items[0]; 285 289 } 290 291 UpdateProblemInstances(); 286 292 } 287 293 … … 326 332 groups.Add(new AlgorithmInstance(alg.Key, trials)); 327 333 } 334 } 335 336 private void UpdateProblemInstances() { 337 try { 338 problems.Clear(); 339 var table = (string)dataTableComboBox.SelectedItem; 340 if (string.IsNullOrEmpty(table)) return; 341 342 var problemDict = CalculateBestTargetPerProblemInstance(table); 343 344 var problemTypesDifferent = problemDict.Keys.Select(x => x.ProblemType).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1; 345 var problemNamesDifferent = problemDict.Keys.Select(x => x.ProblemName).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1; 346 var evaluatorDifferent = problemDict.Keys.Select(x => x.Evaluator).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1; 347 var maximizationDifferent = problemDict.Keys.Select(x => x.Maximization).Distinct().Count() > 1; 348 var allEqual = !problemTypesDifferent && !problemNamesDifferent && !evaluatorDifferent && !maximizationDifferent; 349 350 problems.Add(ProblemInstance.MatchAll); 351 foreach (var p in problemDict.ToList()) { 352 p.Key.BestKnownQuality = p.Value; 353 p.Key.DisplayProblemType = problemTypesDifferent; 354 p.Key.DisplayProblemName = problemNamesDifferent || allEqual; 355 p.Key.DisplayEvaluator = evaluatorDifferent; 356 p.Key.DisplayMaximization = maximizationDifferent; 357 problems.Add(p.Key); 358 } 359 } finally { ((BindingSource)problemComboBox.DataSource).ResetBindings(false); } 328 360 } 329 361 … … 570 602 private IEnumerable<double> GetAbsoluteTargets(ProblemInstance pInstance) { 571 603 if (!targetsAreRelative) return targets; 604 572 605 var maximization = pInstance.IsMaximization(); 573 606 var bestKnown = pInstance.BestKnownQuality; … … 586 619 587 620 private double[] GetAbsoluteTargetsWorstToBest(ProblemInstance pInstance) { 588 if ( double.IsNaN(pInstance.BestKnownQuality)) throw new ArgumentException("Problem instance does not have a defined best-known quality.");621 if (targetsAreRelative && double.IsNaN(pInstance.BestKnownQuality)) throw new ArgumentException("Problem instance does not have a defined best-known quality."); 589 622 var absTargets = GetAbsoluteTargets(pInstance); 590 623 return (pInstance.IsMaximization() … … 719 752 720 753 private void GenerateDefaultBudgets(string table) { 721 var runs = Content.Where(x => x.Results.ContainsKey(table) && x.Results[table] is IndexedDataTable<double> 722 && ((IndexedDataTable<double>)x.Results[table]).Rows.Count > 0 723 && ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values 724 .Any(y => !double.IsNaN(y.Item2))) 725 .Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First()) 754 var runs = Content.Where(x => x.Results.ContainsKey(table) && x.Results[table] is IndexedDataTable<double>) 755 .Select(x => (IndexedDataTable<double>)x.Results[table]) 756 .Where(x => x.Rows.Count > 0) 757 .Select(x => x.Rows.First()) 726 758 .ToList(); 727 759 if (runs.Count == 0) { … … 733 765 } 734 766 735 var min = runs.Select(x => x.Values. Where(y => !double.IsNaN(y.Item2)).Select(y => y.Item1).Min()).Min();736 var max = runs.Select(x => x.Values. Where(y => !double.IsNaN(y.Item2)).Select(y => y.Item1).Max()).Max();767 var min = runs.Select(x => x.Values.Select(y => y.Item1).Min()).Min(); 768 var max = runs.Select(x => x.Values.Select(y => y.Item1).Max()).Max(); 737 769 var points = 3; 738 770 budgets = Enumerable.Range(1, points).Select(x => min + (x / (double)points) * (max - min)).ToArray(); … … 770 802 if (InvokeRequired) Invoke((Action)SynchronizeTargetTextBox); 771 803 else { 772 suppressTargetsEvents = true; 773 try { 774 if (targetsAreRelative) 775 targetsTextBox.Text = string.Join("% ; ", targets.Select(x => x * 100)) + "%"; 776 else targetsTextBox.Text = string.Join(" ; ", targets); 777 } finally { suppressTargetsEvents = false; } 804 if (targetsAreRelative) 805 targetsTextBox.Text = string.Join("% ; ", targets.Select(x => x * 100)) + "%"; 806 else targetsTextBox.Text = string.Join(" ; ", targets); 778 807 } 779 808 } 780 809 781 810 private void groupComboBox_SelectedIndexChanged(object sender, EventArgs e) { 782 UpdateRuns(); 783 SetEnabledStateOfControls(); 811 if (updateInProgress) return; 812 try { 813 updateInProgress = true; 814 UpdateRuns(); 815 SetEnabledStateOfControls(); 816 } finally { updateInProgress = false; } 784 817 } 785 818 private void problemComboBox_SelectedIndexChanged(object sender, EventArgs e) { 786 UpdateRuns(); 787 SetEnabledStateOfControls(); 819 if (updateInProgress) return; 820 try { 821 updateInProgress = true; 822 UpdateRuns(); 823 SetEnabledStateOfControls(); 824 } finally { updateInProgress = false; } 788 825 } 789 826 private void dataTableComboBox_SelectedIndexChanged(object sender, EventArgs e) { 790 if (dataTableComboBox.SelectedIndex >= 0) 791 GenerateDefaultBudgets((string)dataTableComboBox.SelectedItem); 792 UpdateBestKnownQualities(); 793 UpdateRuns(); 794 SetEnabledStateOfControls(); 827 if (updateInProgress) return; 828 try { 829 updateInProgress = true; 830 if (dataTableComboBox.SelectedIndex >= 0) 831 GenerateDefaultBudgets((string)dataTableComboBox.SelectedItem); 832 UpdateBestKnownQualities(); 833 UpdateRuns(); 834 SetEnabledStateOfControls(); 835 } finally { updateInProgress = false; } 795 836 } 796 837 … … 805 846 806 847 #region Event handlers for target analysis 807 private bool suppressTargetsEvents;808 848 private void targetsTextBox_Validating(object sender, CancelEventArgs e) { 809 if (suppressTargetsEvents) return; 810 var targetStrings = targetsTextBox.Text.Split(new[] { '%', ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries); 811 var targetList = new List<decimal>(); 812 foreach (var ts in targetStrings) { 813 decimal t; 814 if (!decimal.TryParse(ts, out t)) { 815 errorProvider.SetError(targetsTextBox, "Not all targets can be parsed: " + ts); 849 if (updateInProgress) return; 850 try { 851 updateInProgress = true; 852 var targetStrings = targetsTextBox.Text.Split(new[] { '%', ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries); 853 var targetList = new List<decimal>(); 854 foreach (var ts in targetStrings) { 855 decimal t; 856 if (!decimal.TryParse(ts, out t)) { 857 errorProvider.SetError(targetsTextBox, "Not all targets can be parsed: " + ts); 858 e.Cancel = true; 859 return; 860 } 861 if (targetsAreRelative) 862 targetList.Add(t / 100); 863 else targetList.Add(t); 864 } 865 if (targetList.Count == 0) { 866 errorProvider.SetError(targetsTextBox, "Give at least one target value!"); 816 867 e.Cancel = true; 817 868 return; 818 869 } 819 if (targetsAreRelative) 820 targetList.Add(t / 100); 821 else targetList.Add(t); 822 } 823 if (targetList.Count == 0) { 824 errorProvider.SetError(targetsTextBox, "Give at least one target value!"); 825 e.Cancel = true; 826 return; 827 } 828 e.Cancel = false; 829 errorProvider.SetError(targetsTextBox, null); 830 targets = targetsAreRelative ? targetList.Select(x => (double)x).OrderByDescending(x => x).ToArray() : targetList.Select(x => (double)x).ToArray(); 831 832 SynchronizeTargetTextBox(); 833 UpdateResultsByTarget(); 834 SetEnabledStateOfControls(); 870 e.Cancel = false; 871 errorProvider.SetError(targetsTextBox, null); 872 targets = targetsAreRelative ? targetList.Select(x => (double)x).OrderByDescending(x => x).ToArray() : targetList.Select(x => (double)x).ToArray(); 873 874 SynchronizeTargetTextBox(); 875 UpdateResultsByTarget(); 876 SetEnabledStateOfControls(); 877 878 } finally { updateInProgress = false; } 835 879 } 836 880 837 881 private void aggregateTargetsCheckBox_CheckedChanged(object sender, EventArgs e) { 838 SuspendRepaint();882 if (updateInProgress) return; 839 883 try { 840 UpdateResultsByTarget(); 841 } finally { ResumeRepaint(true); } 842 } 843 844 private void relativeOrAbsoluteComboBox_SelectedIndexChanged(object sender, EventArgs e) { 845 if (suppressUpdates) return; 846 var pd = (ProblemInstance)problemComboBox.SelectedItem; 847 if (!double.IsNaN(pd.BestKnownQuality)) { 848 var max = pd.IsMaximization(); 849 if (targetsAreRelative) targets = GetAbsoluteTargets(pd).ToArray(); 850 else { 851 // Rounding to 5 digits since it's certainly appropriate for this application 852 if (pd.BestKnownQuality > 0) { 853 targets = targets.Select(x => Math.Round(max ? 1.0 - (x / pd.BestKnownQuality) : (x / pd.BestKnownQuality) - 1.0, 5)).ToArray(); 854 } else if (pd.BestKnownQuality < 0) { 855 targets = targets.Select(x => Math.Round(!max ? 1.0 - (x / pd.BestKnownQuality) : (x / pd.BestKnownQuality) - 1.0, 5)).ToArray(); 856 } 857 } 858 } 859 targetsAreRelative = (string)relativeOrAbsoluteComboBox.SelectedItem == "relative"; 860 SynchronizeTargetTextBox(); 861 862 try { 884 updateInProgress = true; 863 885 SuspendRepaint(); 864 886 UpdateResultsByTarget(); 865 } finally { ResumeRepaint(true); } 887 } finally { 888 updateInProgress = false; 889 ResumeRepaint(true); 890 } 891 } 892 893 private void relativeOrAbsoluteComboBox_SelectedIndexChanged(object sender, EventArgs e) { 894 if (updateInProgress) return; 895 try { 896 updateInProgress = true; 897 var pd = (ProblemInstance)problemComboBox.SelectedItem; 898 if (!double.IsNaN(pd.BestKnownQuality)) { 899 var max = pd.IsMaximization(); 900 if (targetsAreRelative) targets = GetAbsoluteTargets(pd).ToArray(); 901 else { 902 // Rounding to 5 digits since it's certainly appropriate for this application 903 if (pd.BestKnownQuality > 0) { 904 targets = targets.Select(x => Math.Round(max ? 1.0 - (x / pd.BestKnownQuality) : (x / pd.BestKnownQuality) - 1.0, 5)).ToArray(); 905 } else if (pd.BestKnownQuality < 0) { 906 targets = targets.Select(x => Math.Round(!max ? 1.0 - (x / pd.BestKnownQuality) : (x / pd.BestKnownQuality) - 1.0, 5)).ToArray(); 907 } 908 } 909 } 910 targetsAreRelative = (string)relativeOrAbsoluteComboBox.SelectedItem == "relative"; 911 SynchronizeTargetTextBox(); 912 913 SuspendRepaint(); 914 UpdateResultsByTarget(); 915 } finally { 916 updateInProgress = false; 917 ResumeRepaint(true); 918 } 866 919 } 867 920 … … 883 936 : dialog.Values.Select(x => (double)x).ToArray(); 884 937 885 SynchronizeTargetTextBox(); 886 UpdateResultsByTarget(); 887 SetEnabledStateOfControls(); 938 try { 939 updateInProgress = true; 940 SynchronizeTargetTextBox(); 941 UpdateResultsByTarget(); 942 SetEnabledStateOfControls(); 943 } finally { updateInProgress = false; } 888 944 } 889 945 } … … 896 952 897 953 foreach (var run in Content) { 898 if (!run.Results.ContainsKey(table) ) continue;954 if (!run.Results.ContainsKey(table) || !(run.Results[table] is IndexedDataTable<double>)) continue; 899 955 var resultsTable = (IndexedDataTable<double>)run.Results[table]; 900 956 var values = resultsTable.Rows.First().Values; 901 957 var pd = new ProblemInstance(run); 902 958 pd = problems.Single(x => x.Equals(pd)); 903 if ( double.IsNaN(pd.BestKnownQuality)) continue;959 if (targetsAreRelative && double.IsNaN(pd.BestKnownQuality)) continue; 904 960 905 961 var max = pd.IsMaximization(); … … 923 979 924 980 private void markerCheckBox_CheckedChanged(object sender, EventArgs e) { 925 SuspendRepaint();926 981 try { 982 updateInProgress = true; 983 SuspendRepaint(); 927 984 UpdateResultsByTarget(); 928 } finally { ResumeRepaint(true); } 985 } finally { 986 updateInProgress = false; 987 ResumeRepaint(true); 988 } 929 989 } 930 990 931 991 private void showLabelsCheckBox_CheckedChanged(object sender, EventArgs e) { 932 992 showLabelsInTargetChart = showLabelsCheckBox.Checked; 933 SuspendRepaint();934 993 try { 994 updateInProgress = true; 995 SuspendRepaint(); 935 996 UpdateResultsByTarget(); 936 } finally { ResumeRepaint(true); } 997 } finally { 998 updateInProgress = false; 999 ResumeRepaint(true); 1000 } 937 1001 } 938 1002 #endregion … … 1186 1250 } 1187 1251 1252 #region Helper classes 1188 1253 private class AlgorithmInstance : INotifyPropertyChanged { 1189 1254 private string name; … … 1526 1591 } 1527 1592 } 1593 #endregion 1528 1594 } 1529 1595 }
Note: See TracChangeset
for help on using the changeset viewer.