Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3.2/sources/HeuristicLab.GP/3.3/FunctionLibraryEditor.cs @ 4483

Last change on this file since 4483 was 2788, checked in by gkronber, 15 years ago

Removed unnecessary combobox in function library editor. Functions can be dragged in from the right into the allowed sub-functions lists. #873 (FunctionLibraryEditor GUI should be simplified)

File size: 12.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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 System.Windows.Forms;
26using HeuristicLab.Core;
27using HeuristicLab.GP.Interfaces;
28using System.Text;
29using HeuristicLab.Random;
30
31namespace HeuristicLab.GP {
32  public partial class FunctionLibraryEditor : EditorBase {
33    private ChooseItemDialog chooseFunctionDialog;
34    public FunctionLibrary FunctionLibrary {
35      get { return (FunctionLibrary)Item; }
36      set { base.Item = value; }
37    }
38
39    public FunctionLibraryEditor()
40      : base() {
41      InitializeComponent();
42    }
43
44    public FunctionLibraryEditor(FunctionLibrary library)
45      : this() {
46      FunctionLibrary = library;
47    }
48
49    protected override void AddItemEvents() {
50      base.AddItemEvents();
51      base.Item.Changed += (sender, args) => UpdateControls();
52    }
53
54    protected override void UpdateControls() {
55      base.UpdateControls();
56      mutationListView.Items.Clear();
57      initListView.Items.Clear();
58      functionsListView.Clear();
59      foreach (IFunction fun in FunctionLibrary.Functions) {
60        functionsListView.Items.Add(CreateListViewItem(fun));
61        if (fun.Manipulator != null) {
62          mutationListView.Items.Add(CreateListViewItem(fun));
63        }
64        if (fun.Initializer != null) {
65          initListView.Items.Add(CreateListViewItem(fun));
66        }
67      }
68    }
69
70    private void mutationListView_SelectedIndexChanged(object sender, EventArgs e) {
71      if (mutationListView.SelectedItems.Count > 0 && mutationListView.SelectedItems[0].Tag != null) {
72        IOperator manipulator = ((IFunction)mutationListView.SelectedItems[0].Tag).Manipulator;
73        mutationVariableView.Enabled = true;
74        mutationVariableView.Variable = new Variable("Manipulator", manipulator);
75      } else {
76        mutationVariableView.Enabled = false;
77      }
78    }
79
80    private void initListView_SelectedIndexChanged(object sender, EventArgs e) {
81      if (initListView.SelectedItems.Count > 0 && initListView.SelectedItems[0].Tag != null) {
82        IOperator initializer = ((IFunction)initListView.SelectedItems[0].Tag).Initializer;
83        initVariableView.Enabled = true;
84        initVariableView.Variable = new Variable("Initializer", initializer);
85      } else {
86        initVariableView.Enabled = false;
87      }
88    }
89
90    private void addButton_Click(object sender, EventArgs e) {
91      if (chooseFunctionDialog == null) chooseFunctionDialog = new ChooseItemDialog(typeof(IFunction));
92      if (chooseFunctionDialog.ShowDialog(this) == DialogResult.OK) {
93        FunctionLibrary.AddFunction((IFunction)chooseFunctionDialog.Item);
94      }
95    }
96
97    private void removeButton_Click(object sender, EventArgs e) {
98      // delete from the end of the list
99      List<int> removeIndices = functionsListView.SelectedIndices.OfType<int>().OrderBy(x => 1.0 / x).ToList();
100      try {
101        Cursor = Cursors.WaitCursor;
102        foreach (int selectedIndex in removeIndices) {
103          FunctionLibrary.RemoveFunction((IFunction)functionsListView.Items[selectedIndex].Tag);
104        }
105      }
106      finally {
107        Cursor = Cursors.Default;
108      }
109    }
110
111    private void functionsListView_SelectedIndexChanged(object sender, EventArgs e) {
112      if (functionsListView.SelectedIndices.Count > 0) {
113        removeButton.Enabled = true;
114      } else {
115        removeButton.Enabled = false;
116      }
117    }
118
119    private ListViewItem CreateListViewItem(IFunction function) {
120      ListViewItem item = new ListViewItem();
121      item.Name = function.Name;
122      item.Text = function.Name;
123      item.Tag = function;
124      return item;
125    }
126
127    private void functionsListView_ItemDrag(object sender, ItemDragEventArgs e) {
128      ListViewItem item = (ListViewItem)e.Item;
129      IFunction fun = (IFunction)item.Tag;
130      DataObject data = new DataObject();
131      data.SetData("IFunction", fun);
132      data.SetData("DragSource", functionsListView);
133      DoDragDrop(data, DragDropEffects.Link);
134    }
135
136    private void functionsListView_KeyUp(object sender, KeyEventArgs e) {
137      if (e.KeyCode == Keys.Delete && functionsListView.SelectedItems.Count > 0) {
138        List<IFunction> removedFunctions = new List<IFunction>(from x in functionsListView.SelectedItems.OfType<ListViewItem>()
139                                                               select (IFunction)x.Tag);
140        try {
141          Cursor = Cursors.WaitCursor;
142          foreach (var fun in removedFunctions) {
143            FunctionLibrary.RemoveFunction(fun);
144          }
145        }
146        finally {
147          Cursor = Cursors.Default;
148        }
149      }
150    }
151    #region fun lib test
152    private string TestFunctionLibrary() {
153      int n = 1000;
154      try {
155        IFunctionTree[] randomTrees = CreateRandomTrees(n, 1, 100);
156        StringBuilder builder = new StringBuilder();
157        builder.AppendLine("Function symbol frequencies:");
158        builder.AppendLine(CalculateFunctionFrequencies(randomTrees));
159        builder.AppendLine("-----------------------------------------");
160        builder.AppendLine("Terminal symbol frequencies:");
161        builder.AppendLine(CalculateTerminalFrequencies(randomTrees));
162        builder.AppendLine("-----------------------------------------");
163        builder.AppendLine("Function arity frequencies:");
164        builder.AppendLine(CalculateFunctionArityFrequencies(randomTrees));
165        builder.AppendLine("-----------------------------------------");
166        builder.AppendLine("Tree size frequencies:");
167        builder.AppendLine(CalculateTreeSizeFrequencies(randomTrees));
168        builder.AppendLine("-----------------------------------------");
169        builder.AppendLine("Tree height frequencies:");
170        builder.AppendLine(CalculateTreeHeightFrequencies(randomTrees));
171        return builder.ToString();
172      }
173      catch (ArgumentException ex) {
174        return "Could not create random trees:" + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace;
175      }
176    }
177
178    private string CalculateFunctionFrequencies(IFunctionTree[] randomTrees) {
179      Dictionary<IFunction, int> occurances = new Dictionary<IFunction, int>();
180      double n = 0.0;
181      for (int i = 0; i < randomTrees.Length; i++) {
182        foreach (var node in FunctionTreeIterator.IteratePrefix(randomTrees[i])) {
183          if (node.SubTrees.Count > 0) {
184            if (!occurances.ContainsKey(node.Function))
185              occurances[node.Function] = 0;
186            occurances[node.Function]++;
187            n++;
188          }
189        }
190      }
191      StringBuilder strBuilder = new StringBuilder();
192      foreach (var function in occurances.Keys) {
193        strBuilder.Append(Environment.NewLine);
194        strBuilder.Append(function.Name); strBuilder.Append(": ");
195        strBuilder.AppendFormat("{0:#0.00%}", occurances[function] / n);
196      }
197      return strBuilder.ToString();
198    }
199
200    public string CalculateTreeSizeFrequencies(IFunctionTree[] randomTrees) {
201      int[] histogram = new int[105 / 5];
202      for (int i = 0; i < randomTrees.Length; i++) {
203        histogram[randomTrees[i].GetSize() / 5]++;
204      }
205      StringBuilder strBuilder = new StringBuilder();
206      for (int i = 0; i < histogram.Length; i++) {
207        strBuilder.Append(Environment.NewLine);
208        strBuilder.Append("< "); strBuilder.Append((i + 1) * 5);
209        strBuilder.Append(": "); strBuilder.AppendFormat("{0:#0.00%}", histogram[i] / (double)randomTrees.Length);
210      }
211      return strBuilder.ToString();
212    }
213
214    public string CalculateTreeHeightFrequencies(IFunctionTree[] randomTrees) {
215      int[] histogram = new int[100];
216      for (int i = 0; i < randomTrees.Length; i++) {
217        histogram[randomTrees[i].GetHeight()]++;
218      }
219      StringBuilder strBuilder = new StringBuilder();
220      for (int i = 0; i < histogram.Length; i++) {
221        strBuilder.Append(Environment.NewLine);
222        strBuilder.Append("< "); strBuilder.Append((i + 1));
223        strBuilder.Append(": "); strBuilder.AppendFormat("{0:#0.00%}", histogram[i] / (double)randomTrees.Length);
224      }
225      return strBuilder.ToString();
226    }
227
228    public string CalculateFunctionArityFrequencies(IFunctionTree[] randomTrees) {
229      Dictionary<int, int> occurances = new Dictionary<int, int>();
230      double n = 0.0;
231      for (int i = 0; i < randomTrees.Length; i++) {
232        foreach (var node in FunctionTreeIterator.IteratePrefix(randomTrees[i])) {
233          if (!occurances.ContainsKey(node.SubTrees.Count))
234            occurances[node.SubTrees.Count] = 0;
235          occurances[node.SubTrees.Count]++;
236          n++;
237        }
238      }
239      StringBuilder strBuilder = new StringBuilder();
240      foreach (var arity in occurances.Keys) {
241        strBuilder.Append(Environment.NewLine);
242        strBuilder.Append(arity); strBuilder.Append(": ");
243        strBuilder.AppendFormat("{0:#0.00%}", occurances[arity] / n);
244      }
245      return strBuilder.ToString();
246    }
247
248    public string CalculateTerminalFrequencies(IFunctionTree[] randomTrees) {
249      Dictionary<IFunction, int> occurances = new Dictionary<IFunction, int>();
250      double n = 0.0;
251      for (int i = 0; i < randomTrees.Length; i++) {
252        foreach (var node in FunctionTreeIterator.IteratePrefix(randomTrees[i])) {
253          if (node.SubTrees.Count == 0) {
254            if (!occurances.ContainsKey(node.Function))
255              occurances[node.Function] = 0;
256            occurances[node.Function]++;
257            n++;
258          }
259        }
260      }
261      StringBuilder strBuilder = new StringBuilder();
262      foreach (var function in occurances.Keys) {
263        strBuilder.Append(Environment.NewLine);
264        strBuilder.Append(function.Name); strBuilder.Append(": ");
265        strBuilder.AppendFormat("{0:#0.00%}", occurances[function] / n);
266      }
267      return strBuilder.ToString();
268    }
269
270    private IFunctionTree[] CreateRandomTrees(int popSize, int minSize, int maxSize) {
271      int maxHeight = 10;
272      int maxTries = 100;
273      IFunctionTree[] randomTrees = new IFunctionTree[popSize];
274      MersenneTwister twister = new MersenneTwister();
275      for (int i = 0; i < randomTrees.Length; i++) {
276        int treeSize = twister.Next(minSize, maxSize);
277        IFunctionTree root = null;
278        int tries = 0;
279        TreeGardener gardener = new TreeGardener(twister, FunctionLibrary);
280        do {
281          try {
282            root = gardener.PTC2(treeSize, maxSize);
283          }
284          catch (ArgumentException) {
285            // try a different size
286            treeSize = twister.Next(minSize, maxSize);
287            tries = 0;
288          }
289          if (tries++ >= maxTries) {
290            // try a different size
291            treeSize = twister.Next(minSize, maxSize);
292            tries = 0;
293          }
294        } while (root == null || root.GetSize() > maxSize || root.GetHeight() > maxHeight);
295        randomTrees[i] = root;
296      }
297      return randomTrees;
298    }
299
300    private void testButton_Click(object sender, EventArgs e) {
301      try {
302        Cursor = Cursors.WaitCursor;
303        outputTextBox.Text = TestFunctionLibrary();
304      }
305      finally {
306        Cursor = Cursors.Default;
307      }
308    }
309    #endregion
310
311    private void functionsListView_MouseUp(object sender, MouseEventArgs e) {
312      if (functionsListView.SelectedItems.Count > 0) {
313        IFunction selectedFun = (IFunction)functionsListView.SelectedItems[0].Tag;
314        Control funView = (Control)selectedFun.CreateView();
315        funView.Dock = DockStyle.Fill;
316        functionDetailsPanel.Controls.Clear();
317        functionDetailsPanel.Controls.Add(funView);
318      }
319    }
320  }
321}
Note: See TracBrowser for help on using the repository browser.