Changeset 13180
- Timestamp:
- 11/16/15 16:45:17 (9 years ago)
- Location:
- trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.4
- Files:
-
- 1 added
- 4 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.4/EvaluationCache.cs ¶
r12012 r13180 30 30 using System.Text.RegularExpressions; 31 31 using System.Threading; 32 using Google.ProtocolBuffers; 32 33 using HeuristicLab.Common; 33 34 using HeuristicLab.Common.Resources; … … 47 48 48 49 public readonly string Key; 49 public double Value; 50 51 public CacheEntry(string key, double value) { 52 Key = key; 53 Value = value; 50 51 private QualityMessage message; 52 private byte[] rawMessage; 53 54 public byte[] RawMessage { 55 get { return rawMessage; } 56 set { 57 rawMessage = value; 58 message = null; 59 } 54 60 } 55 61 56 62 public CacheEntry(string key) { 57 63 Key = key; 64 } 65 66 public QualityMessage GetMessage(ExtensionRegistry extensions) { 67 if (message == null && rawMessage != null) 68 message = QualityMessage.ParseFrom(ByteString.CopyFrom(rawMessage), extensions); 69 return message; 70 } 71 public void SetMessage(QualityMessage value) { 72 message = value; 73 rawMessage = value.ToByteArray(); 58 74 } 59 75 … … 69 85 } 70 86 87 public string QualityString(IFormatProvider formatProvider = null) { 88 if (formatProvider == null) formatProvider = CultureInfo.CurrentCulture; 89 if (RawMessage == null) return "-"; 90 var msg = message ?? CreateBasicQualityMessage(); 91 switch (msg.Type) { 92 case QualityMessage.Types.Type.SingleObjectiveQualityMessage: 93 return msg.GetExtension(SingleObjectiveQualityMessage.QualityMessage_).Quality.ToString(formatProvider); 94 case QualityMessage.Types.Type.MultiObjectiveQualityMessage: 95 var qualities = msg.GetExtension(MultiObjectiveQualityMessage.QualityMessage_).QualitiesList; 96 return string.Format("[{0}]", string.Join(",", qualities.Select(q => q.ToString(formatProvider)))); 97 default: 98 return "-"; 99 } 100 } 101 private QualityMessage CreateBasicQualityMessage() { 102 var extensions = ExtensionRegistry.CreateInstance(); 103 ExternalEvaluationMessages.RegisterAllExtensions(extensions); 104 return QualityMessage.ParseFrom(ByteString.CopyFrom(rawMessage), extensions); 105 } 106 71 107 public override string ToString() { 72 return string.Format("{{{0} : {1}}}", Key, Value);73 } 74 } 75 76 public delegate double Evaluator(SolutionMessage message);108 return string.Format("{{{0} : {1}}}", Key, QualityString()); 109 } 110 } 111 112 public delegate QualityMessage Evaluator(SolutionMessage message); 77 113 #endregion 78 114 … … 126 162 127 163 #region Persistence 164 #region BackwardsCompatibility3.4 128 165 [Storable(Name = "Cache")] 129 166 private IEnumerable<KeyValuePair<string, double>> Cache_Persistence { 130 get { 131 if (IsPersistent) { 132 return GetCacheValues(); 133 } else { 134 return Enumerable.Empty<KeyValuePair<string, double>>(); 135 } 136 } 167 get { return Enumerable.Empty<KeyValuePair<string, double>>(); } 137 168 set { 138 SetCacheValues(value); 139 } 169 var rawMessages = value.ToDictionary(kvp => kvp.Key, 170 kvp => QualityMessage.CreateBuilder() 171 .SetSolutionId(0) 172 .SetExtension( 173 SingleObjectiveQualityMessage.QualityMessage_, 174 SingleObjectiveQualityMessage.CreateBuilder().SetQuality(kvp.Value).Build()) 175 .Build().ToByteArray()); 176 SetCacheValues(rawMessages); 177 } 178 } 179 #endregion 180 [Storable(Name = "CacheNew")] 181 private IEnumerable<KeyValuePair<string, byte[]>> CacheNew_Persistence { 182 get { return IsPersistent ? GetCacheValues() : Enumerable.Empty<KeyValuePair<string, byte[]>>(); } 183 set { SetCacheValues(value); } 140 184 } 141 185 [StorableHook(HookType.AfterDeserialization)] … … 149 193 protected EvaluationCache(bool deserializing) : base(deserializing) { } 150 194 protected EvaluationCache(EvaluationCache original, Cloner cloner) 151 : base(original, cloner) {195 : base(original, cloner) { 152 196 SetCacheValues(original.GetCacheValues()); 153 197 Hits = original.Hits; … … 190 234 } 191 235 192 public double GetValue(SolutionMessage message, Evaluator evaluate) {236 public QualityMessage GetValue(SolutionMessage message, Evaluator evaluate, ExtensionRegistry extensions) { 193 237 var entry = new CacheEntry(message.ToString()); 194 238 bool lockTaken = false; … … 205 249 Monitor.Exit(cacheLock); 206 250 OnChanged(); 207 return node.Value. Value;251 return node.Value.GetMessage(extensions); 208 252 } else { 209 253 if (!waited && activeEvaluations.Contains(entry.Key)) { … … 217 261 OnChanged(); 218 262 try { 219 entry. Value = evaluate(message);263 entry.SetMessage(evaluate(message)); 220 264 Monitor.Enter(cacheLock, ref lockTaken); 221 265 index[entry] = list.AddLast(entry); 222 266 Trim(); 223 } 224 finally { 267 } finally { 225 268 if (!lockTaken) 226 269 Monitor.Enter(cacheLock, ref lockTaken); … … 231 274 } 232 275 OnChanged(); 233 return entry. Value;276 return entry.GetMessage(extensions); 234 277 } 235 278 } 236 279 } 237 } 238 finally { 280 } finally { 239 281 if (lockTaken) 240 282 Monitor.Exit(cacheLock); … … 250 292 } 251 293 252 private IEnumerable<KeyValuePair<string, double>> GetCacheValues() {294 private IEnumerable<KeyValuePair<string, byte[]>> GetCacheValues() { 253 295 lock (cacheLock) { 254 return index.ToDictionary(kvp => kvp.Key.Key, kvp => kvp.Key. Value);255 } 256 } 257 258 private void SetCacheValues(IEnumerable<KeyValuePair<string, double>> value) {296 return index.ToDictionary(kvp => kvp.Key.Key, kvp => kvp.Key.RawMessage); 297 } 298 } 299 300 private void SetCacheValues(IEnumerable<KeyValuePair<string, byte[]>> value) { 259 301 lock (cacheLock) { 260 list = new LinkedList<CacheEntry>();261 i ndex = new Dictionary<CacheEntry, LinkedListNode<CacheEntry>>();302 if (list == null) list = new LinkedList<CacheEntry>(); 303 if (index == null) index = new Dictionary<CacheEntry, LinkedListNode<CacheEntry>>(); 262 304 foreach (var kvp in value) { 263 var entry = new CacheEntry(kvp.Key) { Value = kvp.Value };305 var entry = new CacheEntry(kvp.Key) { RawMessage = kvp.Value }; 264 306 index[entry] = list.AddLast(entry); 265 307 } … … 274 316 "\"{0}\", {1}", 275 317 Regex.Replace(entry.Key, "\\s", "").Replace("\"", "\"\""), 276 entry. Value));318 entry.QualityString(CultureInfo.InvariantCulture))); 277 319 } 278 320 } -
TabularUnified trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.4/ExternalEvaluationProblem.cs ¶
r13131 r13180 38 38 [Creatable(CreatableAttribute.Categories.ExternalEvaluationProblems, Priority = 100)] 39 39 [StorableClass] 40 public class ExternalEvaluationProblem : SingleObjectiveBasicProblem<IEncoding> {40 public class ExternalEvaluationProblem : SingleObjectiveBasicProblem<IEncoding>, IExternalEvaluationProblem { 41 41 42 42 public static new Image StaticItemImage { … … 89 89 Parameters.Add(new OptionalValueParameter<EvaluationCache>("Cache", "Cache of previously evaluated solutions.")); 90 90 Parameters.Add(new ValueParameter<CheckedItemCollection<IEvaluationServiceClient>>("Clients", "The clients that are used to communicate with the external application.", new CheckedItemCollection<IEvaluationServiceClient>() { new EvaluationServiceClient() })); 91 Parameters.Add(new ValueParameter<SolutionMessageBuilder>("MessageBuilder", "The message builder that converts from HeuristicLab objects to SolutionMessage representation.", new SolutionMessageBuilder()) );91 Parameters.Add(new ValueParameter<SolutionMessageBuilder>("MessageBuilder", "The message builder that converts from HeuristicLab objects to SolutionMessage representation.", new SolutionMessageBuilder()) { Hidden = true }); 92 92 Parameters.Add(new FixedValueParameter<SingleObjectiveOptimizationSupportScript>("SupportScript", "A script that can provide neighborhood and analyze the results of the optimization.", new SingleObjectiveOptimizationSupportScript())); 93 93 … … 101 101 102 102 public override double Evaluate(Individual individual, IRandom random) { 103 return Cache == null ? EvaluateOnNextAvailableClient(BuildSolutionMessage(individual)).Quality 104 : Cache.GetValue(BuildSolutionMessage(individual), m => EvaluateOnNextAvailableClient(m).Quality); 103 var qualityMessage = Evaluate(BuildSolutionMessage(individual)); 104 if (!qualityMessage.HasExtension(SingleObjectiveQualityMessage.QualityMessage_)) 105 throw new InvalidOperationException("The received message is not a SingleObjectiveQualityMessage."); 106 return qualityMessage.GetExtension(SingleObjectiveQualityMessage.QualityMessage_).Quality; 107 } 108 public virtual QualityMessage Evaluate(SolutionMessage solutionMessage) { 109 return Cache == null 110 ? EvaluateOnNextAvailableClient(solutionMessage) 111 : Cache.GetValue(solutionMessage, EvaluateOnNextAvailableClient, GetQualityMessageExtensions()); 105 112 } 106 113 … … 114 121 #endregion 115 122 116 #region Evaluation Helpers 123 public virtual ExtensionRegistry GetQualityMessageExtensions() { 124 var extensions = ExtensionRegistry.CreateInstance(); 125 extensions.Add(SingleObjectiveQualityMessage.QualityMessage_); 126 return extensions; 127 } 128 129 #region Evaluation 117 130 private HashSet<IEvaluationServiceClient> activeClients = new HashSet<IEvaluationServiceClient>(); 118 131 private object clientLock = new object(); 132 119 133 private QualityMessage EvaluateOnNextAvailableClient(SolutionMessage message) { 120 134 IEvaluationServiceClient client = null; … … 130 144 try { 131 145 return client.Evaluate(message, GetQualityMessageExtensions()); 132 } 133 finally { 146 } finally { 134 147 lock (clientLock) { 135 148 activeClients.Remove(client); … … 139 152 } 140 153 141 protected virtual ExtensionRegistry GetQualityMessageExtensions() { 142 return ExtensionRegistry.CreateInstance(); 143 } 144 145 private SolutionMessage BuildSolutionMessage(Individual individual) { 154 private SolutionMessage BuildSolutionMessage(Individual individual, int solutionId = 0) { 146 155 lock (clientLock) { 147 156 SolutionMessage.Builder protobufBuilder = SolutionMessage.CreateBuilder(); 148 protobufBuilder.SolutionId = 0;157 protobufBuilder.SolutionId = solutionId; 149 158 var scope = new Scope(); 150 159 individual.CopyToScope(scope); … … 152 161 try { 153 162 MessageBuilder.AddToMessage(variable.Value, variable.Name, protobufBuilder); 154 } 155 catch (ArgumentException ex) { 156 throw new InvalidOperationException(string.Format("ERROR while building solution message: Parameter {0} cannot be added to the message", name), ex); 163 } catch (ArgumentException ex) { 164 throw new InvalidOperationException(string.Format("ERROR while building solution message: Parameter {0} cannot be added to the message", Name), ex); 157 165 } 158 166 } -
TabularUnified trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.4/HeuristicLab.Problems.ExternalEvaluation-3.4.csproj ¶
r11961 r13180 134 134 <Compile Include="Drivers\EvaluationStreamChannel.cs" /> 135 135 <Compile Include="Drivers\EvaluationTCPChannel.cs" /> 136 <Compile Include="Interfaces\IExternalEvaluationProblem.cs" /> 137 <Compile Include="MultiObjectiveExternalEvaluationProblem.cs" /> 136 138 <Compile Include="ExternalEvaluationProblem.cs" /> 137 139 <Compile Include="Interfaces\IEvaluationServiceClient.cs" /> -
TabularUnified trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.4/MultiObjectiveExternalEvaluationProblem.cs ¶
r13131 r13180 26 26 using System.Threading; 27 27 using Google.ProtocolBuffers; 28 using HeuristicLab.Analysis;29 28 using HeuristicLab.Common; 30 29 using HeuristicLab.Core; … … 35 34 36 35 namespace HeuristicLab.Problems.ExternalEvaluation { 37 [Item(" External Evaluation Problem", "Aproblem that is evaluated in a different process.")]38 [Creatable(CreatableAttribute.Categories.ExternalEvaluationProblems, Priority = 100)]36 [Item("Multi Objective External Evaluation Problem", "A multi-objective problem that is evaluated in a different process.")] 37 [Creatable(CreatableAttribute.Categories.ExternalEvaluationProblems, Priority = 200)] 39 38 [StorableClass] 40 public class ExternalEvaluationProblem : SingleObjectiveBasicProblem<IEncoding>{39 public class MultiObjectiveExternalEvaluationProblem : MultiObjectiveBasicProblem<IEncoding>, IExternalEvaluationProblem { 41 40 42 41 public static new Image StaticItemImage { … … 54 53 get { return (IValueParameter<SolutionMessageBuilder>)Parameters["MessageBuilder"]; } 55 54 } 56 public IFixedValueParameter<SingleObjectiveOptimizationSupportScript> SupportScriptParameter {57 get { return (IFixedValueParameter<SingleObjectiveOptimizationSupportScript>)Parameters["SupportScript"]; }58 }55 //public IFixedValueParameter<MultiObjectiveOptimizationSupportScript> SupportScriptParameter { 56 // get { return (IFixedValueParameter<MultiObjectiveOptimizationSupportScript>)Parameters["SupportScript"]; } 57 //} 59 58 #endregion 60 59 … … 69 68 get { return MessageBuilderParameter.Value; } 70 69 } 71 public SingleObjectiveOptimizationSupportScript OptimizationSupportScript {72 get { return SupportScriptParameter.Value; }73 }74 private ISingleObjectiveOptimizationSupport OptimizationSupport {75 get { return SupportScriptParameter.Value; }76 }70 //public MultiObjectiveOptimizationSupportScript OptimizationSupportScript { 71 // get { return SupportScriptParameter.Value; } 72 //} 73 //private IMultiObjectiveOptimizationSupport OptimizationSupport { 74 // get { return SupportScriptParameter.Value; } 75 //} 77 76 #endregion 78 77 79 78 [StorableConstructor] 80 protected ExternalEvaluationProblem(bool deserializing) : base(deserializing) { }81 protected ExternalEvaluationProblem(ExternalEvaluationProblem original, Cloner cloner) : base(original, cloner) { }79 protected MultiObjectiveExternalEvaluationProblem(bool deserializing) : base(deserializing) { } 80 protected MultiObjectiveExternalEvaluationProblem(MultiObjectiveExternalEvaluationProblem original, Cloner cloner) : base(original, cloner) { } 82 81 public override IDeepCloneable Clone(Cloner cloner) { 83 return new ExternalEvaluationProblem(this, cloner);82 return new MultiObjectiveExternalEvaluationProblem(this, cloner); 84 83 } 85 public ExternalEvaluationProblem()84 public MultiObjectiveExternalEvaluationProblem() 86 85 : base() { 87 86 Parameters.Remove("Maximization"); // readonly in base class 88 Parameters.Add(new FixedValueParameter<Bool Value>("Maximization", "Set to false if the problem should be minimized.", new BoolValue()));87 Parameters.Add(new FixedValueParameter<BoolArray>("Maximization", "Set to false if the problem should be minimized.", new BoolArray())); 89 88 Parameters.Add(new OptionalValueParameter<EvaluationCache>("Cache", "Cache of previously evaluated solutions.")); 90 89 Parameters.Add(new ValueParameter<CheckedItemCollection<IEvaluationServiceClient>>("Clients", "The clients that are used to communicate with the external application.", new CheckedItemCollection<IEvaluationServiceClient>() { new EvaluationServiceClient() })); 91 Parameters.Add(new ValueParameter<SolutionMessageBuilder>("MessageBuilder", "The message builder that converts from HeuristicLab objects to SolutionMessage representation.", new SolutionMessageBuilder()) );92 Parameters.Add(new FixedValueParameter<SingleObjectiveOptimizationSupportScript>("SupportScript", "A script that can provide neighborhood and analyze the results of the optimization.", new SingleObjectiveOptimizationSupportScript()));90 Parameters.Add(new ValueParameter<SolutionMessageBuilder>("MessageBuilder", "The message builder that converts from HeuristicLab objects to SolutionMessage representation.", new SolutionMessageBuilder()) { Hidden = true }); 91 //Parameters.Add(new FixedValueParameter<MultiObjectiveOptimizationSupportScript>("SupportScript", "A script that can analyze the results of the optimization.", new MultiObjectiveOptimizationSupportScript())); 93 92 94 Operators.Add(new BestScopeSolutionAnalyzer());93 //Operators.Add(new BestScopeSolutionAnalyzer()); pareto front 95 94 } 96 95 97 #region Single Objective Problem Overrides 98 public override bool Maximization { 99 get { return Parameters.ContainsKey("Maximization") && ((IValueParameter<BoolValue>)Parameters["Maximization"]).Value.Value; } 96 #region Multi Objective Problem Overrides 97 public override bool[] Maximization { 98 get { 99 return Parameters.ContainsKey("Maximization") ? ((IValueParameter<BoolArray>)Parameters["Maximization"]).Value.ToArray() : new bool[0]; 100 } 100 101 } 101 102 102 public override double Evaluate(Individual individual, IRandom random) { 103 return Cache == null ? EvaluateOnNextAvailableClient(BuildSolutionMessage(individual)).Quality 104 : Cache.GetValue(BuildSolutionMessage(individual), m => EvaluateOnNextAvailableClient(m).Quality); 103 public override double[] Evaluate(Individual individual, IRandom random) { 104 var qualityMessage = Evaluate(BuildSolutionMessage(individual)); 105 if (!qualityMessage.HasExtension(MultiObjectiveQualityMessage.QualityMessage_)) 106 throw new InvalidOperationException("The received message is not a MultiObjectiveQualityMessage."); 107 return qualityMessage.GetExtension(MultiObjectiveQualityMessage.QualityMessage_).QualitiesList.ToArray(); 108 } 109 public virtual QualityMessage Evaluate(SolutionMessage solutionMessage) { 110 return Cache == null 111 ? EvaluateOnNextAvailableClient(solutionMessage) 112 : Cache.GetValue(solutionMessage, EvaluateOnNextAvailableClient, GetQualityMessageExtensions()); 105 113 } 106 114 107 public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {108 OptimizationSupport.Analyze(individuals, qualities, results, random);115 public override void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results, IRandom random) { 116 //OptimizationSupport.Analyze(individuals, qualities, results, random); 109 117 } 110 118 111 public override IEnumerable<Individual> GetNeighbors(Individual individual, IRandom random) {112 return OptimizationSupport.GetNeighbors(individual, random);113 }114 119 #endregion 115 120 116 #region Evaluation Helpers 121 public virtual ExtensionRegistry GetQualityMessageExtensions() { 122 var extensions = ExtensionRegistry.CreateInstance(); 123 extensions.Add(MultiObjectiveQualityMessage.QualityMessage_); 124 return extensions; 125 } 126 127 #region Evaluation 117 128 private HashSet<IEvaluationServiceClient> activeClients = new HashSet<IEvaluationServiceClient>(); 118 129 private object clientLock = new object(); 130 119 131 private QualityMessage EvaluateOnNextAvailableClient(SolutionMessage message) { 120 132 IEvaluationServiceClient client = null; … … 130 142 try { 131 143 return client.Evaluate(message, GetQualityMessageExtensions()); 132 } 133 finally { 144 } finally { 134 145 lock (clientLock) { 135 146 activeClients.Remove(client); … … 139 150 } 140 151 141 protected virtual ExtensionRegistry GetQualityMessageExtensions() { 142 return ExtensionRegistry.CreateInstance(); 143 } 144 145 private SolutionMessage BuildSolutionMessage(Individual individual) { 152 private SolutionMessage BuildSolutionMessage(Individual individual, int solutionId = 0) { 146 153 lock (clientLock) { 147 154 SolutionMessage.Builder protobufBuilder = SolutionMessage.CreateBuilder(); 148 protobufBuilder.SolutionId = 0;155 protobufBuilder.SolutionId = solutionId; 149 156 var scope = new Scope(); 150 157 individual.CopyToScope(scope); … … 152 159 try { 153 160 MessageBuilder.AddToMessage(variable.Value, variable.Name, protobufBuilder); 154 } 155 catch (ArgumentException ex) { 156 throw new InvalidOperationException(string.Format("ERROR while building solution message: Parameter {0} cannot be added to the message", name), ex); 161 } catch (ArgumentException ex) { 162 throw new InvalidOperationException(string.Format("ERROR while building solution message: Parameter {0} cannot be added to the message", Name), ex); 157 163 } 158 164 } -
TabularUnified trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.4/Protos/ExternalEvaluationMessages.proto ¶
r8298 r13180 64 64 } 65 65 66 // Nested Extensions http://www.indelible.org/ink/protobuf-polymorphism/ 66 67 message QualityMessage { 67 68 required int32 solutionId = 1; 68 required double quality = 2; 69 69 enum Type { 70 SingleObjectiveQualityMessage = 1; 71 MultiObjectiveQualityMessage = 2; 72 } 73 required Type type = 2; 70 74 extensions 1000 to max; 71 75 } 76 77 message SingleObjectiveQualityMessage { 78 extend QualityMessage { 79 required SingleObjectiveQualityMessage qualityMessage = 1000; // unique QualityMessage extension number 80 } 81 required double quality = 1; 82 } 83 message MultiObjectiveQualityMessage { 84 extend QualityMessage { 85 required MultiObjectiveQualityMessage qualityMessage = 1001; // unique QualityMessage extension number 86 } 87 repeated double qualities = 1; 88 } 89 72 90 73 91 service EvaluationService { 74 rpc Evaluate (SolutionMessage) returns (QualityMessage); 92 rpc EvaluateSingleObjective (SolutionMessage) returns (SingleObjectiveQualityMessage); 93 rpc EvaluateMultiObjectives (SolutionMessage) returns (MultiObjectiveQualityMessage); 75 94 }
Note: See TracChangeset
for help on using the changeset viewer.