Changeset 14333 for branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/MultiObjectiveGoalSeekingProblem.cs
- Timestamp:
- 10/14/16 15:51:10 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/MultiObjectiveGoalSeekingProblem.cs
r14325 r14333 23 23 using System.Collections.Generic; 24 24 using System.Linq; 25 using System.Windows.Forms;26 25 using HeuristicLab.Collections; 27 26 using HeuristicLab.Common; … … 39 38 [StorableClass] 40 39 public sealed class MultiObjectiveGoalSeekingProblem : MultiObjectiveBasicProblem<RealVectorEncoding>, IGoalSeekingProblem { 40 #region parameter names 41 41 private const string ModifiableDatasetParameterName = "Dataset"; 42 private const string ProblemDataParameterName = "ProblemData"; 43 private const string ControllableParametersParameterName = "ControllableParameters"; 44 private const string ControllableParameterBoundsParameterName = "ControllableParameterBounds"; 45 private const string TargetGoalsParameterName = "TargetGoals"; 46 private const string TargetsParameterName = "Targets"; 47 private const string ModelCollectionParameterName = "ModelCollection"; 48 private const string RowParameterName = "Row"; 49 // these parameters are used by the pareto folding analyzer 42 private const string InputsParameterName = "Inputs"; 43 private const string GoalsParameterName = "Goals"; 44 private const string ModelsParameterName = "Models"; 50 45 private const string QualitySumCutoffParameterName = "QualitySumCutoff"; 46 #endregion 51 47 52 48 #region parameters 49 public IValueParameter<CheckedItemList<InputParameter>> InputsParameter { 50 get { return (IValueParameter<CheckedItemList<InputParameter>>)Parameters[InputsParameterName]; } 51 } 52 public IValueParameter<CheckedItemList<GoalParameter>> GoalsParameter { 53 get { return (IValueParameter<CheckedItemList<GoalParameter>>)Parameters[GoalsParameterName]; } 54 } 55 public IFixedValueParameter<ItemCollection<IRegressionModel>> ModelsParameter { 56 get { return (IFixedValueParameter<ItemCollection<IRegressionModel>>)Parameters[ModelsParameterName]; } 57 } 53 58 public IFixedValueParameter<DoubleValue> QualitySumCutoffParameter { 54 59 get { return (IFixedValueParameter<DoubleValue>)Parameters[QualitySumCutoffParameterName]; } 55 60 } 56 public IValueParameter<IRegressionProblemData> ProblemDataParameter { 57 get { return (IValueParameter<IRegressionProblemData>)Parameters[ProblemDataParameterName]; } 58 } 59 public IValueParameter<CheckedItemList<StringValue>> ControllableParametersParameter { 60 get { return (IValueParameter<CheckedItemList<StringValue>>)Parameters[ControllableParametersParameterName]; } 61 } 62 public IValueParameter<DoubleMatrix> ControllableParameterBoundsParameter { 63 get { return (IValueParameter<DoubleMatrix>)Parameters[ControllableParameterBoundsParameterName]; } 64 } 65 public IFixedValueParameter<ItemCollection<IRegressionModel>> ModelCollectionParameter { 66 get { return (IFixedValueParameter<ItemCollection<IRegressionModel>>)Parameters[ModelCollectionParameterName]; } 67 } 68 public IValueParameter<CheckedItemList<StringValue>> TargetsParameter { 69 get { return (IValueParameter<CheckedItemList<StringValue>>)Parameters[TargetsParameterName]; } 70 } 71 public IValueParameter<DoubleMatrix> TargetGoalsParameter { 72 get { return (IValueParameter<DoubleMatrix>)Parameters[TargetGoalsParameterName]; } 73 } 74 public IFixedValueParameter<IntValue> RowParameter { 75 get { return (IFixedValueParameter<IntValue>)Parameters[RowParameterName]; } 76 } 77 #endregion 78 79 #region parameter properties 80 private IItemCollection<IRegressionModel> ModelCollection { 81 get { return ModelCollectionParameter.Value; } 82 } 83 public DoubleMatrix TargetGoals { 84 get { return TargetGoalsParameter.Value; } 85 set { TargetGoalsParameter.Value = value; } 86 } 87 public double QualitySumCutoff { 88 get { return QualitySumCutoffParameter.Value.Value; } 89 set { QualitySumCutoffParameter.Value.Value = value; } 90 } 91 #endregion 92 93 #region IProcessParameterOptimizationProblem properties 94 [Storable] 95 private IRegressionProblemData problemData; 96 public IRegressionProblemData ProblemData { 97 get { return problemData; } 98 set { 99 if (value == null || value == problemData) return; 100 var variables = value.Dataset.DoubleVariables.ToList(); 101 if (Models.Any()) { 102 var targets = Models.Select(x => x.TargetVariable); 103 var hashset = new HashSet<string>(variables); 104 foreach (var target in targets) { 105 if (!hashset.Contains(target)) { 106 throw new ArgumentException(string.Format("Incompatible problem data. Target \"{0}\" is missing.", target)); 107 } 108 } 109 } 110 problemData = value; 111 dataset = new ModifiableDataset(variables, variables.Select(x => new List<double> { ProblemData.Dataset.GetDoubleValue(x, Row) })); 112 ProblemDataParameter.Value = ProblemData; 113 UpdateControllableParameters(); 114 UpdateTargetList(); 115 } 116 } 117 118 public int Row { 119 get { return RowParameter.Value.Value; } 120 set { RowParameter.Value.Value = value; } 121 } 122 61 #endregion 62 63 #region IGoalSeekingProblem implementation 123 64 public IEnumerable<IRegressionModel> Models { 124 get { return ModelCollectionParameter.Value; } 125 } 126 127 #region targets 128 public ICheckedItemList<StringValue> TargetList { 129 get { return TargetsParameter.Value; } 130 set { TargetsParameter.Value = (CheckedItemList<StringValue>)value; } 131 } 132 // convenience method 133 private IEnumerable<string> ActiveTargets { 134 get { return TargetList.CheckedItems.Select(x => x.Value.Value); } 135 } 136 #endregion 137 138 #region parameters 139 public ICheckedItemList<StringValue> ControllableParameters { 140 get { return ControllableParametersParameter.Value; } 141 set { ControllableParametersParameter.Value = (CheckedItemList<StringValue>)value; } 142 } 143 // convenience method 144 private IEnumerable<string> ActiveParameters { 145 get { return ControllableParameters.CheckedItems.Select(x => x.Value.Value); } 146 } 147 public DoubleMatrix ControllableParameterBounds { 148 get { return ControllableParameterBoundsParameter.Value; } 149 set { ControllableParameterBoundsParameter.Value = value; } 150 } 151 #endregion 152 #endregion 153 154 #region IProcessParameterOptimizationProblem methods 155 #region models 65 get { return ModelsParameter.Value; } 66 } 67 68 public IEnumerable<GoalParameter> Goals { 69 get { return GoalsParameter.Value; } 70 } 71 72 public IEnumerable<InputParameter> Inputs { 73 get { return InputsParameter.Value; } 74 } 75 76 public void AddModel(IRegressionModel model) { 77 var models = ModelsParameter.Value; 78 models.Add(model); 79 GoalSeekingUtil.RaiseEvent(this, ModelsChanged); 80 } 81 82 public void RemoveModel(IRegressionModel model) { 83 var models = ModelsParameter.Value; 84 models.Remove(model); 85 GoalSeekingUtil.RaiseEvent(this, ModelsChanged); 86 } 87 88 public void Configure(IRegressionProblemData problemData, int row) { 89 GoalSeekingUtil.Configure(Goals, Inputs, problemData, row); 90 } 91 156 92 public IEnumerable<double> GetEstimatedGoalValues(IEnumerable<double> parameterValues, bool round = false) { 157 93 var ds = (ModifiableDataset)dataset.Clone(); 158 foreach (var parameter in Active Parameters.Zip(parameterValues, (p, v) => new { Name = p, Value = v })) {94 foreach (var parameter in ActiveInputs.Zip(parameterValues, (p, v) => new { Name = p.Name, Value = v })) { 159 95 ds.SetVariableValue(parameter.Value, parameter.Name, 0); 160 96 } 161 97 var rows = new[] { 0 }; // actually just one row 162 163 98 var estimatedValues = 164 round ? Active Targets.Select(t => RoundToNearestStepMultiple(GetModels(t).Average(m => m.GetEstimatedValues(ds, rows).Single()), GetTargetStepSize(t)))165 : Active Targets.Select(t => GetModels(t).Average(m => m.GetEstimatedValues(ds, rows).Single()));99 round ? ActiveGoals.Select(t => RoundToNearestStepMultiple(GetModels(t.Name).Average(m => m.GetEstimatedValues(ds, rows).Single()), t.Step)) 100 : ActiveGoals.Select(t => GetModels(t.Name).Average(m => m.GetEstimatedValues(ds, rows).Single())); 166 101 return estimatedValues; 167 102 } 168 103 169 public void AddModel(IRegressionModel model) {170 var target = model.TargetVariable;171 CheckIfDatasetContainsTarget(target);172 ModelCollection.Add(model);173 OnModelsChanged(this, EventArgs.Empty);174 }175 176 // method which throws an exception that can be caught in the event handler if the check fails177 private void CheckIfDatasetContainsTarget(string target) {178 if (dataset.DoubleVariables.All(x => x != target))179 throw new ArgumentException(string.Format("Model target \"{0}\" does not exist in the dataset.", target));180 }181 182 public void RemoveModel(IRegressionModel model) {183 ModelCollection.Remove(model);184 OnModelsChanged(this, EventArgs.Empty);185 }186 187 104 public event EventHandler ModelsChanged; 188 private void OnModelsChanged(object sender, EventArgs args) {189 var changed = ModelsChanged;190 if (changed == null) return;191 changed(sender, args);192 }193 #endregion194 195 #region targets196 public bool GetTargetActive(string target) {197 var item = TargetList.SingleOrDefault(x => x.Value == target);198 if (item == null)199 throw new ArgumentException(string.Format("SetTargetActive: Invalid target name {0}", target));200 return TargetList.ItemChecked(item);201 }202 203 public void SetTargetActive(string target, bool active) {204 var item = TargetList.SingleOrDefault(x => x.Value == target);205 if (item == null)206 throw new ArgumentException(string.Format("SetTargetActive: Invalid target name {0}", target));207 TargetList.SetItemCheckedState(item, active);208 OnTargetsChanged(this, EventArgs.Empty);209 }210 211 public double GetTargetGoal(string target) {212 if (!IsValidTarget(target))213 throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));214 int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();215 return TargetGoals[i, 0];216 }217 218 public void SetTargetGoal(string target, double goal) {219 if (!IsValidTarget(target))220 throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));221 int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();222 TargetGoals[i, 0] = goal;223 OnTargetsChanged(this, EventArgs.Empty);224 }225 226 public double GetTargetWeight(string target) {227 if (!IsValidTarget(target))228 throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));229 int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();230 return TargetGoals[i, 1];231 }232 233 public void SetTargetWeight(string target, double weight) {234 if (!IsValidTarget(target))235 throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));236 int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();237 TargetGoals[i, 1] = weight;238 OnTargetsChanged(this, EventArgs.Empty);239 }240 241 public double GetTargetVariance(string target) {242 if (!IsValidTarget(target))243 throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));244 int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();245 return TargetGoals[i, 2];246 }247 248 public void SetTargetVariance(string target, double variance) {249 if (!IsValidTarget(target))250 throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));251 int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();252 TargetGoals[i, 2] = variance;253 OnTargetsChanged(this, EventArgs.Empty);254 }255 256 public double GetTargetStepSize(string target) {257 if (!IsValidTarget(target))258 throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));259 int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();260 return TargetGoals[i, 3];261 }262 263 public void SetTargetStepSize(string target, double stepSize) {264 if (!IsValidTarget(target))265 throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));266 int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();267 TargetGoals[i, 3] = stepSize;268 OnTargetsChanged(this, EventArgs.Empty);269 }270 271 105 public event EventHandler TargetsChanged; 272 private void OnTargetsChanged(object sender, EventArgs args) {273 var changed = TargetsChanged;274 if (changed == null) return;275 changed(sender, args);276 }277 #endregion // targets278 279 #region process parameters280 /// <summary>281 /// Returns the parameter bounds (min and max) and the step size for the specified parameter282 /// </summary>283 /// <param name="parameterName"></param>284 /// <returns>A double array containing the values (min, max, step) in this order</returns>285 public double[] GetParameterBounds(string parameterName) {286 var index = ControllableParameters.TakeWhile(x => x.Value != parameterName).Count();287 if (index < ControllableParameters.Count) {288 var min = ControllableParameterBounds[index, 0];289 var max = ControllableParameterBounds[index, 1];290 var step = ControllableParameterBounds[index, 2];291 return new[] { min, max, step };292 }293 throw new ArgumentException(string.Format("GetParameterBounds: Unknown parameter {0}.", parameterName));294 }295 296 public void SetParameterBounds(string parameterName, double min, double max, double step) {297 int i = ControllableParameterBounds.RowNames.TakeWhile(x => x != parameterName).Count();298 if (i < ControllableParameterBounds.Rows) {299 ControllableParameterBounds[i, 0] = min;300 ControllableParameterBounds[i, 1] = max;301 ControllableParameterBounds[i, 2] = step;302 UpdateEncoding();303 OnParametersChanged(this, EventArgs.Empty);304 } else {305 throw new ArgumentException(string.Format("SetParameterBounds: Invalid parameter name {0}", parameterName));306 }307 308 }309 310 public double GetParameterStepSize(string parameter) {311 int i = ControllableParameterBounds.RowNames.TakeWhile(x => x != parameter).Count();312 if (i < ControllableParameterBounds.Rows)313 return ControllableParameterBounds[i, 2];314 throw new ArgumentException(string.Format("GetParameterStepSize: Invalid parameter name {0}", parameter));315 }316 317 public void SetParameterStepSize(string parameter, double stepSize) {318 int i = ControllableParameterBounds.RowNames.TakeWhile(x => x != parameter).Count();319 if (i < ControllableParameterBounds.Rows) {320 ControllableParameterBounds[i, 2] = stepSize;321 OnParametersChanged(this, EventArgs.Empty);322 return;323 }324 throw new ArgumentException(string.Format("SetParameterStepSize: Invalid parameter name {0}", parameter));325 }326 327 public bool GetParameterActive(string parameter) {328 var item = ControllableParameters.SingleOrDefault(x => x.Value == parameter);329 if (item == null)330 throw new ArgumentException(string.Format("GetParameterActive: Invalid target name {0}", parameter));331 return ControllableParameters.ItemChecked(item);332 }333 334 public void SetParameterActive(string parameter, bool active) {335 var item = ControllableParameters.SingleOrDefault(x => x.Value == parameter);336 if (item == null)337 throw new ArgumentException(string.Format("SetParameterActive: Invalid target name {0}", parameter));338 ControllableParameters.SetItemCheckedState(item, active);339 OnParametersChanged(this, EventArgs.Empty);340 }341 342 public void SetControllableParameters(IEnumerable<string> parameterNames) {343 ControllableParameters = new CheckedItemList<StringValue>();344 foreach (var v in parameterNames) {345 ControllableParameters.Add(new StringValue(v), false);346 }347 ControllableParameters.CheckedItemsChanged += ControllableParameters_OnItemsChanged;348 ControllableParameterBounds = new DoubleMatrix(ControllableParameters.Count, 3);349 ControllableParameterBounds.RowNames = GetControllableParameters();350 ControllableParameterBounds.ColumnNames = new[] { "Min", "Max", "Step" };351 352 for (int i = 0; i < ControllableParameters.Count; ++i) {353 var itemName = ControllableParameters[i].Value;354 var values = ProblemData.Dataset.GetReadOnlyDoubleValues(itemName).Where(x => !double.IsNaN(x) && !double.IsInfinity(x)).ToList();355 if (!values.Any()) continue;356 357 // add a 20% margin to allow the optimization algorithm more freedom of exploration358 ControllableParameterBounds[i, 0] = 0.8 * values.Min(); // min359 ControllableParameterBounds[i, 1] = 1.2 * values.Max(); // max360 ControllableParameterBounds[i, 2] = 1e-6; // step361 }362 OnParametersChanged(this, EventArgs.Empty);363 }364 365 public IEnumerable<string> GetControllableParameters() {366 return ControllableParameters.Select(x => x.Value);367 }368 369 106 public event EventHandler ParametersChanged; 370 private void OnParametersChanged(object sender, EventArgs args) { 371 var changed = ParametersChanged; 372 if (changed == null) return; 373 changed(sender, args); 374 } 375 #endregion // process parameters 376 #endregion // IGoalSeekingProblem methods 377 378 #region data members 107 #endregion 108 109 private IEnumerable<GoalParameter> ActiveGoals { 110 get { return Goals.Where(x => x.Active); } 111 } 112 private IEnumerable<InputParameter> ActiveInputs { 113 get { return Inputs.Where(x => x.Active); } 114 } 115 private double QualitySumCutoff { 116 get { return QualitySumCutoffParameter.Value.Value; } 117 } 118 379 119 [Storable] 380 120 private ModifiableDataset dataset; // modifiable dataset … … 389 129 get { return (ValueParameter<BoolArray>)Parameters["Maximization"]; } 390 130 } 391 #endregion392 131 393 132 #region constructors … … 397 136 private MultiObjectiveGoalSeekingProblem(MultiObjectiveGoalSeekingProblem original, Cloner cloner) : base(original, cloner) { 398 137 this.dataset = cloner.Clone(original.dataset); 399 this.problemData = cloner.Clone(original.problemData);400 138 401 139 RegisterEvents(); … … 408 146 [StorableHook(HookType.AfterDeserialization)] 409 147 private void AfterDeserialization() { 410 if (Parameters.ContainsKey("Accuracy"))411 Parameters.Remove("Accuracy");412 413 if (!Parameters.ContainsKey(QualitySumCutoffParameterName)) {414 Parameters.Add(new FixedValueParameter<DoubleValue>(QualitySumCutoffParameterName, new DoubleValue(0.2)));415 QualitySumCutoffParameter.Hidden = true;416 }417 418 if (ProblemData == null && Parameters.ContainsKey(ProblemDataParameterName)) {419 ProblemData = ProblemDataParameter.Value;420 }421 422 if (!Parameters.ContainsKey(ModifiableDatasetParameterName)) {423 Parameters.Add(new ValueParameter<IDataset>(ModifiableDatasetParameterName, dataset) { Hidden = true });424 }425 426 // backwards-compatibility427 if (Parameters.ContainsKey("Models")) {428 var solutions = ((IFixedValueParameter<ItemCollection<IRegressionSolution>>)Parameters["Models"]).Value;429 var models = new ItemCollection<IRegressionModel>();430 foreach (var solution in solutions) {431 var model = solution.Model;432 model.TargetVariable = solution.ProblemData.TargetVariable;433 models.Add(model);434 }435 if (Parameters.ContainsKey(ModelCollectionParameterName))436 Parameters.Remove(ModelCollectionParameterName);437 Parameters.Add(new FixedValueParameter<ItemCollection<IRegressionModel>>(ModelCollectionParameterName, models));438 }439 440 148 RegisterEvents(); 441 149 } 442 150 443 151 public MultiObjectiveGoalSeekingProblem() { 444 Parameters.Add(new ValueParameter<IRegressionProblemData>(ProblemDataParameterName, new RegressionProblemData()));152 dataset = new ModifiableDataset(); 445 153 Parameters.Add(new ValueParameter<IDataset>(ModifiableDatasetParameterName, dataset) { Hidden = true }); 446 Parameters.Add(new ValueParameter<CheckedItemList<StringValue>>(ControllableParametersParameterName)); 447 Parameters.Add(new ValueParameter<CheckedItemList<StringValue>>(TargetsParameterName)); 448 Parameters.Add(new ValueParameter<DoubleMatrix>(ControllableParameterBoundsParameterName)); 449 Parameters.Add(new FixedValueParameter<ItemCollection<IRegressionModel>>(ModelCollectionParameterName, new ItemCollection<IRegressionModel>())); 450 Parameters.Add(new ValueParameter<DoubleMatrix>(TargetGoalsParameterName)); // model target weights 451 Parameters.Add(new FixedValueParameter<IntValue>(RowParameterName)); 154 Parameters.Add(new ValueParameter<CheckedItemList<InputParameter>>(InputsParameterName)); 155 Parameters.Add(new ValueParameter<CheckedItemList<GoalParameter>>(GoalsParameterName)); 156 Parameters.Add(new FixedValueParameter<ItemCollection<IRegressionModel>>(ModelsParameterName, new ItemCollection<IRegressionModel>())); 452 157 Parameters.Add(new FixedValueParameter<DoubleValue>(QualitySumCutoffParameterName, new DoubleValue(0.2))); 453 454 158 QualitySumCutoffParameter.Hidden = true; 455 456 // when the problem is created, the problem data parameter will be set to a default value457 // set the internal property to the same value458 ProblemData = ProblemDataParameter.Value;459 460 UpdateControllableParameters();461 UpdateTargetList();159 EncodingParameter.Hidden = true; 160 EvaluatorParameter.Hidden = true; 161 SolutionCreatorParameter.Hidden = true; 162 MaximizationParameter.Hidden = true; 163 GoalSeekingUtil.UpdateInputs(InputsParameter.Value, Models, InputParameterChanged); 164 Encoding = GoalSeekingUtil.CreateEncoding(ActiveInputs); 165 GoalSeekingUtil.UpdateTargets(GoalsParameter.Value, Models, GoalParameterChanged); 462 166 RegisterEvents(); 463 167 } … … 466 170 public override double[] Evaluate(Individual individual, IRandom random) { 467 171 var vector = individual.RealVector(); 468 vector.ElementNames = ActiveParameters; 469 172 vector.ElementNames = ActiveInputs.Select(x => x.Name); 470 173 int i = 0; 471 174 // round vector according to parameter step sizes 472 foreach (var parameter in ControllableParameters.CheckedItems) { 473 var step = ControllableParameterBounds[parameter.Index, 2]; 474 vector[i] = RoundToNearestStepMultiple(vector[i], step); 175 foreach (var parameter in ActiveInputs) { 176 vector[i] = RoundToNearestStepMultiple(vector[i], parameter.Step); 475 177 ++i; 476 178 } 477 179 var estimatedValues = GetEstimatedGoalValues(vector, round: true); 478 var qualities = TargetList.CheckedItems.Zip(estimatedValues, (t, v) => new { Name = t.Value.Value, Index = t.Index, EstimatedValue = v }) 479 .Select(target => { 480 var goal = TargetGoals[target.Index, 0]; 481 var weight = TargetGoals[target.Index, 1]; 482 var variance = TargetGoals[target.Index, 2]; 483 return weight * Math.Pow(target.EstimatedValue - goal, 2) / variance; 484 }); 180 var qualities = ActiveGoals.Zip(estimatedValues, (t, v) => new { Target = t, EstimatedValue = v }) 181 .Select(x => x.Target.Weight * Math.Pow(x.EstimatedValue - x.Target.Goal, 2) / x.Target.Variance); 485 182 return qualities.ToArray(); 486 183 } 487 184 185 #region pareto analyzer 488 186 public override void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results, IRandom random) { 489 187 var matrix = FilterFrontsByQualitySum(individuals, qualities, Math.Max(QualitySumCutoff, qualities.Min(x => x.Sum()))); … … 498 196 499 197 private DoubleMatrix FilterFrontsByQualitySum(Individual[] individuals, double[][] qualities, double qualitySumCutoff) { 500 var activeParameters = Active Parameters.ToList();501 var active Targets = ActiveTargets.ToList();198 var activeParameters = ActiveInputs.ToList(); 199 var activeGoals = ActiveGoals.ToList(); 502 200 var filteredModels = new List<double[]>(); 503 201 var rowNames = new List<string>(); 504 202 // build list of column names by combining target and parameter names (with their respective original and estimated values) 505 203 var columnNames = new List<string> { "Quality Sum" }; 506 foreach (var target in active Targets) {507 columnNames.Add(target );508 columnNames.Add(target + " (estimated)");509 } 510 foreach (var controllableParameter in activeParameters) {511 columnNames.Add( controllableParameter);512 columnNames.Add( controllableParameter+ " (estimated)");513 columnNames.Add( controllableParameter+ " (deviation)");204 foreach (var target in activeGoals) { 205 columnNames.Add(target.Name); 206 columnNames.Add(target.Name + " (estimated)"); 207 } 208 foreach (var parameter in activeParameters) { 209 columnNames.Add(parameter.Name); 210 columnNames.Add(parameter.Name + " (estimated)"); 211 columnNames.Add(parameter.Name + " (deviation)"); 514 212 } 515 213 // filter models based on their quality sum; remove duplicate models … … 524 222 rowValues[0] = qualitySum; 525 223 int offset = 1; 526 for (int j = 0; j < active Targets.Count * 2; j += 2) {224 for (int j = 0; j < activeGoals.Count * 2; j += 2) { 527 225 int k = j + offset; 528 var goal = GetTargetGoal(activeTargets[j / 2]);226 var goal = activeGoals[j / 2].Goal; 529 227 rowValues[k] = goal; // original value 530 228 rowValues[k + 1] = estimatedValues[j / 2]; // estimated value 531 229 } 532 offset += active Targets.Count * 2;230 offset += activeGoals.Count * 2; 533 231 for (int j = 0; j < activeParameters.Count * 3; j += 3) { 534 232 int k = j + offset; 535 rowValues[k] = problemData.Dataset.GetDoubleValue(columnNames[k], Row);233 rowValues[k] = 0; // TODO: figure this out and fix 536 234 rowValues[k + 1] = vector[j / 3]; 537 235 rowValues[k + 2] = rowValues[k + 1] - rowValues[k]; … … 550 248 return matrix; 551 249 } 250 #endregion 552 251 553 252 #region event handlers 554 253 private void RegisterEvents() { 555 ProblemDataParameter.ValueChanged += OnProblemDataChanged; 556 ModelCollectionParameter.Value.ItemsAdded += ModelCollection_OnItemsAdded; 557 ModelCollectionParameter.Value.ItemsRemoved += ModelCollection_OnItemsRemoved; 558 RowParameter.Value.ValueChanged += OnRowChanged; 559 ControllableParameters.CheckedItemsChanged += ControllableParameters_OnItemsChanged; 560 ControllableParameterBounds.ItemChanged += ControllableParameterBounds_ItemChanged; 561 } 562 563 private void OnRowChanged(object o, EventArgs e) { 564 // set variables in the modifiable dataset according to the new row 565 foreach (var v in dataset.DoubleVariables) 566 dataset.SetVariableValue(ProblemData.Dataset.GetDoubleValue(v, Row), v, 0); 567 // set the correct targets 568 UpdateTargetList(); 569 } 570 571 private void OnProblemDataChanged(object o, EventArgs e) { 572 try { 573 ProblemData = ProblemDataParameter.Value; 574 } 575 catch (ArgumentException exception) { 576 MessageBox.Show(exception.Message, "Update Problem Data", MessageBoxButtons.OK, MessageBoxIcon.Error); 577 ProblemDataParameter.Value = problemData; 578 } 579 } 580 581 private void ModelCollection_OnItemsAdded(object sender, CollectionItemsChangedEventArgs<IRegressionModel> e) { 582 if (e.Items == null) return; 583 584 var collection = (IObservableCollection<IRegressionModel>)sender; 585 var newItems = e.Items.ToList(); 586 587 foreach (var model in e.Items) { 588 try { 589 CheckIfDatasetContainsTarget(model.TargetVariable); 590 } 591 catch (ArgumentException exception) { 592 MessageBox.Show(exception.Message, "Add Model", MessageBoxButtons.OK, MessageBoxIcon.Error); 593 newItems.Remove(model); 594 collection.Remove(model); 595 } 596 } 597 UpdateTargetList(); 598 OnModelsChanged(this, EventArgs.Empty); 599 } 600 601 private void ModelCollection_OnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRegressionModel> e) { 602 if (e.Items == null) return; 603 UpdateTargetList(); 604 OnModelsChanged(this, EventArgs.Empty); 605 } 606 607 private void ControllableParameters_OnItemsChanged(object o, CollectionItemsChangedEventArgs<IndexedItem<StringValue>> e) { 608 UpdateEncoding(); 609 } 610 611 private void ControllableParameterBounds_ItemChanged(object o, EventArgs e) { 612 UpdateEncoding(); 254 ModelsParameter.Value.ItemsAdded += ModelCollection_ItemsChanged; 255 ModelsParameter.Value.ItemsRemoved += ModelCollection_ItemsChanged; 256 GoalsParameter.Value.CheckedItemsChanged += GoalSeekingUtil.Goals_CheckedItemsChanged; 257 InputsParameter.Value.CheckedItemsChanged += GoalSeekingUtil.Inputs_CheckedItemsChanged; 258 } 259 260 private void ModelCollection_ItemsChanged(object sender, CollectionItemsChangedEventArgs<IRegressionModel> e) { 261 if (e.Items == null || !e.Items.Any()) return; 262 GoalSeekingUtil.UpdateInputs(InputsParameter.Value, Models, InputParameterChanged); 263 Encoding = GoalSeekingUtil.CreateEncoding(ActiveInputs); 264 GoalSeekingUtil.UpdateTargets(GoalsParameter.Value, Models, GoalParameterChanged); 265 GoalSeekingUtil.RaiseEvent(this, ModelsChanged); 266 } 267 268 private void InputParameterChanged(object sender, EventArgs args) { 269 var inputParameter = (InputParameter)sender; 270 var inputs = InputsParameter.Value; 271 if (inputs.ItemChecked(inputParameter) != inputParameter.Active) 272 inputs.SetItemCheckedState(inputParameter, inputParameter.Active); 273 Encoding = GoalSeekingUtil.CreateEncoding(ActiveInputs); 274 } 275 276 private void GoalParameterChanged(object sender, EventArgs args) { 277 var goalParameter = (GoalParameter)sender; 278 var goals = GoalsParameter.Value; 279 if (goals.ItemChecked(goalParameter) != goalParameter.Active) 280 goals.SetItemCheckedState(goalParameter, goalParameter.Active); 613 281 } 614 282 #endregion 615 283 616 284 #region helper methods 617 private void UpdateControllableParameters() { 618 if (ProblemData == null) return; 619 var variablesUsedForPrediction = ModelCollection.Any() 620 ? ModelCollection.SelectMany(x => x.VariablesUsedForPrediction).Distinct() 621 : ProblemData.Dataset.DoubleVariables; 622 SetControllableParameters(variablesUsedForPrediction); 623 } 624 625 private void UpdateTargetList() { 626 if (ProblemData == null) return; 627 if (!Models.Any()) { 628 TargetGoals = new DoubleMatrix(); 629 maximization = new[] { false }; 630 MaximizationParameter.Value = (BoolArray)new BoolArray(maximization).AsReadOnly(); 631 TargetList = new CheckedItemList<StringValue>(); 632 return; 633 } 634 635 var targetNames = Models.Select(x => x.TargetVariable).Distinct().ToList(); 636 var oldTargetGoals = (DoubleMatrix)TargetGoals.Clone(); 637 var oldRowIndices = oldTargetGoals.RowNames.Select((x, i) => new { x, i }).ToDictionary(x => x.x, x => x.i); 638 TargetGoals = new DoubleMatrix(targetNames.Count, 4); 639 TargetGoals.RowNames = targetNames; 640 TargetGoals.ColumnNames = new[] { "Goal", "Weight", "Variance", "Step size" }; 641 642 TargetList = new CheckedItemList<StringValue>(); 643 for (int i = 0; i < targetNames.Count; ++i) { 644 TargetList.Add(new StringValue(targetNames[i]), true); 645 int rowIndex; 646 if (oldRowIndices.TryGetValue(targetNames[i], out rowIndex)) { 647 for (int j = 0; j < TargetGoals.Columns; ++j) 648 TargetGoals[i, j] = oldTargetGoals[rowIndex, j]; 649 } else { 650 TargetGoals[i, 0] = ProblemData.Dataset.GetDoubleValue(targetNames[i], Row); 651 TargetGoals[i, 1] = 1.0; 652 TargetGoals[i, 2] = ProblemData.Dataset.GetReadOnlyDoubleValues(targetNames[i]).Variance(); 653 TargetGoals[i, 3] = 1e-6; 654 } 655 } 656 maximization = new bool[targetNames.Count]; 657 MaximizationParameter.Value = (BoolArray)new BoolArray(maximization).AsReadOnly(); 658 } 659 660 private void UpdateEncoding() { 661 var activeParameters = ActiveParameters.ToList(); 662 if (Encoding == null) 663 Encoding = new RealVectorEncoding(activeParameters.Count); 664 else 665 Encoding.Length = activeParameters.Count; 666 667 Encoding.Bounds = new DoubleMatrix(activeParameters.Count, 2); // only two columns: min and max 668 Encoding.Bounds.RowNames = activeParameters; 669 Encoding.Bounds.ColumnNames = new[] { "Min.", "Max." }; 670 671 int i = 0; 672 foreach (var item in ControllableParameters.CheckedItems) { 673 var index = item.Index; 674 Encoding.Bounds[i, 0] = ControllableParameterBounds[index, 0]; 675 Encoding.Bounds[i, 1] = ControllableParameterBounds[index, 1]; 676 ++i; 677 } 678 } 679 680 private bool IsValidTarget(string target) { 681 return TargetList.Any(x => x.Value == target); 285 // method which throws an exception that can be caught in the event handler if the check fails 286 private void CheckIfDatasetContainsTarget(string target) { 287 if (dataset.DoubleVariables.All(x => x != target)) 288 throw new ArgumentException(string.Format("Model target \"{0}\" does not exist in the dataset.", target)); 682 289 } 683 290 private static double RoundToNearestStepMultiple(double value, double step) { … … 685 292 } 686 293 private IEnumerable<IRegressionModel> GetModels(string target) { 687 return Model Collection.Where(x => x.TargetVariable == target);294 return Models.Where(x => x.TargetVariable == target); 688 295 } 689 296 private class DoubleEqualityComparer : IEqualityComparer<double> {
Note: See TracChangeset
for help on using the changeset viewer.