source: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Parsers/AlgorithmConverter.cs @ 9324

Last change on this file since 9324 was 9324, checked in by fschoepp, 6 years ago

#1888:

  • DAL: Added a Delete method which deletes by experiment id.
  • HL DataTables will now be transposed and mapped as double[ROWS][COLUMNS] (transposed)
  • JS: Moved all classes into "modules" to prevent namespace pollution (using OAAS_MODEL for model classes, OAAS_VIEW for views and OAAS_CONTROLLER for controllers)
  • JS: Moved DatatypeMapper classes into Backbone views
  • JS: Models now correctly send DELETE requests
  • Added a new job overview page (which also renders run details) using AJAX
  • Using moment.min.js to format DateTime as string
  • Controllers now inherit from BaseController which provides a RedirectToLoginIfNecessary-method
  • Added loading animations to several AJAX bound places (loading experiments / scenarios)
  • Added a section to _Layout.cshtml which allows page-specific JavaScript includes (<script> only for a certain page)
  • Fixed Build/Edit of experiment menu redirecting to the wrong page
  • The Experiment Variation Dialog disables input fields, if the property has not been activated before
File size: 9.3 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Services.Optimization.ControllerService.Model;
6using Newtonsoft.Json.Linq;
7using Newtonsoft.Json;
8
9namespace HeuristicLab.Services.Optimization.ControllerService.Parsers {
10  public static class AlgorithmConverter {
11    #region private methods
12    private static Parameter CreateParameter(JObject property) {
13      var name = (string)property["Name"];
14      var value = property["Value"];
15      switch (value.Type) {
16        case JTokenType.Integer:
17        case JTokenType.Float:
18          return new Parameter() { Type = ParameterType.Decimal, Value = new DecimalValue() { Name = name, Value = (double)value } };
19        case JTokenType.Boolean:
20          return new Parameter() { Type = ParameterType.Boolean, Value = new BoolValue() { Name = name, Value = (bool)value } };
21        case JTokenType.String:
22          return new Parameter() { Type = ParameterType.Type, Value = new TypeValue() { Name = name, Value = (string)value, Options = (from e in property["Options"] select (string)e).ToArray() } };
23        case JTokenType.Array:
24          var arr = (JArray)value;
25          // its a matrix
26          if (arr[0].Type == JTokenType.Array) {
27            return CreateMatrixParameter(name, arr);
28          }
29          return CreateVectorParameter(name, arr);
30        default:
31          throw new Exception("Unhandled datatype: " + property.Type);
32      }
33    }
34
35    private static Parameter CreateMatrixParameter(string name, JArray arr) {
36      double[][] entries = new double[arr.Count][];
37      for (int i = 0; i < entries.Length; i++) {
38        entries[i] = (from d in arr[i] select (double)d).ToArray<double>();
39      }
40      return new Parameter { Type = ParameterType.DecimalMatrix, Value = new DecimalMatrix() { Name = name, Value = entries } };
41    }
42
43    private static Parameter CreateVectorParameter(string name, JArray arr) {
44      double[] entries = (from d in arr select (double)d).ToArray<double>();
45      return new Parameter { Type = ParameterType.DecimalVector, Value = new DecimalVector() { Name = name, Value = entries } };
46    }
47
48    private class StackEntry {
49      public Algorithm Parent { get; set; }
50      public JToken Child { get; set; }
51    }
52
53    private static JArray ConvertParametersToJson(IList<Parameter> parameters) {
54      var array = new JArray();
55      foreach (var param in parameters) {
56        array.Add(JObject.FromObject(param.Value));
57      }
58      return array;
59    }
60
61    private struct Entry {
62      public JObject TargetAlgorithm { get; set; }
63
64      public Algorithm SourceAlgorithm { get; set; }
65    }
66
67    private static Algorithm ParseAlgorithm(JToken jsonAlgorithm) {
68      var algorithm = new Algorithm();
69
70      foreach (JObject param in jsonAlgorithm["AlgorithmParameters"]) {
71        Parameter parameter = CreateParameter(param);
72        algorithm.Parameters.Items.Add(parameter);
73      }
74
75      var problemParams = jsonAlgorithm["ProblemParameters"];
76      if (problemParams != null) {
77        algorithm.Problem = new Problem();
78        foreach (JObject param in problemParams) {
79          Parameter parameter = CreateParameter(param);
80          algorithm.Problem.Parameters.Items.Add(parameter);
81        }
82      }
83      return algorithm;
84    }
85    #endregion
86
87
88    #region public methods
89
90
91    public static JObject ConvertExperimentToJson(Experiment experiment) {
92      var exp = new JObject();
93      exp["title"] = experiment.Name;
94      exp["children"] = new JArray();
95      exp["nodeId"] = experiment.Id;
96      exp["isExperiment"] = true;
97
98      var stack = new Stack<Entry>();
99      foreach (var algo in experiment.Algorithm)
100        stack.Push(new Entry() { TargetAlgorithm = exp, SourceAlgorithm = algo });
101
102      while (stack.Count > 0) {
103        var entry = stack.Pop();
104        var algorithm = ConvertAlgorithmToJson(entry.SourceAlgorithm);
105        (entry.TargetAlgorithm["children"] as JArray).Add(algorithm);
106
107        if (entry.SourceAlgorithm.ChildAlgorithms.Count > 0) {
108          // push children
109          foreach (var child in entry.SourceAlgorithm.ChildAlgorithms) {
110            stack.Push(new Entry() { TargetAlgorithm = algorithm, SourceAlgorithm = child });
111          }
112        }
113
114      }
115      return exp;
116    }
117
118    public static JArray ConvertExperimentsToJson(IEnumerable<Experiment> experiments) {
119      var jarray = new JArray();
120      foreach (var exp in experiments)
121        jarray.Add(ConvertExperimentToJson(exp));
122      return jarray;
123    }
124
125    public static JArray ConvertAlgorithmsToJson(IEnumerable<Algorithm> algorithms) {
126      var jarray = new JArray();
127      foreach (var algo in algorithms)
128        jarray.Add(ConvertAlgorithmToJson(algo));
129      return jarray;
130    }
131
132
133    public static JArray ConvertScenariosToJson(IEnumerable<OptimizationScenario> scenarios) {
134      var jarray = new JArray();
135      foreach (var scen in scenarios)
136        jarray.Add(ConvertScenarioToJson(scen));
137      return jarray;
138    }
139
140    public static JObject ConvertScenarioToJson(OptimizationScenario scenario) {
141      var exp = new JObject();
142      exp["title"] = scenario.Id;
143      exp["children"] = new JArray();
144      exp["nodeId"] = scenario.Id;
145      exp["isExperiment"] = false;
146
147      var stack = new Stack<Entry>();
148      var baseAlgorithm = ConvertAlgorithmToJson(scenario.FirstAlgorithm);
149      exp["data"] = baseAlgorithm["data"];
150      if (scenario.FirstAlgorithm.ChildAlgorithms.Count > 0) {
151        foreach (var child in scenario.FirstAlgorithm.ChildAlgorithms)
152          stack.Push(new Entry() { TargetAlgorithm = exp, SourceAlgorithm = child});
153      }
154
155      while (stack.Count > 0) {
156        var entry = stack.Pop();
157        var algorithm = ConvertAlgorithmToJson(entry.SourceAlgorithm);
158        (entry.TargetAlgorithm["children"] as JArray).Add(algorithm);
159
160        if (entry.SourceAlgorithm.ChildAlgorithms.Count > 0) {
161          // push children
162          foreach (var child in entry.SourceAlgorithm.ChildAlgorithms) {
163            stack.Push(new Entry() { TargetAlgorithm = algorithm, SourceAlgorithm = child });
164          }
165        }
166
167      }
168      return exp;
169    }
170
171    public static JObject ConvertAlgorithmToJson(Algorithm algorithm) {
172      var jalgo = new JObject();
173      jalgo["title"] = algorithm.Name;
174      jalgo["nodeId"] = algorithm.Id;
175      var jalgoData = new JObject();
176      jalgo["data"] = jalgoData;
177      jalgo["isExperiment"] = algorithm.IsExperiment;
178      jalgoData["AlgorithmParameters"] = ConvertParametersToJson(algorithm.Parameters.Items);
179      if (algorithm.Problem != null && algorithm.Problem.Parameters != null)
180        jalgoData["ProblemParameters"] = ConvertParametersToJson(algorithm.Problem.Parameters.Items);
181
182      jalgo["children"] = new JArray();
183      return jalgo;
184    }
185
186    public static JObject ConvertRunToJson(Run run) {
187      var jrun = new JObject();
188      jrun["id"] = run.Id;
189      jrun["name"] = run.Name;
190      jrun["results"] = ConvertParametersToJson(run.Results);
191      return jrun;
192    }
193
194    public static JArray ConvertRunsToJson(IList<Run> runs) {
195       var jarray = new JArray();
196      foreach (var run in runs)
197        jarray.Add(ConvertRunToJson(run));
198      return jarray;
199    }
200
201    public static Experiment ConvertJsonToExperiment(string json) {
202      var experiment = new Experiment();
203      var jsonExperiment = JObject.Parse(json);
204      experiment.Name = (string)jsonExperiment["title"];
205      experiment.Id = (string)jsonExperiment["nodeId"];     
206      var stack = new Stack<StackEntry>();
207      var root = new Algorithm();
208
209      if (jsonExperiment["run"] != null && (bool)jsonExperiment["run"]) {
210        experiment.JobDetails = new JobExecutionDetails() {
211          Group = (string)jsonExperiment["group"],
212          Repititions = (int)jsonExperiment["repititions"]
213        };
214      }
215
216      // ignore experiment node, skip to its children
217      if (jsonExperiment["experiment"] != null)
218        foreach (var algo in jsonExperiment["experiment"]["children"]) {
219          stack.Push(new StackEntry() { Parent = root, Child = algo });
220        }
221
222      if (jsonExperiment["children"] != null)
223        foreach (var algo in jsonExperiment["children"]) {
224          stack.Push(new StackEntry() { Parent = root, Child = algo });
225        }
226
227      while (stack.Count > 0) {
228        var entry = stack.Pop();
229        var data = entry.Child["data"];
230        var currentAlgo = data == null || !data.HasValues ? new Algorithm() : ParseAlgorithm(entry.Child["data"]);
231        currentAlgo.Name = (string)entry.Child["title"];
232        currentAlgo.Id = (string)entry.Child["nodeId"];
233        currentAlgo.IsExperiment = (bool)entry.Child["isExperiment"];
234        entry.Parent.ChildAlgorithms.Add(currentAlgo);
235        // push children on stack (inverse order to preserve ordering)
236        var cnt = entry.Child["children"].Count();
237        for (var i = 0; i < cnt; i++) {
238          stack.Push(new StackEntry() { Parent = currentAlgo, Child = entry.Child["children"][cnt - 1 - i] });
239        }
240      }
241
242      foreach (var algo in root.ChildAlgorithms) {
243        experiment.Algorithm.Add(algo);
244      }
245
246      return experiment;
247    }
248    #endregion
249  }
250}
Note: See TracBrowser for help on using the repository browser.