Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3026_IntegrationIntoSymSpace/HeuristicLab.JsonInterface/JCInstantiator.cs @ 17324

Last change on this file since 17324 was 17324, checked in by dpiringe, 5 years ago

#3026

  • added new project HeuristicLab.JsonInterface.App -> takes two arguments (template and config) to create an IOptimizer-Item, starts the run and writes the results to a file (currently hardcoded: C:\Workspace\test.txt)
  • made HeuristicLab.JsonInterface and HeuristicLab.JsonInterface.App to valid plugins
  • fixed a reference resolving bug with not-changeable parameters
File size: 6.8 KB
Line 
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.IO;
5using System.Linq;
6using System.Reflection;
7using System.Text;
8using System.Threading.Tasks;
9using HeuristicLab.Core;
10using HeuristicLab.Data;
11using HeuristicLab.Optimization;
12using HeuristicLab.SequentialEngine;
13using Newtonsoft.Json.Linq;
14
15namespace HeuristicLab.JsonInterface {
16  public class JCInstantiator {
17
18    private JToken Template { get; set; }
19    private JArray Config { get; set; }
20
21    private Dictionary<string, string> TypeList = new Dictionary<string, string>();
22    private IDictionary<string, JsonItem> ParameterizedItems { get; set; } = new Dictionary<string, JsonItem>();
23    private IDictionary<string, JsonItem> ConfigurableItems { get; set; } = new Dictionary<string, JsonItem>();
24   
25    public IAlgorithm Instantiate(string templateFile, string configFile) {
26
27      //1. Parse Template and Config files
28      Template = JToken.Parse(File.ReadAllText(templateFile));
29      Config = JArray.Parse(File.ReadAllText(configFile));
30      TypeList = Template[Constants.Types].ToObject<Dictionary<string, string>>();
31      string algorithmName = Template[Constants.Metadata][Constants.Algorithm].ToString();
32      string problemName = Template[Constants.Metadata][Constants.Problem].ToString();
33
34      //2. Collect all parameterizedItems from template
35      CollectParameterizedItems();
36
37      //3. select all ConfigurableItems
38      SelectConfigurableItems();
39
40      //4. Merge Template and Config
41      MergeTemplateWithConfig();
42
43      //5. resolve the references between parameterizedItems
44      ResolveReferences();
45
46      //6. get algorthm data and object
47      JsonItem algorithmData = GetData(algorithmName);
48      IAlgorithm algorithm = CreateObject<IAlgorithm>(algorithmData);
49
50      //7. get problem data and object
51      JsonItem problemData = GetData(problemName);
52     
53      IProblem problem = CreateObject<IProblem>(problemData);
54      algorithm.Problem = problem;
55
56      //8. inject configuration
57      JsonItemConverter.Inject(algorithm, algorithmData);
58      //JsonItemConverter.Inject(problem, problemData);
59
60      if (algorithm is EngineAlgorithm) {
61        algorithm.Cast<EngineAlgorithm>().Engine = new SequentialEngine.SequentialEngine();
62        File.WriteAllText(@"C:\Workspace\test2.txt", "test");
63      }
64
65      return algorithm;
66    }
67
68    private void CollectParameterizedItems() {
69      foreach (JObject item in Template[Constants.Objects]) {
70        JsonItem data = BuildJsonItem(item);
71        ParameterizedItems.Add(data.Path, data);
72      }
73    }
74
75    private void SelectConfigurableItems() {
76      foreach (var item in ParameterizedItems.Values) {
77        if (item.Parameters != null)
78          AddConfigurableItems(item.Parameters);
79
80        if (item.Operators != null)
81          AddConfigurableItems(item.Operators);
82      }
83    }
84
85    private void AddConfigurableItems(IEnumerable<JsonItem> items) {
86      foreach (var item in items)
87        if (item.IsConfigurable)
88          ConfigurableItems.Add(item.Path, item);
89    }
90
91    private void ResolveReferences() {
92      foreach(var x in ParameterizedItems.Values)
93        foreach (var p in x.Parameters)
94          if (p.Default is string) {
95            string key = p.Path;
96            if (p.Range != null)
97              key = $"{p.Path}.{p.Default.Cast<string>()}";
98
99            if (ParameterizedItems.TryGetValue(key, out JsonItem value))
100              p.Reference = value;
101          }
102    }
103
104    private void MergeTemplateWithConfig() {
105      foreach (JObject obj in Config) {
106        // build item from config object
107        JsonItem item = BuildJsonItem(obj);
108        // override default value
109        if (ConfigurableItems.TryGetValue(item.Path, out JsonItem param)) {
110          param.Default = item.Default;
111          // override default value of reference (for ValueLookupParameters)
112          if (param.Reference != null)
113            param.Reference.Default = item.Reference?.Default;
114        } else throw new InvalidDataException($"No {Constants.FreeParameters.Trim('s')} with path='{item.Path}' defined!");
115      }
116    }
117
118    private JsonItem GetData(string key)
119    {
120      if (ParameterizedItems.TryGetValue(key, out JsonItem value))
121        return value;
122      else
123        throw new InvalidDataException($"Type of item '{key}' is not defined!");
124    }
125
126    private T CreateObject<T>(JsonItem data) {
127      if (TypeList.TryGetValue(data.Name, out string typeName)) {
128        Type type = Type.GetType(typeName);
129        return (T)Activator.CreateInstance(type);
130      } else throw new TypeLoadException($"Cannot find AssemblyQualifiedName for {data.Name}.");
131    }
132
133    #region BuildJsonItemMethods
134    private JsonItem BuildJsonItem(JObject obj) =>
135      new JsonItem() {
136        Name = obj[nameof(JsonItem.Name)]?.ToString(),
137        Path = obj[nameof(JsonItem.Path)]?.ToString(),
138        Default = obj[nameof(JsonItem.Default)]?.ToObject<object>(),
139        Range = obj[nameof(JsonItem.Range)]?.ToObject<object[]>(),
140        Type = GetType(obj[nameof(JsonItem.Path)]?.ToObject<string>()),
141        Reference = obj[nameof(JsonItem.Type)] == null ?
142                    null :
143                    BuildJsonItem(obj[nameof(JsonItem.Type)].ToObject<JObject>()),
144        Parameters = PopulateParameters(obj),
145        Operators = PopulateOperators(obj)
146      };
147
148    private string GetType(string path) {
149      if(!string.IsNullOrEmpty(path))
150        if (TypeList.TryGetValue(path, out string value))
151          return value;
152      return null;
153    }
154
155    private IList<JsonItem> PopulateParameters(JObject obj) {
156      IList<JsonItem> list = new List<JsonItem>();
157
158      // add staticParameters
159      if (obj[Constants.StaticParameters] != null)
160        foreach (JObject param in obj[Constants.StaticParameters])
161          list.Add(BuildJsonItem(param));
162
163      // merge staticParameter with freeParameter
164      if (obj[Constants.FreeParameters] != null) {
165        foreach (JObject param in obj[Constants.FreeParameters]) {
166          JsonItem tmp = BuildJsonItem(param);
167         
168          // search staticParameter from list
169          JsonItem comp = null;
170          foreach (var p in list)
171            if (p.Name == tmp.Name) comp = p;
172          if (comp == null)
173            throw new InvalidDataException($"Invalid {Constants.FreeParameters.Trim('s')}: '{tmp.Name}'!");
174
175          JsonItem.Merge(comp, tmp);
176        }
177      }
178      return list;
179    }
180
181    private IList<JsonItem> PopulateOperators(JObject obj) {
182      IList<JsonItem> list = new List<JsonItem>();
183      JToken operators = obj[nameof(JsonItem.Operators)];
184      if (operators != null)
185        foreach (JObject sp in operators)
186          list.Add(BuildJsonItem(sp));
187      return list;
188    }
189    #endregion
190  }
191}
Note: See TracBrowser for help on using the repository browser.