Changeset 6183 for trunk/sources/HeuristicLab.Problems.ExternalEvaluation
- Timestamp:
- 05/11/11 15:36:30 (14 years ago)
- Location:
- trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.3
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.3/CachedExternalEvaluator.cs
r6172 r6183 21 21 22 22 23 using System.Threading; 23 24 using HeuristicLab.Common; 24 25 using HeuristicLab.Core; … … 33 34 34 35 #region Parameters 35 public OptionalValueParameter<EvaluationCache> CacheParameter {36 get { return ( OptionalValueParameter<EvaluationCache>)Parameters["Cache"]; }36 public ValueLookupParameter<EvaluationCache> CacheParameter { 37 get { return (ValueLookupParameter<EvaluationCache>)Parameters["Cache"]; } 37 38 } 38 39 #endregion 39 40 40 41 #region Parameter Values 41 public EvaluationCache Cache {42 get { return CacheParameter.Value; }43 set { CacheParameter.Value = value; }44 }45 42 protected DoubleValue Quality { 46 43 get { return QualityParameter.ActualValue; } … … 49 46 protected IEvaluationServiceClient Client { 50 47 get { return ClientParameter.ActualValue; } 48 } 49 protected EvaluationCache Cache { 50 get { return CacheParameter.ActualValue; } 51 set { CacheParameter.ActualValue = value; } 51 52 } 52 53 #endregion … … 61 62 public CachedExternalEvaluator() 62 63 : base() { 63 Parameters.Add(new OptionalValueParameter<EvaluationCache>("Cache", "Cache of previously evaluated solutions"));64 Parameters.Add(new ValueLookupParameter<EvaluationCache>("Cache", "Cache of previously evaluated solutions")); 64 65 } 65 66 #endregion 66 67 67 68 public override IOperation Apply() { 68 if (Cache == null) Cache = new EvaluationCache(); 69 if (Cache == null) 70 return base.Apply(); 71 69 72 if (Quality == null) Quality = new DoubleValue(0); 70 71 73 Quality.Value = Cache.GetValue(BuildSolutionMessage(), m => Client.Evaluate(m).Quality); 72 73 74 if (Successor != null) 74 75 return ExecutionContext.CreateOperation(Successor); -
trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.3/EvaluationCache.cs
r6169 r6183 26 26 using System.Collections.Generic; 27 27 using System.Linq; 28 using System.Threading; 28 29 using HeuristicLab.Common; 29 30 using HeuristicLab.Common.Resources; … … 73 74 private LinkedList<CacheEntry> list; 74 75 private Dictionary<CacheEntry, LinkedListNode<CacheEntry>> index; 76 private static HashSet<string> activeEvaluations = new HashSet<string>(); 77 private static object cacheLock = new object(); 78 private static object evaluationLock = new object(); 79 private static AutoResetEvent evaluationDone = new AutoResetEvent(false); 75 80 #endregion 76 81 … … 80 85 } 81 86 public int Size { 82 get { return index.Count; } 87 get { 88 lock (cacheLock) { 89 return index.Count; 90 } 91 } 92 } 93 public int ActiveEvaluations { 94 get { 95 lock (evaluationLock) { 96 return activeEvaluations.Count; 97 } 98 } 83 99 } 84 100 [Storable] … … 89 105 public event EventHandler SizeChanged; 90 106 public event EventHandler HitsChanged; 107 public event EventHandler ActiveEvalutionsChanged; 91 108 92 109 protected virtual void OnSizeChanged() { … … 100 117 handler(this, EventArgs.Empty); 101 118 } 119 protected virtual void OnActiveEvalutionsChanged() { 120 EventHandler handler = ActiveEvalutionsChanged; 121 if (handler != null) 122 handler(this, EventArgs.Empty); 123 } 102 124 #endregion 103 125 … … 105 127 public FixedValueParameter<IntValue> CapacityParameter { 106 128 get { return (FixedValueParameter<IntValue>)Parameters["Capacity"]; } 129 } 130 public FixedValueParameter<BoolValue> PersistentCacheParameter { 131 get { return (FixedValueParameter<BoolValue>)Parameters["PersistentCache"]; } 107 132 } 108 133 #endregion … … 113 138 set { CapacityParameter.Value.Value = value; } 114 139 } 140 public bool IsPersistent { 141 get { return PersistentCacheParameter.Value.Value; } 142 } 115 143 #endregion 116 144 … … 119 147 private IEnumerable<KeyValuePair<string, double>> Cache_Persistence { 120 148 get { 149 if (IsPersistent) { 150 return GetCacheValues(); 151 } else { 152 return Enumerable.Empty<KeyValuePair<string, double>>(); 153 } 154 } 155 set { 156 SetCacheValues(value); 157 } 158 } 159 [StorableHook(HookType.AfterDeserialization)] 160 private void AfterDeserialization() { 161 RegisterEvents(); 162 } 163 #endregion 164 165 #region Construction & Cloning 166 [StorableConstructor] 167 protected EvaluationCache(bool deserializing) : base(deserializing) { } 168 protected EvaluationCache(EvaluationCache original, Cloner cloner) 169 : base(original, cloner) { 170 SetCacheValues(original.GetCacheValues()); 171 RegisterEvents(); 172 } 173 public EvaluationCache() { 174 list = new LinkedList<CacheEntry>(); 175 index = new Dictionary<CacheEntry, LinkedListNode<CacheEntry>>(); 176 Parameters.Add(new FixedValueParameter<IntValue>("Capacity", "Maximum number of cache entries.", new IntValue(10000))); 177 Parameters.Add(new FixedValueParameter<BoolValue>("PersistentCache", "Save cache when serializing object graph?", new BoolValue(false))); 178 RegisterEvents(); 179 } 180 public override IDeepCloneable Clone(Cloner cloner) { 181 return new EvaluationCache(this, cloner); 182 } 183 #endregion 184 185 #region Event Handling 186 private void RegisterEvents() { 187 CapacityParameter.Value.ValueChanged += new EventHandler(Value_ValueChanged); 188 } 189 190 void Value_ValueChanged(object sender, EventArgs e) { 191 if (Capacity < 0) 192 throw new ArgumentOutOfRangeException("Cache capacity cannot be less than zero"); 193 Trim(); 194 } 195 #endregion 196 197 #region Methods 198 public void Reset() { 199 lock (cacheLock) { 200 list = new LinkedList<CacheEntry>(); 201 index = new Dictionary<CacheEntry, LinkedListNode<CacheEntry>>(); 202 Hits = 0; 203 } 204 OnSizeChanged(); 205 OnHitsChanged(); 206 } 207 208 public double GetValue(SolutionMessage message, Evaluator evaluate) { 209 CacheEntry entry = new CacheEntry(message.ToString()); 210 LinkedListNode<CacheEntry> node; 211 bool lockTaken = false; 212 try { 213 Monitor.Enter(cacheLock, ref lockTaken); 214 if (index.TryGetValue(entry, out node)) { 215 list.Remove(node); 216 list.AddLast(node); 217 Hits++; 218 lockTaken = false; 219 Monitor.Exit(cacheLock); 220 OnHitsChanged(); 221 return node.Value.Value; 222 } else { 223 lockTaken = false; 224 Monitor.Exit(cacheLock); 225 return Evaluate(message, evaluate, entry); 226 } 227 } finally { 228 if (lockTaken) 229 Monitor.Exit(cacheLock); 230 } 231 } 232 233 private double Evaluate(SolutionMessage message, Evaluator evaluate, CacheEntry entry) { 234 bool lockTaken = false; 235 try { 236 Monitor.Enter(evaluationLock, ref lockTaken); 237 if (activeEvaluations.Contains(entry.Key)) { 238 while (activeEvaluations.Contains(entry.Key)) { 239 lockTaken = false; 240 Monitor.Exit(evaluationLock); 241 evaluationDone.WaitOne(); 242 Monitor.Enter(evaluationLock, ref lockTaken); 243 } 244 lock (cacheLock) { 245 return index[entry].Value.Value; 246 } 247 } else { 248 activeEvaluations.Add(entry.Key); 249 lockTaken = false; 250 Monitor.Exit(evaluationLock); 251 OnActiveEvalutionsChanged(); 252 entry.Value = evaluate(message); 253 lock (cacheLock) { 254 index[entry] = list.AddLast(entry); 255 } 256 lock (evaluationLock) { 257 activeEvaluations.Remove(entry.Key); 258 evaluationDone.Set(); 259 } 260 OnActiveEvalutionsChanged(); 261 Trim(); 262 return entry.Value; 263 } 264 } finally { 265 if (lockTaken) 266 Monitor.Exit(evaluationLock); 267 } 268 } 269 270 private void Trim() { 271 lock (cacheLock) { 272 while (list.Count > Capacity) { 273 LinkedListNode<CacheEntry> item = list.First; 274 list.Remove(item); 275 index.Remove(item.Value); 276 } 277 } 278 OnSizeChanged(); 279 } 280 private IEnumerable<KeyValuePair<string, double>> GetCacheValues() { 281 lock (cacheLock) { 121 282 return index.ToDictionary(kvp => kvp.Key.Key, kvp => kvp.Key.Value); 122 283 } 123 set { 284 } 285 private void SetCacheValues(IEnumerable<KeyValuePair<string, double>> value) { 286 lock (cacheLock) { 124 287 list = new LinkedList<CacheEntry>(); 125 288 index = new Dictionary<CacheEntry, LinkedListNode<CacheEntry>>(); … … 131 294 } 132 295 } 133 [StorableHook(HookType.AfterDeserialization)]134 private void AfterDeserialization() {135 RegisterEvents();136 }137 #endregion138 139 #region Construction & Cloning140 [StorableConstructor]141 protected EvaluationCache(bool deserializing) : base(deserializing) { }142 protected EvaluationCache(EvaluationCache original, Cloner cloner)143 : base(original, cloner) {144 Cache_Persistence = original.Cache_Persistence;145 RegisterEvents();146 }147 public EvaluationCache() {148 list = new LinkedList<CacheEntry>();149 index = new Dictionary<CacheEntry, LinkedListNode<CacheEntry>>();150 Parameters.Add(new FixedValueParameter<IntValue>("Capacity", "Maximum number of cache entries.", new IntValue(10000)));151 RegisterEvents();152 }153 public override IDeepCloneable Clone(Cloner cloner) {154 return new EvaluationCache(this, cloner);155 }156 #endregion157 158 #region Event Handling159 private void RegisterEvents() {160 CapacityParameter.Value.ValueChanged += new EventHandler(Value_ValueChanged);161 }162 163 void Value_ValueChanged(object sender, EventArgs e) {164 if (Capacity < 0)165 throw new ArgumentOutOfRangeException("Cache capacity cannot be less than zero");166 Trim();167 }168 #endregion169 170 #region Methods171 public void Reset() {172 list = new LinkedList<CacheEntry>();173 index = new Dictionary<CacheEntry, LinkedListNode<CacheEntry>>();174 Hits = 0;175 OnSizeChanged();176 OnHitsChanged();177 }178 179 public double GetValue(SolutionMessage message, Evaluator evaluate) {180 CacheEntry entry = new CacheEntry(message.ToString());181 LinkedListNode<CacheEntry> node;182 if (index.TryGetValue(entry, out node)) {183 list.Remove(node);184 list.AddLast(node);185 Hits++;186 OnHitsChanged();187 return node.Value.Value;188 } else {189 entry.Value = evaluate(message);190 index[entry] = list.AddLast(entry);191 Trim();192 return entry.Value;193 }194 }195 196 private void Trim() {197 while (list.Count > Capacity) {198 LinkedListNode<CacheEntry> item = list.First;199 list.Remove(item);200 index.Remove(item.Value);201 }202 OnSizeChanged();203 }204 296 #endregion 205 297 -
trunk/sources/HeuristicLab.Problems.ExternalEvaluation/3.3/ExternalEvaluationProblem.cs
r5809 r6183 86 86 get { return (ValueParameter<ItemList<IOperator>>)Parameters["Operators"]; } 87 87 } 88 public OptionalValueParameter<EvaluationCache> CacheParameter { 89 get { return (OptionalValueParameter<EvaluationCache>)Parameters["Cache"]; } 90 } 88 91 #endregion 89 92 … … 148 151 Parameters.Add(new OptionalValueParameter<IScope>("BestKnownSolution", "The best known solution for this external evaluation problem.")); 149 152 Parameters.Add(new ValueParameter<ItemList<IOperator>>("Operators", "The operators that are passed to the algorithm.", new ItemList<IOperator>())); 153 Parameters.Add(new OptionalValueParameter<EvaluationCache>("Cache", "Cache of previously evaluated solutions.")); 150 154 151 155 InitializeOperators();
Note: See TracChangeset
for help on using the changeset viewer.