1 | using System;
|
---|
2 | using System.Collections;
|
---|
3 | using System.Collections.Generic;
|
---|
4 | using System.IO;
|
---|
5 | using System.Linq;
|
---|
6 | using System.Reflection;
|
---|
7 | using System.Text;
|
---|
8 | using System.Threading.Tasks;
|
---|
9 | using HeuristicLab.Core;
|
---|
10 | using HeuristicLab.Data;
|
---|
11 | using HeuristicLab.Optimization;
|
---|
12 | using Newtonsoft.Json.Linq;
|
---|
13 |
|
---|
14 | namespace ParameterTest {
|
---|
15 |
|
---|
16 |
|
---|
17 | public class JCInstantiator {
|
---|
18 | //private Dictionary<string, JCProperty> Properties = new Dictionary<string, JCProperty>();
|
---|
19 | private Dictionary<string, string> TypeList = new Dictionary<string, string>();
|
---|
20 |
|
---|
21 | #region Constants
|
---|
22 | private const string SParametersID = "StaticParameters";
|
---|
23 | private const string FParametersID = "FreeParameters";
|
---|
24 | private const string TListID = "TypeList";
|
---|
25 | private const string AlgorithmID = "Algorithm";
|
---|
26 | private const string ProblemID = "Problem";
|
---|
27 | #endregion
|
---|
28 |
|
---|
29 | public IAlgorithm Instantiate(string configFile) {
|
---|
30 | JObject config = JObject.Parse(File.ReadAllText(configFile));
|
---|
31 |
|
---|
32 | TypeList = config[SParametersID][TListID].ToObject<Dictionary<string, string>>();
|
---|
33 |
|
---|
34 | JCObject algorithmData = config[SParametersID][AlgorithmID].ToObject<JCObject>();
|
---|
35 | JCObject problemData = config[SParametersID][ProblemID].ToObject<JCObject>();
|
---|
36 |
|
---|
37 | IAlgorithm algorithm = CreateTypeListObject<IAlgorithm>(algorithmData.Name);
|
---|
38 | algorithm.Problem = CreateTypeListObject<IProblem>(problemData.Name);
|
---|
39 |
|
---|
40 | ProcessParameters(algorithmData, algorithm);
|
---|
41 | ProcessParameters(problemData, algorithm.Problem);
|
---|
42 |
|
---|
43 | ParameterData[] freeAlgorithmParameters = config[FParametersID][algorithmData.Name].ToObject<ParameterData[]>();
|
---|
44 | ParameterData[] freeProblemParameters = config[FParametersID][problemData.Name].ToObject<ParameterData[]>();
|
---|
45 | UseFreeParams(algorithmData.Name, freeAlgorithmParameters, algorithm);
|
---|
46 | UseFreeParams(problemData.Name, freeProblemParameters, algorithm.Problem);
|
---|
47 | return algorithm;
|
---|
48 | }
|
---|
49 |
|
---|
50 | private T CreateTypeListObject<T>(string key) {
|
---|
51 | if (TypeList.TryGetValue(key, out string value)) {
|
---|
52 | Type type = Type.GetType(value);
|
---|
53 | return (T)Activator.CreateInstance(type);
|
---|
54 | } else throw new TypeLoadException($"The type '{key}' does not exists in TypeList.");
|
---|
55 | }
|
---|
56 |
|
---|
57 | private void ProcessParameters(JCObject obj, IParameterizedItem instance) {
|
---|
58 | foreach (var param in obj.Parameters)
|
---|
59 | if (param.Default != null)
|
---|
60 | SetParameterValue(FindPropertyByKey(instance, param.Name), param.Default);
|
---|
61 | }
|
---|
62 |
|
---|
63 | private void SetParameterValue (IParameter parameter, object value) {
|
---|
64 | if (Util.IsTypeOf(parameter, typeof(IFixedValueParameter<>))) return;
|
---|
65 | if (Util.IsTypeOf(parameter, typeof(IConstrainedValueParameter<>)))
|
---|
66 | SetCVParameter(parameter, value);
|
---|
67 | else if (Util.IsTypeOf(parameter.ActualValue, typeof(ValueTypeMatrix<>)))
|
---|
68 | SetVTMatrix(parameter, value);
|
---|
69 | else if (Util.IsTypeOf(parameter.ActualValue, typeof(ValueTypeArray<>)))
|
---|
70 | SetVTArray(parameter, value);
|
---|
71 | else if (Util.IsTypeOf(parameter.ActualValue, typeof(EnumValue<>)))
|
---|
72 | SetEnum(parameter, value);
|
---|
73 | else if (!(value is string))
|
---|
74 | SetValue(parameter, value);
|
---|
75 | else
|
---|
76 | SetNewInstance(parameter, value);
|
---|
77 | }
|
---|
78 | #region Helper for SetParameterValue
|
---|
79 | private void SetCVParameter(IParameter parameter, object value) {
|
---|
80 | foreach (var x in ((dynamic)parameter).ValidValues)
|
---|
81 | if (x.GetType().Name == (string)value)
|
---|
82 | parameter.ActualValue = x;
|
---|
83 | }
|
---|
84 |
|
---|
85 | private void SetVTMatrix(IParameter parameter, object value) {
|
---|
86 | var matrixType = ((dynamic)parameter.ActualValue).CloneAsMatrix().GetType();
|
---|
87 | var data = ((JToken)value).ToObject(matrixType);
|
---|
88 | parameter.ActualValue = (IItem)Activator.CreateInstance(parameter.ActualValue.GetType(), new object[] { data });
|
---|
89 | }
|
---|
90 |
|
---|
91 | private void SetVTArray(IParameter parameter, object value) {
|
---|
92 | var arrayType = ((dynamic)parameter.ActualValue).CloneAsArray().GetType();
|
---|
93 | var data = ((JToken)value).ToObject(arrayType);
|
---|
94 | parameter.ActualValue = (IItem)Activator.CreateInstance(parameter.ActualValue.GetType(), new object[] { data });
|
---|
95 | }
|
---|
96 |
|
---|
97 | private void SetEnum(IParameter parameter, object value) {
|
---|
98 | var enumType = ((dynamic)parameter.ActualValue).Value.GetType();
|
---|
99 | var data = Enum.Parse(enumType, (string)value);
|
---|
100 | ((dynamic)parameter.ActualValue).Value = data;
|
---|
101 | }
|
---|
102 |
|
---|
103 | private void SetValue(IParameter parameter, object value) {
|
---|
104 | var x = (dynamic)parameter.ActualValue;
|
---|
105 | if (value is IConvertible)
|
---|
106 | x.Value = Convert.ChangeType(value, x.Value.GetType());
|
---|
107 | else
|
---|
108 | x.Value = value;
|
---|
109 | }
|
---|
110 |
|
---|
111 | private void SetNewInstance(IParameter parameter, object value) =>
|
---|
112 | parameter.ActualValue = (IItem)Activator.CreateInstance(Type.GetType(TypeList[(string)value]));
|
---|
113 | #endregion
|
---|
114 |
|
---|
115 | private IParameter FindPropertyByKey(IParameterizedItem item, string key) {
|
---|
116 | if (item.Parameters.TryGetValue(key, out IParameter param))
|
---|
117 | return param;
|
---|
118 | else throw new KeyNotFoundException();
|
---|
119 | }
|
---|
120 |
|
---|
121 |
|
---|
122 | /*
|
---|
123 | JCProperty property = FindPropertyByPath(instance, param.Path);
|
---|
124 | property.Value = param.Default;
|
---|
125 | Properties.Add(obj.Name + "." + param.Name, property);
|
---|
126 |
|
---|
127 | private JCProperty FindPropertyByPath(object start, string path) {
|
---|
128 | string[] parts = path.Split('.');
|
---|
129 | object instance = start;
|
---|
130 | for (int i = 0; i < parts.Length - 1; ++i) {
|
---|
131 | if (parts[i].StartsWith("Parameters['")) {
|
---|
132 | IParameterizedItem pItem = (IParameterizedItem)instance;
|
---|
133 | string tmp = parts[i].Replace("Parameters['", "").Replace("']", "");
|
---|
134 | if (pItem.Parameters.ContainsKey(tmp))
|
---|
135 | instance = pItem.Parameters[tmp];
|
---|
136 | } else {
|
---|
137 | PropertyInfo propInfo = instance.GetType().GetProperty(parts[i]);
|
---|
138 | instance = propInfo.GetValue(instance);
|
---|
139 | }
|
---|
140 | }
|
---|
141 | return new JCProperty(instance.GetType().GetProperty(parts[parts.Length - 1]), instance, TypeList);
|
---|
142 | }
|
---|
143 | */
|
---|
144 | private bool IsInRangeList(IEnumerable<object> list, object value) {
|
---|
145 | foreach (var x in list)
|
---|
146 | if (x.Equals(value)) return true;
|
---|
147 | return false;
|
---|
148 | }
|
---|
149 |
|
---|
150 | private void UseFreeParams(string root, ParameterData[] parameters, IParameterizedItem instance) {
|
---|
151 | foreach (var param in parameters) {
|
---|
152 | string key = $"{root}.{param.Name}";
|
---|
153 | if((param.Range == null && param.Default != null) ||
|
---|
154 | (param.Range != null && IsInRangeList(param.Range, param.Default)) ||
|
---|
155 | IsInNumericRange<long>(param.Default, param.Range[0], param.Range[1]) ||
|
---|
156 | IsInNumericRange<double>(param.Default, param.Range[0], param.Range[1]))
|
---|
157 | SetParameterValue(FindPropertyByKey(instance, param.Name), param.Default);
|
---|
158 | //Properties[key].Value = param.Default;
|
---|
159 | else
|
---|
160 | throw new ArgumentOutOfRangeException(key);
|
---|
161 | }
|
---|
162 | }
|
---|
163 |
|
---|
164 | private bool IsInNumericRange<T>(object value, object min, object max) where T : IComparable =>
|
---|
165 | (value != null && min != null && max != null && value is T && min is T && max is T &&
|
---|
166 | (((T)min).CompareTo(value) == -1 || ((T)min).CompareTo(value) == 0) &&
|
---|
167 | (((T)max).CompareTo(value) == 1 || ((T)max).CompareTo(value) == 0));
|
---|
168 | }
|
---|
169 | }
|
---|