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

Last change on this file since 3614 was 3614, checked in by mkommend, 12 years ago

implemented first version of RunConstraints (ticket #970)

File size: 11.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
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
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29using HeuristicLab.Collections;
30
31namespace HeuristicLab.Optimization {
32  [StorableClass]
33  [Item("RunCollection", "Represents a collection of runs.")]
34  public class RunCollection : ItemCollection<IRun>, IStringConvertibleMatrix {
35    public RunCollection() : base() { Initialize(); }
36    public RunCollection(int capacity) : base(capacity) { Initialize(); }
37    public RunCollection(IEnumerable<IRun> collection) : base(collection) { Initialize(); this.OnItemsAdded(collection); }
38    private void Initialize() {
39      parameterNames = new List<string>();
40      resultNames = new List<string>();
41      dataTypes = new Dictionary<string, HashSet<Type>>();
42      constraints = new RunCollectionConstraintCollection();
43      constraints.ItemsAdded += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_ItemsAdded);
44      constraints.ItemsRemoved += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_ItemsRemoved);
45      constraints.CollectionReset += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_CollectionReset);
46    }
47    private Dictionary<string, HashSet<Type>> dataTypes;
48    public IEnumerable<Type> GetDataType(string columnName) {
49      if (!dataTypes.ContainsKey(columnName))
50        return new Type[0];
51      return dataTypes[columnName];
52    }
53    private RunCollectionConstraintCollection constraints;
54    public RunCollectionConstraintCollection Constraints {
55      get { return constraints;}
56    }
57
58    protected override void OnCollectionReset(IEnumerable<IRun> items, IEnumerable<IRun> oldItems) {
59      parameterNames.Clear();
60      resultNames.Clear();
61      foreach (IRun run in items) {
62        foreach (KeyValuePair<string, IItem> parameter in run.Parameters)
63          AddParameter(parameter.Key, parameter.Value);
64        foreach (KeyValuePair<string, IItem> result in run.Results)
65          AddResult(result.Key, result.Value);
66      }
67      base.OnCollectionReset(items, oldItems);
68      OnReset();
69      OnColumnNamesChanged();
70      OnRowNamesChanged();
71    }
72    protected override void OnItemsAdded(IEnumerable<IRun> items) {
73      bool columnNamesChanged = false;
74      foreach (IRun run in items) {
75        foreach (KeyValuePair<string, IItem> parameter in run.Parameters)
76          columnNamesChanged |= AddParameter(parameter.Key, parameter.Value);
77        foreach (KeyValuePair<string, IItem> result in run.Results)
78          columnNamesChanged |= AddResult(result.Key, result.Value);
79      }
80      base.OnItemsAdded(items);
81      OnReset();
82      if (columnNamesChanged)
83        OnColumnNamesChanged();
84      OnRowNamesChanged();
85    }
86    protected override void OnItemsRemoved(IEnumerable<IRun> items) {
87      bool columnNamesChanged = false;
88      foreach (IRun run in items) {
89        foreach (string parameterName in run.Parameters.Keys)
90          columnNamesChanged |= RemoveParameterName(parameterName);
91        foreach (string resultName in run.Results.Keys)
92          columnNamesChanged |= RemoveResultName(resultName);
93      }
94      base.OnItemsRemoved(items);
95      OnReset();
96      if (columnNamesChanged)
97        OnColumnNamesChanged();
98      OnRowNamesChanged();
99    }
100
101    private bool AddParameter(string name, IItem value) {
102      if (value == null)
103        return false;
104      if (!parameterNames.Contains(name)) {
105        parameterNames.Add(name);
106        dataTypes[name] = new HashSet<Type>();
107        dataTypes[name].Add(value.GetType());
108        return true;
109      }
110      dataTypes[name].Add(value.GetType());
111      return false;
112    }
113    private bool AddResult(string name, IItem value) {
114      if (value == null)
115        return false;
116      if (!resultNames.Contains(name)) {
117        resultNames.Add(name);
118        dataTypes[name] = new HashSet<Type>();
119        dataTypes[name].Add(value.GetType());
120        return true;
121      }
122      dataTypes[name].Add(value.GetType());
123      return false;
124    }
125    private bool RemoveParameterName(string name) {
126      if (!list.Any(x => x.Parameters.ContainsKey(name))) {
127        parameterNames.Remove(name);
128        return true;
129      }
130      return false;
131    }
132    private bool RemoveResultName(string name) {
133      if (!list.Any(x => x.Results.ContainsKey(name))) {
134        resultNames.Remove(name);
135        return true;
136      }
137      return false;
138    }
139
140    public IItem GetValue(int rowIndex, int columnIndex) {
141      IRun run = this.list[rowIndex];
142      return GetValue(run, columnIndex);
143    }
144
145    public IItem GetValue(IRun run, int columnIndex) {
146      IItem value = null;
147      if (columnIndex < parameterNames.Count) {
148        string parameterName = parameterNames[columnIndex];
149        if (run.Parameters.ContainsKey(parameterName))
150          value = run.Parameters[parameterName];
151      } else if (columnIndex < parameterNames.Count + resultNames.Count) {
152        string resultName = resultNames[columnIndex - parameterNames.Count];
153        if (run.Results.ContainsKey(resultName))
154          value = run.Results[resultName];
155      }
156      return value;
157    }
158
159    #region IStringConvertibleMatrix Members
160    [Storable]
161    private List<string> parameterNames;
162    public IEnumerable<string> ParameterNames {
163      get { return this.parameterNames; }
164    }
165    [Storable]
166    private List<string> resultNames;
167    public IEnumerable<string> ResultNames {
168      get { return this.resultNames; }
169    }
170    int IStringConvertibleMatrix.Rows {
171      get { return this.Count; }
172      set { throw new NotSupportedException(); }
173    }
174    int IStringConvertibleMatrix.Columns {
175      get { return parameterNames.Count + resultNames.Count; }
176      set { throw new NotSupportedException(); }
177    }
178    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
179      get {
180        List<string> value = new List<string>(parameterNames);
181        value.AddRange(resultNames);
182        return value;
183      }
184      set { throw new NotSupportedException(); }
185    }
186    IEnumerable<string> IStringConvertibleMatrix.RowNames {
187      get { return list.Select(x => x.Name).ToList(); }
188      set { throw new NotSupportedException(); }
189    }
190    bool IStringConvertibleMatrix.SortableView {
191      get { return true; }
192      set { throw new NotSupportedException(); }
193    }
194    bool IStringConvertibleMatrix.ReadOnly {
195      get { return true; }
196    }
197
198    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
199      IItem value = GetValue(rowIndex, columnIndex);
200      if (value == null)
201        return string.Empty;
202      return value.ToString();
203    }
204
205    public event EventHandler<EventArgs<int, int>> ItemChanged;
206    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
207      if (ItemChanged != null)
208        ItemChanged(this, new EventArgs<int, int>(rowIndex, columnIndex));
209      OnToStringChanged();
210    }
211    public event EventHandler Reset;
212    protected virtual void OnReset() {
213      if (Reset != null)
214        Reset(this, EventArgs.Empty);
215      OnToStringChanged();
216    }
217    public event EventHandler ColumnNamesChanged;
218    protected virtual void OnColumnNamesChanged() {
219      EventHandler handler = ColumnNamesChanged;
220      if (handler != null)
221        handler(this, EventArgs.Empty);
222    }
223    public event EventHandler RowNamesChanged;
224    protected virtual void OnRowNamesChanged() {
225      EventHandler handler = RowNamesChanged;
226      if (handler != null)
227        handler(this, EventArgs.Empty);
228    }
229
230    public event EventHandler SortableViewChanged;
231    protected virtual void OnSortableViewChanged() {
232      EventHandler handler = SortableViewChanged;
233      if (handler != null)
234        handler(this, EventArgs.Empty);
235    }
236
237    public bool Validate(string value, out string errorMessage) { throw new NotSupportedException(); }
238    public bool SetValue(string value, int rowIndex, int columnIndex) { throw new NotSupportedException(); }
239    #endregion
240
241    #region filtering
242    private void UpdateFiltering() {
243      list.ForEach(r => r.Visible = true);
244      foreach (IRunCollectionConstraint constraint in this.constraints)
245        constraint.Check();
246    }
247
248    protected virtual void RegisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
249      foreach (IRunCollectionConstraint constraint in constraints) {
250        constraint.ActiveChanged += new EventHandler(Constraint_ActiveChanged);
251        constraint.ConstrainedValueChanged += new EventHandler(Constraint_ConstrainedValueChanged);
252        constraint.ConstraintOperationChanged += new EventHandler(Constraint_ConstraintOperationChanged);
253        constraint.ConstraintDataChanged += new EventHandler(Constraint_ConstraintDataChanged);
254      }
255    }
256    protected virtual void DeregisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
257      foreach (IRunCollectionConstraint constraint in constraints) {
258        constraint.ActiveChanged -= new EventHandler(Constraint_ActiveChanged);
259        constraint.ConstrainedValueChanged -= new EventHandler(Constraint_ConstrainedValueChanged);
260        constraint.ConstraintOperationChanged -= new EventHandler(Constraint_ConstraintOperationChanged);
261        constraint.ConstraintDataChanged -= new EventHandler(Constraint_ConstraintDataChanged);
262      }
263    }
264
265    protected virtual void Constraints_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
266      DeregisterConstraintEvents(e.OldItems);
267      RegisterConstraintEvents(e.Items);
268      this.UpdateFiltering();
269    }
270    protected virtual void Constraints_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
271      RegisterConstraintEvents(e.Items);
272      foreach (IRunCollectionConstraint constraint in e.Items)
273        constraint.ConstrainedValue = this;
274      this.UpdateFiltering();
275    }
276    protected virtual void Constraints_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
277      DeregisterConstraintEvents(e.Items);
278      this.UpdateFiltering();
279    }
280    protected virtual void Constraint_ActiveChanged(object sender, EventArgs e) {
281      this.UpdateFiltering();
282    }
283    protected virtual void Constraint_ConstrainedValueChanged(object sender, EventArgs e) {
284      //mkommend: this method is intentionally left empty, because the constrainedValue is set in the ItemsAdded method
285    }
286    protected virtual void Constraint_ConstraintOperationChanged(object sender, EventArgs e) {
287      this.UpdateFiltering();
288    }
289    protected virtual void Constraint_ConstraintDataChanged(object sender, EventArgs e) {
290      this.UpdateFiltering();
291    }
292    #endregion
293  }
294}
Note: See TracBrowser for help on using the repository browser.