Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 16038 was 9395, checked in by fschoepp, 12 years ago

#1888:

  • Added visual extensions (dynamic JavaScript) which will be used to render additional result parameters specific to scenarios (e. g. create a graphical representation of a TSP).
  • Added relationship between jobs and experiments (otherwise, it's not possible to get the job's experiment).
  • Updated Admin page to allow removal/addition of visual extensions.
  • Added back-end logic to store/retrieve/delete visual extensions.
  • Added visual extension functionality to the JavaScript views/controllers (job.*.js).
  • Added tsp.js which is a visual extension for the "Genetic Algorithm - TSP" scenario. It adds a graphical representation of the TSP (just like the C# version does) to the results.
File size: 10.2 KB
RevLine 
[9215]1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Services.Optimization.ControllerService.Model;
6using Newtonsoft.Json.Linq;
[9227]7using Newtonsoft.Json;
[9215]8
9namespace HeuristicLab.Services.Optimization.ControllerService.Parsers {
10  public static class AlgorithmConverter {
[9305]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    }
[9215]34
[9305]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 } };
[9227]41    }
42
[9305]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) {
[9215]68      var algorithm = new Algorithm();
[9227]69
[9305]70      foreach (JObject param in jsonAlgorithm["AlgorithmParameters"]) {
[9215]71        Parameter parameter = CreateParameter(param);
72        algorithm.Parameters.Items.Add(parameter);
73      }
74
[9305]75      var problemParams = jsonAlgorithm["ProblemParameters"];
[9215]76      if (problemParams != null) {
77        algorithm.Problem = new Problem();
[9305]78        foreach (JObject param in problemParams) {
[9215]79          Parameter parameter = CreateParameter(param);
80          algorithm.Problem.Parameters.Items.Add(parameter);
81        }
82      }
83      return algorithm;
84    }
[9305]85    #endregion
[9215]86
87
[9305]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 });
[9215]111          }
112        }
113
114      }
[9305]115      return exp;
[9215]116    }
[9227]117
[9305]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;
[9227]123    }
124
[9305]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;
[9227]130    }
131
132
[9305]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;
[9227]138    }
139
[9305]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;
[9227]169    }
170
[9305]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;
[9227]184    }
185
[9324]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);
[9350]191      jrun["params"] = ConvertParametersToJson(run.InputParameters);
[9395]192      jrun["algorithmName"] = run.AlgorithmName;     
[9324]193      return jrun;
194    }
195
196    public static JArray ConvertRunsToJson(IList<Run> runs) {
197       var jarray = new JArray();
198      foreach (var run in runs)
199        jarray.Add(ConvertRunToJson(run));
[9350]200     
201     
202      // if there are multiple different jobs to execute and they have the same id, we must change it here manually
203      var maxId = new Dictionary<string,int>();
204      for (int i = 0; i < jarray.Count; i++) {
205        for (int j = i + 1; j < jarray.Count; j++) {
206          if (jarray[i]["id"].ToString() == jarray[j]["id"].ToString()) {
207            int max;
208            if (!maxId.TryGetValue(jarray[i]["id"].ToString(), out max)) {
209              max = 1;
210              maxId[jarray[i]["id"].ToString()] = max;             
211            }
212            maxId[jarray[i]["id"].ToString()]++;
213            // change j's entry
214            jarray[j]["id"] = jarray[j]["id"].ToString() + " (" + max + ")";
215            jarray[j]["name"] = jarray[j]["name"] + " (" + max + ")";
216          }
217        }
218      }
[9324]219      return jarray;
220    }
221
[9305]222    public static Experiment ConvertJsonToExperiment(string json) {
[9227]223      var experiment = new Experiment();
224      var jsonExperiment = JObject.Parse(json);
[9305]225      experiment.Name = (string)jsonExperiment["title"];
226      experiment.Id = (string)jsonExperiment["nodeId"];     
[9227]227      var stack = new Stack<StackEntry>();
228      var root = new Algorithm();
229
[9305]230      if (jsonExperiment["run"] != null && (bool)jsonExperiment["run"]) {
[9227]231        experiment.JobDetails = new JobExecutionDetails() {
[9305]232          Group = (string)jsonExperiment["group"],
233          Repititions = (int)jsonExperiment["repititions"]
[9227]234        };
235      }
236
[9305]237      // ignore experiment node, skip to its children
238      if (jsonExperiment["experiment"] != null)
239        foreach (var algo in jsonExperiment["experiment"]["children"]) {
240          stack.Push(new StackEntry() { Parent = root, Child = algo });
241        }
[9227]242
[9305]243      if (jsonExperiment["children"] != null)
244        foreach (var algo in jsonExperiment["children"]) {
245          stack.Push(new StackEntry() { Parent = root, Child = algo });
246        }
247
[9227]248      while (stack.Count > 0) {
249        var entry = stack.Pop();
250        var data = entry.Child["data"];
[9305]251        var currentAlgo = data == null || !data.HasValues ? new Algorithm() : ParseAlgorithm(entry.Child["data"]);
252        currentAlgo.Name = (string)entry.Child["title"];
253        currentAlgo.Id = (string)entry.Child["nodeId"];
254        currentAlgo.IsExperiment = (bool)entry.Child["isExperiment"];
[9227]255        entry.Parent.ChildAlgorithms.Add(currentAlgo);
256        // push children on stack (inverse order to preserve ordering)
257        var cnt = entry.Child["children"].Count();
[9305]258        for (var i = 0; i < cnt; i++) {
[9227]259          stack.Push(new StackEntry() { Parent = currentAlgo, Child = entry.Child["children"][cnt - 1 - i] });
260        }
261      }
262
263      foreach (var algo in root.ChildAlgorithms) {
264        experiment.Algorithm.Add(algo);
265      }
266
267      return experiment;
268    }
[9305]269    #endregion
[9215]270  }
271}
Note: See TracBrowser for help on using the repository browser.