1 | #region License Information
|
---|
2 |
|
---|
3 | /* HeuristicLab
|
---|
4 | * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
|
---|
5 | *
|
---|
6 | * This file is part of HeuristicLab.
|
---|
7 | *
|
---|
8 | * HeuristicLab is free software: you can redistribute it and/or modify
|
---|
9 | * it under the terms of the GNU General Public License as published by
|
---|
10 | * the Free Software Foundation, either version 3 of the License, or
|
---|
11 | * (at your option) any later version.
|
---|
12 | *
|
---|
13 | * HeuristicLab is distributed in the hope that it will be useful,
|
---|
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
16 | * GNU General Public License for more details.
|
---|
17 | *
|
---|
18 | * You should have received a copy of the GNU General Public License
|
---|
19 | * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
|
---|
20 | */
|
---|
21 |
|
---|
22 | #endregion
|
---|
23 |
|
---|
24 | using System;
|
---|
25 | using System.Drawing;
|
---|
26 | using System.Text;
|
---|
27 | using System.Windows.Forms;
|
---|
28 | using HeuristicLab.Collections;
|
---|
29 | using HeuristicLab.MainForm;
|
---|
30 | using HeuristicLab.MainForm.WindowsForms;
|
---|
31 |
|
---|
32 | namespace HeuristicLab.Problems.DataAnalysis.Views {
|
---|
33 | [View("ShapeConstraints View")]
|
---|
34 | [Content(typeof(ShapeConstraints), true)]
|
---|
35 | public partial class ShapeConstraintsView : AsynchronousContentView {
|
---|
36 | public new ShapeConstraints Content {
|
---|
37 | get => (ShapeConstraints)base.Content;
|
---|
38 | set => base.Content = value;
|
---|
39 | }
|
---|
40 |
|
---|
41 | public bool suspendUpdates = false;
|
---|
42 |
|
---|
43 | public ShapeConstraintsView() {
|
---|
44 | InitializeComponent();
|
---|
45 | errorOutput.Text = "";
|
---|
46 | }
|
---|
47 |
|
---|
48 | protected override void OnContentChanged() {
|
---|
49 | base.OnContentChanged();
|
---|
50 | this.intervalConstraintsView.Content = Content;
|
---|
51 | UpdateControl();
|
---|
52 | }
|
---|
53 |
|
---|
54 | protected override void RegisterContentEvents() {
|
---|
55 | base.RegisterContentEvents();
|
---|
56 | Content.ItemsAdded += constraints_Added;
|
---|
57 | Content.ItemsRemoved += constraint_Removed;
|
---|
58 | Content.Changed += Content_Changed;
|
---|
59 | Content.CollectionReset += constraints_Reset;
|
---|
60 | Content.ItemsMoved += constraints_Moved;
|
---|
61 | Content.ItemsReplaced += Content_ItemsReplaced;
|
---|
62 | Content.CheckedItemsChanged += Content_CheckedItemsChanged;
|
---|
63 | }
|
---|
64 |
|
---|
65 |
|
---|
66 | protected override void DeregisterContentEvents() {
|
---|
67 | Content.ItemsAdded -= constraints_Added;
|
---|
68 | Content.ItemsRemoved -= constraint_Removed;
|
---|
69 | Content.Changed -= Content_Changed;
|
---|
70 | Content.CollectionReset -= constraints_Reset;
|
---|
71 | Content.ItemsMoved -= constraints_Moved;
|
---|
72 | Content.ItemsReplaced -= Content_ItemsReplaced;
|
---|
73 | Content.CheckedItemsChanged -= Content_CheckedItemsChanged;
|
---|
74 | base.DeregisterContentEvents();
|
---|
75 | }
|
---|
76 |
|
---|
77 | protected override void SetEnabledStateOfControls() {
|
---|
78 | constraintsInput.Enabled = Content != null && !Locked && !ReadOnly;
|
---|
79 | }
|
---|
80 |
|
---|
81 |
|
---|
82 | private void parseBtn_Click(object sender, EventArgs e) {
|
---|
83 | if (constraintsInput.Text != null) {
|
---|
84 | suspendUpdates = true;
|
---|
85 | Content.Clear();
|
---|
86 | try {
|
---|
87 | var parsedConstraints = ShapeConstraintsParser.ParseConstraints(constraintsInput.Text);
|
---|
88 | Content = parsedConstraints;
|
---|
89 | errorOutput.Text = "Constraints successfully parsed.";
|
---|
90 | errorOutput.ForeColor = Color.DarkGreen;
|
---|
91 | //Catch the exception from the constraints parser and show it in the error dialog
|
---|
92 | } catch (ArgumentException ex) {
|
---|
93 | Content.Clear();
|
---|
94 | errorOutput.Text = ex.Message.Replace("Parameter name", "@Line");
|
---|
95 | errorOutput.ForeColor = Color.DarkRed;
|
---|
96 | }
|
---|
97 | suspendUpdates = false;
|
---|
98 | UpdateControl();
|
---|
99 | } else {
|
---|
100 | errorOutput.Text = "No constraints were found!";
|
---|
101 | }
|
---|
102 | }
|
---|
103 |
|
---|
104 | private void UpdateControl() {
|
---|
105 | if (suspendUpdates) return;
|
---|
106 | if (Content == null) {
|
---|
107 | constraintsInput.Text = string.Empty;
|
---|
108 | } else {
|
---|
109 | this.intervalConstraintsView.Content = Content;
|
---|
110 | constraintsInput.Text = ToString(Content);
|
---|
111 | }
|
---|
112 | }
|
---|
113 |
|
---|
114 | private string ToString(ShapeConstraints constraints) {
|
---|
115 | var sb = new StringBuilder();
|
---|
116 | foreach (var constraint in constraints) {
|
---|
117 | if (!constraints.ItemChecked(constraint)) {
|
---|
118 | sb.Append("# ").AppendLine(constraint.ToString());
|
---|
119 | } else {
|
---|
120 | sb.AppendLine(constraint.ToString());
|
---|
121 | }
|
---|
122 | }
|
---|
123 | return sb.ToString();
|
---|
124 | }
|
---|
125 |
|
---|
126 | private void constraint_Changed(object sender, EventArgs e) {
|
---|
127 | UpdateControl();
|
---|
128 | }
|
---|
129 |
|
---|
130 | private void constraints_Added(object sender,
|
---|
131 | CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) {
|
---|
132 | foreach (var addedItem in e.Items) addedItem.Value.Changed += constraint_Changed;
|
---|
133 | UpdateControl();
|
---|
134 | }
|
---|
135 |
|
---|
136 | private void constraint_Removed(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) {
|
---|
137 | foreach (var removedItem in e.Items) removedItem.Value.Changed -= constraint_Changed;
|
---|
138 | UpdateControl();
|
---|
139 | }
|
---|
140 |
|
---|
141 | private void constraints_Moved(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) {
|
---|
142 | UpdateControl();
|
---|
143 | }
|
---|
144 |
|
---|
145 | private void constraints_Reset(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) {
|
---|
146 | foreach (var addedItem in e.Items) addedItem.Value.Changed += constraint_Changed;
|
---|
147 | foreach (var removedItem in e.OldItems) removedItem.Value.Changed -= constraint_Changed;
|
---|
148 | UpdateControl();
|
---|
149 | }
|
---|
150 |
|
---|
151 | private void Content_CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) {
|
---|
152 | UpdateControl();
|
---|
153 | }
|
---|
154 |
|
---|
155 | private void Content_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<ShapeConstraint>> e) {
|
---|
156 | foreach (var addedItem in e.Items) addedItem.Value.Changed += constraint_Changed;
|
---|
157 | foreach (var removedItem in e.OldItems) removedItem.Value.Changed -= constraint_Changed;
|
---|
158 | UpdateControl();
|
---|
159 | }
|
---|
160 |
|
---|
161 | private void constraintsInput_TextChanged(object sender, EventArgs e) {
|
---|
162 | errorOutput.Text = "Unparsed changes! Press parse button to save changes.";
|
---|
163 | errorOutput.ForeColor = Color.DarkOrange;
|
---|
164 | }
|
---|
165 |
|
---|
166 | private void Content_Changed(object sender, EventArgs e) {
|
---|
167 | UpdateControl();
|
---|
168 | }
|
---|
169 |
|
---|
170 | private void label1_DoubleClick(object sender, EventArgs e) {
|
---|
171 | var infoText =
|
---|
172 | "Within the text field you can define different types of shape constraints e.g. range constraints, monotonicity constraints, ..." +
|
---|
173 | System.Environment.NewLine +
|
---|
174 | "To define a model constraint: f in [0 .. 100], f is used for the selected target, the 'in' key word specifies the target in which the constraint should be, the interval is defined between square bracket." +
|
---|
175 | System.Environment.NewLine +
|
---|
176 | "The interval contains two bounds (lower and upper) this bounds are given as double values, to seperate both bounds from each other you can use (.., ;, ' ')" +
|
---|
177 | System.Environment.NewLine +
|
---|
178 | "To define monotonic or concave constraints you need to define the partial derivatives:" +
|
---|
179 | System.Environment.NewLine +
|
---|
180 | "∂f/∂x in [0 .. 1], therefore you have to define the partial fraction first, which can be done by using the \\partial symbol or 'd' followed by the target and the variable in the numerator and denominator respectively, after defining the fraction the interval is defined like in the model constraint." +
|
---|
181 | System.Environment.NewLine +
|
---|
182 | "To define constraints only on a specific range of the function you can define interval ranges" +
|
---|
183 | System.Environment.NewLine +
|
---|
184 | "f in [0 .. 100], x in [0 .. 1] the ranges are separated by commas and follow the same rules as before (giving the variable with the interval definition)" +
|
---|
185 | System.Environment.NewLine + "To specify different weights on the constraints:" +
|
---|
186 | System.Environment.NewLine + "f in [0 .. 100], x in [0 .. 1] weight: 2.0, you can add the keyword 'weight:' followed by a double value.";
|
---|
187 |
|
---|
188 | MessageBox.Show(infoText,"How to define shape constraints", MessageBoxButtons.OKCancel);
|
---|
189 | }
|
---|
190 | }
|
---|
191 | } |
---|