Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Optimization/3.3/RunCollection.cs @ 9666

Last change on this file since 9666 was 9456, checked in by swagner, 12 years ago

Updated copyright year and added some missing license headers (#1889)

File size: 18.0 KB
RevLine 
[3260]1#region License Information
2/* HeuristicLab
[9456]3 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[3260]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
[3329]22using System;
[3260]23using System.Collections.Generic;
24using System.Linq;
[4068]25using HeuristicLab.Collections;
[3376]26using HeuristicLab.Common;
[3260]27using HeuristicLab.Core;
[3329]28using HeuristicLab.Data;
[3260]29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Optimization {
[3716]32  [Item("Run Collection", "Represents a collection of runs.")]
33  [Creatable("Testing & Analysis")]
[3260]34  [StorableClass]
[4419]35  public class RunCollection : ItemCollection<IRun>, IStringConvertibleMatrix, IStorableContent {
36    public string Filename { get; set; }
37
[4164]38    [StorableConstructor]
[4888]39    protected RunCollection(bool deserializing)
40      : base(deserializing) {
41      updateOfRunsInProgress = false;
42    }
[4722]43    protected RunCollection(RunCollection original, Cloner cloner)
44      : base(original, cloner) {
[4888]45      updateOfRunsInProgress = false;
[8962]46      optimizerName = original.optimizerName;
[8738]47
[4722]48      resultNames = new List<string>(original.resultNames);
49      parameterNames = new List<string>(original.parameterNames);
50      dataTypes = new Dictionary<string, HashSet<Type>>();
51      foreach (string s in original.dataTypes.Keys)
52        dataTypes[s] = new HashSet<Type>(original.dataTypes[s]);
53
54      constraints = new RunCollectionConstraintCollection(original.constraints.Select(x => cloner.Clone(x)));
[6693]55      modifiers = new CheckedItemList<IRunCollectionModifier>(original.modifiers.Select(cloner.Clone));
[4722]56      foreach (IRunCollectionConstraint constraint in constraints)
57        constraint.ConstrainedValue = this;
58      RegisterConstraintsEvents();
59      RegisterConstraintEvents(constraints);
60
61      UpdateFiltering(true);
62    }
[3329]63    public RunCollection() : base() { Initialize(); }
64    public RunCollection(int capacity) : base(capacity) { Initialize(); }
65    public RunCollection(IEnumerable<IRun> collection) : base(collection) { Initialize(); this.OnItemsAdded(collection); }
[3447]66    private void Initialize() {
[4888]67      updateOfRunsInProgress = false;
[3447]68      parameterNames = new List<string>();
69      resultNames = new List<string>();
[3614]70      dataTypes = new Dictionary<string, HashSet<Type>>();
71      constraints = new RunCollectionConstraintCollection();
[6693]72      modifiers = new CheckedItemList<IRunCollectionModifier>();
[4164]73      RegisterConstraintsEvents();
[3447]74    }
[4164]75
[3625]76    [Storable]
[3614]77    private Dictionary<string, HashSet<Type>> dataTypes;
78    public IEnumerable<Type> GetDataType(string columnName) {
79      if (!dataTypes.ContainsKey(columnName))
80        return new Type[0];
81      return dataTypes[columnName];
82    }
[4164]83
84    [Storable]
[3614]85    private RunCollectionConstraintCollection constraints;
86    public RunCollectionConstraintCollection Constraints {
[3625]87      get { return constraints; }
[3614]88    }
[3329]89
[6693]90    [Storable]
91    private CheckedItemList<IRunCollectionModifier> modifiers;
92    public CheckedItemList<IRunCollectionModifier> Modifiers {
93      get { return modifiers; }
94    }
95
96
[4888]97    private bool updateOfRunsInProgress;
98    public bool UpdateOfRunsInProgress {
99      get { return updateOfRunsInProgress; }
100      set {
101        if (updateOfRunsInProgress != value) {
102          updateOfRunsInProgress = value;
103          OnUpdateOfRunsInProgressChanged();
104        }
105      }
106    }
107
[8962]108    private string optimizerName = string.Empty;
[8738]109    [Storable]
[8962]110    public string OptimizerName {
111      get { return optimizerName; }
[8738]112      set {
[8962]113        if (value != optimizerName && !string.IsNullOrEmpty(value)) {
114          optimizerName = value;
115          OnOptimizerNameChanged();
[8738]116        }
117      }
118    }
119
[8967]120    // BackwardsCompatibility3.3
121    #region Backwards compatible code, remove with 3.4
[8962]122    [Storable(AllowOneWay = true)]
123    private string AlgorithmName {
124      set { optimizerName = value; }
125    }
[8967]126    #endregion
[8962]127
[4888]128    [StorableHook(HookType.AfterDeserialization)]
129    private void AfterDeserialization() {
130      if (constraints == null) constraints = new RunCollectionConstraintCollection();
[6693]131      if (modifiers == null) modifiers = new CheckedItemList<IRunCollectionModifier>();
[4888]132      RegisterConstraintsEvents();
133      RegisterConstraintEvents(constraints);
134      UpdateFiltering(true);
135    }
136
137    public override IDeepCloneable Clone(Cloner cloner) {
138      return new RunCollection(this, cloner);
139    }
140
141    public event EventHandler UpdateOfRunsInProgressChanged;
142    protected virtual void OnUpdateOfRunsInProgressChanged() {
143      var handler = UpdateOfRunsInProgressChanged;
144      if (handler != null) handler(this, EventArgs.Empty);
145    }
146
[8962]147    public event EventHandler OptimizerNameChanged;
148    protected virtual void OnOptimizerNameChanged() {
149      var handler = OptimizerNameChanged;
[8738]150      if (handler != null) handler(this, EventArgs.Empty);
151    }
152
[3329]153    protected override void OnCollectionReset(IEnumerable<IRun> items, IEnumerable<IRun> oldItems) {
154      parameterNames.Clear();
155      resultNames.Clear();
[7798]156      dataTypes.Clear();
[3329]157      foreach (IRun run in items) {
158        foreach (KeyValuePair<string, IItem> parameter in run.Parameters)
159          AddParameter(parameter.Key, parameter.Value);
160        foreach (KeyValuePair<string, IItem> result in run.Results)
161          AddResult(result.Key, result.Value);
162      }
[4200]163      columnNameCache = null;
[5150]164      OnColumnsChanged();
[3329]165      OnColumnNamesChanged();
[4200]166      rowNamesCache = null;
[4518]167      base.OnCollectionReset(items, oldItems);
[5150]168      OnRowsChanged();
[3329]169      OnRowNamesChanged();
[4518]170      OnReset();
171      UpdateFiltering(false);
[3329]172    }
173    protected override void OnItemsAdded(IEnumerable<IRun> items) {
[5150]174      bool columnsChanged = false;
[3329]175      foreach (IRun run in items) {
176        foreach (KeyValuePair<string, IItem> parameter in run.Parameters)
[5150]177          columnsChanged |= AddParameter(parameter.Key, parameter.Value);
[3329]178        foreach (KeyValuePair<string, IItem> result in run.Results)
[5150]179          columnsChanged |= AddResult(result.Key, result.Value);
[3329]180      }
[5150]181      if (columnsChanged) columnNameCache = null;
[4200]182      rowNamesCache = null;
[4518]183      base.OnItemsAdded(items);
[4707]184      OnReset();
[5150]185      OnRowsChanged();
[3329]186      OnRowNamesChanged();
[5150]187      if (columnsChanged) {
188        OnColumnsChanged();
189        OnColumnNamesChanged();
190      }
[4518]191      UpdateFiltering(false);
[3329]192    }
193    protected override void OnItemsRemoved(IEnumerable<IRun> items) {
[5150]194      bool columnsChanged = false;
[3329]195      foreach (IRun run in items) {
196        foreach (string parameterName in run.Parameters.Keys)
[5150]197          columnsChanged |= RemoveParameterName(parameterName);
[3329]198        foreach (string resultName in run.Results.Keys)
[5150]199          columnsChanged |= RemoveResultName(resultName);
[3329]200      }
[5150]201      if (columnsChanged) columnNameCache = null;
[4200]202      rowNamesCache = null;
[4518]203      base.OnItemsRemoved(items);
[4707]204      OnReset();
[5152]205      OnRowsChanged();
[3329]206      OnRowNamesChanged();
[5150]207      if (columnsChanged) {
208        OnColumnsChanged();
209        OnColumnNamesChanged();
210      }
[3329]211    }
212
213    private bool AddParameter(string name, IItem value) {
214      if (value == null)
215        return false;
[3441]216      if (!parameterNames.Contains(name)) {
[3329]217        parameterNames.Add(name);
[3614]218        dataTypes[name] = new HashSet<Type>();
219        dataTypes[name].Add(value.GetType());
[3329]220        return true;
221      }
[3614]222      dataTypes[name].Add(value.GetType());
[3329]223      return false;
224    }
225    private bool AddResult(string name, IItem value) {
226      if (value == null)
227        return false;
[3441]228      if (!resultNames.Contains(name)) {
[3329]229        resultNames.Add(name);
[3614]230        dataTypes[name] = new HashSet<Type>();
231        dataTypes[name].Add(value.GetType());
[3329]232        return true;
233      }
[3614]234      dataTypes[name].Add(value.GetType());
[3329]235      return false;
236    }
237    private bool RemoveParameterName(string name) {
238      if (!list.Any(x => x.Parameters.ContainsKey(name))) {
239        parameterNames.Remove(name);
240        return true;
241      }
242      return false;
243    }
244    private bool RemoveResultName(string name) {
245      if (!list.Any(x => x.Results.ContainsKey(name))) {
246        resultNames.Remove(name);
247        return true;
248      }
249      return false;
250    }
251
[3447]252    public IItem GetValue(int rowIndex, int columnIndex) {
253      IRun run = this.list[rowIndex];
[3492]254      return GetValue(run, columnIndex);
255    }
256
257    public IItem GetValue(IRun run, int columnIndex) {
[3717]258      string name = ((IStringConvertibleMatrix)this).ColumnNames.ElementAt(columnIndex);
259      return GetValue(run, name);
260    }
261
262    public IItem GetValue(IRun run, string columnName) {
[3447]263      IItem value = null;
[3767]264      if (run.Parameters.ContainsKey(columnName))
265        value = run.Parameters[columnName];
266      else if (run.Results.ContainsKey(columnName))
267        value = run.Results[columnName];
[3447]268      return value;
269    }
270
[3329]271    #region IStringConvertibleMatrix Members
[3347]272    [Storable]
[3329]273    private List<string> parameterNames;
[3492]274    public IEnumerable<string> ParameterNames {
275      get { return this.parameterNames; }
276    }
[3347]277    [Storable]
[3329]278    private List<string> resultNames;
[3492]279    public IEnumerable<string> ResultNames {
280      get { return this.resultNames; }
281    }
[3447]282    int IStringConvertibleMatrix.Rows {
[3329]283      get { return this.Count; }
[3447]284      set { throw new NotSupportedException(); }
[3329]285    }
[3447]286    int IStringConvertibleMatrix.Columns {
[3329]287      get { return parameterNames.Count + resultNames.Count; }
288      set { throw new NotSupportedException(); }
289    }
[4200]290    private List<string> columnNameCache;
[3447]291    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
[3329]292      get {
[4200]293        if (columnNameCache == null) {
294          columnNameCache = new List<string>(parameterNames);
295          columnNameCache.AddRange(resultNames);
296          columnNameCache.Sort();
297        }
298        return columnNameCache;
[3329]299      }
300      set { throw new NotSupportedException(); }
301    }
[4200]302    private List<string> rowNamesCache;
[3447]303    IEnumerable<string> IStringConvertibleMatrix.RowNames {
[4200]304      get {
305        if (rowNamesCache == null)
306          rowNamesCache = list.Select(x => x.Name).ToList();
307        return rowNamesCache;
308      }
[3329]309      set { throw new NotSupportedException(); }
310    }
[3447]311    bool IStringConvertibleMatrix.SortableView {
[3329]312      get { return true; }
313      set { throw new NotSupportedException(); }
314    }
[3447]315    bool IStringConvertibleMatrix.ReadOnly {
316      get { return true; }
[3430]317    }
[3329]318
[3447]319    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
320      IItem value = GetValue(rowIndex, columnIndex);
321      if (value == null)
322        return string.Empty;
323      return value.ToString();
[3329]324    }
325
326    public event EventHandler<EventArgs<int, int>> ItemChanged;
327    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
[4722]328      EventHandler<EventArgs<int, int>> handler = ItemChanged;
329      if (handler != null) handler(this, new EventArgs<int, int>(rowIndex, columnIndex));
[3329]330      OnToStringChanged();
331    }
332    public event EventHandler Reset;
333    protected virtual void OnReset() {
[4722]334      EventHandler handler = Reset;
335      if (handler != null) handler(this, EventArgs.Empty);
[3329]336      OnToStringChanged();
337    }
[5150]338    public event EventHandler ColumnsChanged;
339    protected virtual void OnColumnsChanged() {
340      var handler = ColumnsChanged;
341      if (handler != null) handler(this, EventArgs.Empty);
342    }
343    public event EventHandler RowsChanged;
344    protected virtual void OnRowsChanged() {
345      var handler = RowsChanged;
346      if (handler != null) handler(this, EventArgs.Empty);
347    }
[3329]348    public event EventHandler ColumnNamesChanged;
349    protected virtual void OnColumnNamesChanged() {
350      EventHandler handler = ColumnNamesChanged;
[4722]351      if (handler != null) handler(this, EventArgs.Empty);
[3329]352    }
353    public event EventHandler RowNamesChanged;
354    protected virtual void OnRowNamesChanged() {
355      EventHandler handler = RowNamesChanged;
[4722]356      if (handler != null) handler(this, EventArgs.Empty);
[3329]357    }
358    public event EventHandler SortableViewChanged;
[3333]359    protected virtual void OnSortableViewChanged() {
360      EventHandler handler = SortableViewChanged;
[4722]361      if (handler != null) handler(this, EventArgs.Empty);
[3333]362    }
363
[3329]364    public bool Validate(string value, out string errorMessage) { throw new NotSupportedException(); }
365    public bool SetValue(string value, int rowIndex, int columnIndex) { throw new NotSupportedException(); }
366    #endregion
[3614]367
[4888]368    #region Filtering
[3632]369    private void UpdateFiltering(bool reset) {
[4888]370      UpdateOfRunsInProgress = true;
[3632]371      if (reset)
372        list.ForEach(r => r.Visible = true);
[3614]373      foreach (IRunCollectionConstraint constraint in this.constraints)
374        constraint.Check();
[4888]375      UpdateOfRunsInProgress = false;
[3614]376    }
377
[4164]378    private void RegisterConstraintsEvents() {
379      constraints.ItemsAdded += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_ItemsAdded);
380      constraints.ItemsRemoved += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_ItemsRemoved);
381      constraints.CollectionReset += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_CollectionReset);
382    }
383
[3614]384    protected virtual void RegisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
385      foreach (IRunCollectionConstraint constraint in constraints) {
386        constraint.ActiveChanged += new EventHandler(Constraint_ActiveChanged);
387        constraint.ConstrainedValueChanged += new EventHandler(Constraint_ConstrainedValueChanged);
388        constraint.ConstraintOperationChanged += new EventHandler(Constraint_ConstraintOperationChanged);
389        constraint.ConstraintDataChanged += new EventHandler(Constraint_ConstraintDataChanged);
390      }
391    }
392    protected virtual void DeregisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
393      foreach (IRunCollectionConstraint constraint in constraints) {
394        constraint.ActiveChanged -= new EventHandler(Constraint_ActiveChanged);
395        constraint.ConstrainedValueChanged -= new EventHandler(Constraint_ConstrainedValueChanged);
396        constraint.ConstraintOperationChanged -= new EventHandler(Constraint_ConstraintOperationChanged);
397        constraint.ConstraintDataChanged -= new EventHandler(Constraint_ConstraintDataChanged);
398      }
399    }
400
401    protected virtual void Constraints_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
402      DeregisterConstraintEvents(e.OldItems);
403      RegisterConstraintEvents(e.Items);
[3632]404      this.UpdateFiltering(true);
[3614]405    }
406    protected virtual void Constraints_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
407      RegisterConstraintEvents(e.Items);
408      foreach (IRunCollectionConstraint constraint in e.Items)
409        constraint.ConstrainedValue = this;
[3632]410      this.UpdateFiltering(false);
[3614]411    }
412    protected virtual void Constraints_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
413      DeregisterConstraintEvents(e.Items);
[3632]414      this.UpdateFiltering(true);
[3614]415    }
416    protected virtual void Constraint_ActiveChanged(object sender, EventArgs e) {
[3632]417      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
418      this.UpdateFiltering(!constraint.Active);
[3614]419    }
420    protected virtual void Constraint_ConstrainedValueChanged(object sender, EventArgs e) {
421      //mkommend: this method is intentionally left empty, because the constrainedValue is set in the ItemsAdded method
422    }
423    protected virtual void Constraint_ConstraintOperationChanged(object sender, EventArgs e) {
[3632]424      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
425      if (constraint.Active)
426        this.UpdateFiltering(true);
[3614]427    }
428    protected virtual void Constraint_ConstraintDataChanged(object sender, EventArgs e) {
[3632]429      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
430      if (constraint.Active)
431        this.UpdateFiltering(true);
[3614]432    }
433    #endregion
[6693]434
435    #region Modification
436    public void Modify() {
437      UpdateOfRunsInProgress = true;
438      var runs = this.ToList();
439      var selectedRuns = runs.Where(r => r.Visible).ToList();
440      int nSelected = selectedRuns.Count;
441      if (nSelected > 0) {
442        foreach (var modifier in Modifiers.CheckedItems)
443          modifier.Value.Modify(selectedRuns);
444        if (nSelected != selectedRuns.Count || HaveDifferentOrder(selectedRuns, runs.Where(r => r.Visible))) {
445          Clear();
446          AddRange(ReplaceVisibleRuns(runs, selectedRuns));
447        } else if (runs.Count > 0) {
448          OnCollectionReset(this, runs);
449        }
450      }
451      UpdateOfRunsInProgress = false;
452    }
453
454    private static IEnumerable<IRun> ReplaceVisibleRuns(IEnumerable<IRun> runs, IEnumerable<IRun> visibleRuns) {
455      var newRuns = new List<IRun>();
456      var runIt = runs.GetEnumerator();
457      var visibleRunIt = visibleRuns.GetEnumerator();
458      while (runIt.MoveNext()) {
459        if (runIt.Current != null && !runIt.Current.Visible)
460          newRuns.Add(runIt.Current);
461        else if (visibleRunIt.MoveNext())
462          newRuns.Add(visibleRunIt.Current);
463      }
464      while (visibleRunIt.MoveNext())
465        newRuns.Add(visibleRunIt.Current);
466      return newRuns;
467    }
468
469    private static bool HaveDifferentOrder(IEnumerable<IRun> l1, IEnumerable<IRun> l2) {
470      return l1.Zip(l2, (r1, r2) => r1 != r2).Any();
471    }
472    #endregion
[3260]473  }
474}
Note: See TracBrowser for help on using the repository browser.