/// <summary> /// Sets best solution /// </summary> /// <param name="bestSolution"></param> public void SetBestSolution(BestSolution bestSolution) { Dictionary <long, BestSolution> innerBestSolutions; if (BestSolutions.TryGetValue(bestSolution.RneuronId, out innerBestSolutions)) { innerBestSolutions.Add(bestSolution.SolutionId, bestSolution); } else { innerBestSolutions = new Dictionary <long, BestSolution>(); innerBestSolutions.Add(bestSolution.SolutionId, bestSolution); BestSolutions.TryAdd(bestSolution.RneuronId, innerBestSolutions); } }
public void FindBestSolution(long rneuronId) { Dictionary <long, BestSolution> bsDict; if (BestSolutions.TryGetValue(rneuronId, out bsDict)) { IEnumerable <BestSolution> solutionDic; if (excludeSolutions != null && excludeSolutions.Count() > 0) { solutionDic = bsDict .Where(a => !excludeSolutions.Any(b => b == a.Key)) .Select(a => a.Value); } else { solutionDic = bsDict.Values; } foreach (var bs in solutionDic) { if (currBS == null) { Interlocked.Exchange(ref currBS, bs); continue; } if (!predict) { if ((bs.CycleScore > currBS.CycleScore) || (bs.CycleScore == currBS.CycleScore && bs.SessionScore > currBS.SessionScore) || (bs.CycleScore == currBS.CycleScore && bs.SessionScore == currBS.SessionScore && bs.CycleOrder > currBS.CycleOrder)) { Interlocked.Exchange(ref currBS, bs); } } else { if ((bs.SessionScore > currBS.SessionScore) || (bs.SessionScore == currBS.SessionScore && bs.CycleScore > currBS.CycleScore) || (bs.SessionScore == currBS.SessionScore && bs.CycleScore == currBS.CycleScore && bs.CycleOrder > currBS.CycleOrder)) { Interlocked.Exchange(ref currBS, bs); } } } } }
/// <summary> /// Gets best Solution /// </summary> /// <param name="inputs"></param> /// <param name="linearTolerance"></param> /// <param name="predict"></param> /// <returns></returns> public Solution GetBestSolution(IEnumerable <RlmIOWithValue> inputs, double linearTolerance = 0, bool predict = false) { Solution retVal = null; var comparer = new DynamicInputComparer();//Util.DynamicInputComparer; List <long> rneuronsFound = new List <long>(); var rangeInfos = new Dictionary <int, InputRangeInfo>(); int cnt = 0; foreach (var item in inputs) { if (item.Type == Enums.RlmInputType.Linear) { double val = Convert.ToDouble(item.Value); double off = (item.Max - item.Min) * ((linearTolerance == 0) ? 0 : (linearTolerance / 100D)); rangeInfos.Add(cnt, new InputRangeInfo() { InputId = item.ID, InputType = item.Type, FromValue = val - off, ToValue = val + off }); } else { rangeInfos.Add(cnt, new InputRangeInfo() { InputId = item.ID, InputType = item.Type, Value = item.Value }); } cnt++; } //swGetRneuron.Start(); //RnnInputValue.RecurseInputForMatchingRneurons(DynamicInputs, rangeInfos, rneuronsFound); //swGetRneuron.Stop(); //GetRneuronTimes.Add(swGetRneuron.Elapsed); //swGetRneuron.Reset(); //TODO Cache Box, current implementation is slow don't know why if (!predict) { if (CacheBox.IsWithinRange(rangeInfos, linearTolerance)) { swGetRneuron.Start(); RlmInputValue.RecurseInputForMatchingRneurons(CacheBox.CachedInputs, rangeInfos, rneuronsFound); swGetRneuron.Stop(); GetRneuronTimes.Add(swGetRneuron.Elapsed); swGetRneuron.Reset(); } else { swRebuildCache.Start(); CacheBoxCount++; CacheBox.Clear(); var cacheBoxRangeInfos = new Dictionary <int, InputRangeInfo>(); int cacheRangeCnt = 0; foreach (var item in inputs) { if (item.Type == Enums.RlmInputType.Linear) { double val = Convert.ToDouble(item.Value); double dataOff = (item.Max - item.Min) * ((linearTolerance == 0) ? 0 : (linearTolerance / 100D)); //double cacheMargin = (CacheBoxMargin == 0) ? 0 : ((item.Max - item.Min) * (CacheBoxMargin / 100)); double momentum = item.InputMomentum.MomentumDirection; double toOff = 0; double fromOff = 0; double cacheOff = 0; if (UseMomentumAvgValue) { cacheOff = item.InputMomentum.MomentumValue * MomentumAdjustment; } else { cacheOff = (item.Max - item.Min) * ((linearTolerance == 0) ? 0 : (MomentumAdjustment / 100D)); } if (momentum > 0) { var offset = momentum * cacheOff; toOff = val + dataOff + (cacheOff + offset); fromOff = val - dataOff - (cacheOff - offset); } else if (momentum < 0) { var offset = Math.Abs(momentum) * cacheOff; toOff = val + dataOff + (cacheOff - offset); fromOff = val - dataOff - (cacheOff + offset); } else { toOff = val + dataOff + cacheOff; fromOff = val - dataOff - cacheOff; } double cacheMargin = (CacheBoxMargin == 0) ? 0 : (cacheOff) * (CacheBoxMargin / 100D); toOff += cacheMargin; fromOff -= cacheMargin; cacheBoxRangeInfos.Add(cacheRangeCnt, new InputRangeInfo() { InputId = item.ID, FromValue = Math.Ceiling(fromOff), ToValue = Math.Ceiling(toOff) }); } else { cacheBoxRangeInfos.Add(cacheRangeCnt, new InputRangeInfo() { InputId = item.ID, Value = item.Value }); } cacheRangeCnt++; } CacheBox.SetRanges(cacheBoxRangeInfos.Values); CacheBox.CachedInputs = RlmInputValue.RecurseInputForMatchingRneuronsForCaching(DynamicInputs, cacheBoxRangeInfos, rangeInfos, rneuronsFound); //RnnInputValue.RecurseInputForMatchingRneurons(CacheBox.CachedInputs, rangeInfos, rneuronsFound); swRebuildCache.Stop(); RebuildCacheboxTimes.Add(swRebuildCache.Elapsed); swRebuildCache.Reset(); } } else { RlmInputValue.RecurseInputForMatchingRneurons(DynamicInputs, rangeInfos, rneuronsFound); } BestSolution currBS = null; foreach (var rneuronId in rneuronsFound) { Dictionary <long, BestSolution> bsDict; if (BestSolutions.TryGetValue(rneuronId, out bsDict)) { foreach (var bs in bsDict.Values) { if (!predict) { if (currBS != null) { if (bs.CycleScore > currBS.CycleScore) { currBS = bs; } else if (bs.CycleScore == currBS.CycleScore && bs.SessionScore >= currBS.SessionScore && bs.CycleOrder >= currBS.CycleOrder) { currBS = bs; } } else { currBS = bs; } } else { if (currBS != null) { if (bs.SessionScore > currBS.SessionScore) { currBS = bs; } else if (bs.SessionScore == currBS.SessionScore && bs.CycleScore >= currBS.CycleScore && bs.CycleOrder >= currBS.CycleOrder) { currBS = bs; } } else { currBS = bs; } } } } } if (currBS != null) { retVal = Solutions[currBS.SolutionId]; } return(retVal); }