Open HeuristicLab-Trac-Bot opened 8 years ago
The following would be a cache implementation with reprioritization on hits based on a high performance priority queue (github) that is also used in Sim#:
#!csharp public class DeterministicEvaluationCache<TSolution, TComparer> where TSolution : IItem where TComparer : EqualityComparer<TSolution>, new() { private int maxBufferSize; private FastPriorityQueue<DeterministicEvaluationCacheNode<TSolution>> buffer; private Dictionary<TSolution, DeterministicEvaluationCacheNode<TSolution>> cache; private int cacheHits; private long sequence; public int Hits { get { return cacheHits; } } public DeterministicEvaluationCache(int maxBufferSize) { this.maxBufferSize = maxBufferSize; buffer = new FastPriorityQueue<DeterministicEvaluationCacheNode<TSolution>>(maxBufferSize); cache = new Dictionary<TSolution, DeterministicEvaluationCacheNode<TSolution>>(maxBufferSize, new TComparer()); cacheHits = 0; sequence = 0; } public void Reset() { buffer.Clear(); cache.Clear(); cacheHits = 0; sequence = 0; } public bool TryGetValue(TSolution solution, out double quality) { DeterministicEvaluationCacheNode<TSolution> node; if (cache.TryGetValue(solution, out node)) { quality = node.Quality; buffer.UpdatePriority(node, ++sequence); cacheHits++; return true; } quality = double.NaN; return false; } public void Add(TSolution solution, double quality) { if (buffer.Count == maxBufferSize) { var old = buffer.Dequeue(); cache.Remove(old.Solution); } var node = new DeterministicEvaluationCacheNode<TSolution>(solution, quality); buffer.Enqueue(node, ++sequence); cache[solution] = node; } public double GetOrAdd(TSolution solution, Func<double> qualityFunc) { double quality; if (TryGetValue(solution, out quality)) { quality = qualityFunc(); Add(solution, quality); } return quality; } } public class DeterministicEvaluationCacheNode<TSolution> : FastPriorityQueueNode { public TSolution Solution { get; private set; } public double Quality { get; private set; } public DeterministicEvaluationCacheNode(TSolution solution, double quality) { Solution = solution; Quality = quality; } }
My thoughts on this...
Yes, caching might be useful in some cases (very expensive fitness functions). But you also need to consider the overhead for calculation of hash codes and equality checks for every individual. Caching also introduces complexity (probably into specific evaluators).
I believe the root problem is that so many duplicate solutions candidates are visited by the algorithm. This means that the algorithm is inefficient overall. We should 'think big' to improve overall algorithm efficiency instead of investing resources into performance tuning.
Issue migrated from trac ticket # 2633
milestone: HeuristicLab 4.x Backlog | component: Optimization | priority: medium
2016-07-11 22:28:15: @abeham created the issue