/// <summary> /// Sets the Rneuron /// </summary> /// <param name="rneuron"></param> public void SetRneuronWithInputs(Rneuron rneuron) { var rneuronId = rneuron.ID; // add rneuron to cache Rneurons.TryAdd(rneuronId, rneuron); bool isFirstInput = true; RlmInputValue lastInputValue = null; int cnt = 0; IComparer <RlmInputKey> distinctComparer = new RlmInputKeyDistinctComparer(); IComparer <RlmInputKey> linearComparer = new RlmInputKeyLinearComparer(); // build dynamic inputs foreach (var i in rneuron.Input_Values_Reneurons) { RlmInputKey inputKey = new RlmInputKey() { Value = i.Value, InputNum = cnt, Type = i.InputType }; inputKey.DoubleValue = (i.InputType == Enums.RlmInputType.Linear) ? Convert.ToDouble(i.Value) : 0D; RlmInputValue inputVal = null; if (!isFirstInput) { if (lastInputValue.RelatedInputs == null) { lastInputValue.RelatedInputs = new SortedList <RlmInputKey, RlmInputValue>(i.InputType == Enums.RlmInputType.Linear ? linearComparer : distinctComparer); } if (!lastInputValue.RelatedInputs.TryGetValue(inputKey, out inputVal)) { inputVal = new RlmInputValue(); lastInputValue.RelatedInputs.Add(inputKey, inputVal); } lastInputValue = inputVal; } else { if (DynamicInputs == null) { DynamicInputs = new SortedList <RlmInputKey, RlmInputValue>(i.InputType == Enums.RlmInputType.Linear ? linearComparer : distinctComparer); } isFirstInput = false; if (!DynamicInputs.TryGetValue(inputKey, out inputVal)) { inputVal = new RlmInputValue(); DynamicInputs.Add(inputKey, inputVal); } lastInputValue = inputVal; } cnt++; } lastInputValue.RneuronId = rneuronId; }
/// <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); }
/// <summary> /// Gets existing Rneuron and creates a new one if not existing /// </summary> /// <param name="inputs">Inputs with value</param> /// <param name="rnetworkID">Current NetworkId</param> /// <returns></returns> public GetRneuronResult GetRneuronFromInputs(IEnumerable <RlmIOWithValue> inputs, long rnetworkID) { GetRneuronResult retVal = new GetRneuronResult(); Rneuron rneuron = null; // generate key based on input values long rneuronId = Util.GenerateHashKey(inputs.Select(a => a.Value).ToArray()); // create new rneuron if not exists if (!Rneurons.TryGetValue(rneuronId, out rneuron)) { rneuron = new Rneuron() { ID = rneuronId, Rnetwork_ID = rnetworkID }; bool isFirstInput = true; RlmInputValue lastInputValue = null; int cnt = 0; IComparer <RlmInputKey> distinctComparer = new RlmInputKeyDistinctComparer(); IComparer <RlmInputKey> linearComparer = new RlmInputKeyLinearComparer(); foreach (var i in inputs) { // create IVR instance var ivr = new Input_Values_Rneuron() { ID = Util.GenerateHashKey(rneuronId, i.ID), Value = i.Value, Input_ID = i.ID, Rneuron_ID = rneuronId, DotNetType = i.DotNetType, InputType = i.Type }; rneuron.Input_Values_Reneurons.Add(ivr); RlmInputKey inputKey = new RlmInputKey() { Value = ivr.Value, InputNum = cnt, Type = i.Type }; inputKey.DoubleValue = (i.Type == Enums.RlmInputType.Linear) ? Convert.ToDouble(ivr.Value) : 0D; RlmInputValue inputVal = null; if (!isFirstInput) { if (lastInputValue.RelatedInputs == null) { lastInputValue.RelatedInputs = new SortedList <RlmInputKey, RlmInputValue>(i.Type == Enums.RlmInputType.Linear ? linearComparer : distinctComparer); } if (!lastInputValue.RelatedInputs.TryGetValue(inputKey, out inputVal)) { inputVal = new RlmInputValue(); lastInputValue.RelatedInputs.Add(inputKey, inputVal); } lastInputValue = inputVal; } else { if (DynamicInputs == null) { DynamicInputs = new SortedList <RlmInputKey, RlmInputValue>(i.Type == Enums.RlmInputType.Linear ? linearComparer : distinctComparer); } isFirstInput = false; if (!DynamicInputs.TryGetValue(inputKey, out inputVal)) { inputVal = new RlmInputValue(); DynamicInputs.Add(inputKey, inputVal); } lastInputValue = inputVal; } cnt++; } lastInputValue.RneuronId = rneuronId; Rneurons.TryAdd(rneuronId, rneuron); //rneuron_queue.Add(retVal); //if (Rneurons.TryAdd(rneuronId, retVal)) //{ //} //Rneurons2.Enqueue(retVal); //rneuron_queue.Add(retVal); retVal.Rneuron = rneuron; retVal.ExistsInCache = false; } else { retVal.Rneuron = rneuron; retVal.ExistsInCache = true; } return(retVal); }