public override IEnumerable <BestSolution> LoadBestSolutions() { EntityInfo einfo = Util.GetEntityInfo <BestSolution>(); string sql = $@"SELECT main.[Rneuron_ID] as [RneuronId], main.[Solution_ID] as [SolutionId], MAX(main.[CycleScore]) as [CycleScore], MAX(sess.[SessionScore]) as [SessionScore], MAX(main.[Order]) as [CycleOrder] FROM [{DatabaseName}].[dbo].[{nameof(_Case)}] main with (nolock) INNER JOIN [{DatabaseName}].[dbo].[{nameof(_Session)}] sess ON main.[Session_ID] = sess.[ID] WHERE sess.[Hidden] = 0 GROUP BY main.[Rneuron_ID], main.[Solution_ID]"; using (var conn = GetOpenDBConnection(ConnectionStringWithDatabaseName)) { using (var comm = new SqlCommand(sql, (SqlConnection)conn)) { using (var reader = comm.ExecuteReader()) { while (reader.Read()) { var instance = new BestSolution(); foreach (var item in einfo.Properties) { item.SetValue(instance, reader[item.Name]); } yield return(instance); } } } } }
/// <summary> /// Saves cycle information to database and updates with the score /// </summary> /// <param name="cycleId">Unique identifier of the Cycle</param> /// <param name="cycleScore">Score the engine attained this cycle</param> public void ScoreCycle(long cycleId, double cycleScore) { CurrentCase.CycleScore = cycleScore; // add to best solution staging var bsol = new BestSolution() { RneuronId = CurrentCase.Rneuron_ID, SolutionId = CurrentCase.Solution_ID, CycleOrder = CurrentCase.Order, //CurrentCase.CycleEndTime, CycleScore = CurrentCase.CycleScore, SessionScore = double.MinValue }; MemoryManager.BestSolutionStaging.Add(bsol); //save case to db if (PersistData) { MemoryManager.AddCaseToQueue(cycleId, CurrentCase); } CurrentCase = null; bsol = null; }
public void Run() { long start = System.Environment.TickCount; BestSolution = _initialSolution; BestSolution.Run(false); Fitness = BestSolution.Fitness; ElapsedTime = (int)(System.Environment.TickCount - start); }
int Selection() { roulette.Clear(); int best = 0, score = ObjectiveFunction(population[0]); for (int i = 0; i < population.Count; i++) { int f = ObjectiveFunction(population[i]); if (f < score) { best = i; score = f; } roulette.Add(Math.Pow(1d / f, SelectionWeight)); } if (population[best] == localBest) { age++; } else { age = 0; } localScore = score; localBest = population[best]; if (localScore < BestScore || BestScore == 0) { BestSolution.Copy(localBest); BestScore = localScore; } if (age < AgeLimit) { for (int i = 0; i < SelectionLimit; i++) { int r = roulette.Get(); population.Persist(r); } population.Persist(best); population.NextGeneration(); } else { age = 0; RandomizePopulation(population.Count); return(Selection()); } return(population.Count); }
/// <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); } }
/// <summary> /// Runs the solution /// </summary> /// <returns>the best solution found</returns> public Nelder_Mead_Solution LocateTarget() { for (int t = 0; t < maxLoop; t++) { if (BestSolution.Value < Tolerance) { break; // solution in tolerance } // progress report if ((t % 500 == 0) && onReportProgress != null) { onReportProgress(t * 100 / maxLoop, (object)BestSolution.ToString()); } Nelder_Mead_Solution centroid = GetCentroid(); Nelder_Mead_Solution reflected = GetReflected(centroid); if (reflected.Value < BestSolution.Value) { Nelder_Mead_Solution expanded = GetExpanded(reflected, centroid); ReplaceTheWorstWith((expanded.Value < BestSolution.Value) ? expanded : reflected); continue; } if (!IsWorseThanAllButTheWorst(reflected)) { ReplaceTheWorstWith(reflected); continue; } if (reflected.Value <= WorstSolution.Value) { ReplaceTheWorstWith(reflected); } Nelder_Mead_Solution contracted = GetContracted(centroid); if (contracted.Value > WorstSolution.Value) { ShrinkTowardsTheBestSolution(); } else { ReplaceTheWorstWith(contracted); } } return(BestSolution); }
int GetBestSolution() { int best = 0, score = ObjectiveFunction(population[0]); for (int i = 1; i < population.Count; i++) { int f = ObjectiveFunction(population[i]); if (f < score) { best = i; score = f; } } localScore = score; localBest = population[best]; if (localScore < BestScore || BestScore == 0) { BestSolution.Copy(localBest); BestScore = localScore; } return(best); }
/// <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 trainingLinearTolerance = 0, bool predict = false, double predictLinearTolerance = 0, IEnumerable <long> excludeSolutions = null) { this.predict = predict; this.excludeSolutions = excludeSolutions; bool useLinearTolerance = ((predict && predictLinearTolerance > 0) || !predict) ? true : false; double linearTolerance = (predict) ? predictLinearTolerance : trainingLinearTolerance; Solution retVal = null; int cnt = 0; foreach (var item in inputs) { InputRangeInfo rangeInfo = null; double val; if (item.DotNetType == typeof(bool).ToString()) { bool boolVal = Convert.ToBoolean(item.Value); val = (boolVal) ? 1 : 0; } else { val = Convert.ToDouble(item.Value); } if (item.Type == Enums.RlmInputType.Linear) { double off = (item.Max - item.Min) * ((linearTolerance == 0) ? 0 : (linearTolerance / 100D)); rangeInfo = new InputRangeInfo() { InputId = item.ID, InputType = item.Type, FromValue = val - off, ToValue = val + off }; } else { rangeInfo = new InputRangeInfo() { InputId = item.ID, InputType = item.Type, Value = item.Value, FromValue = val, ToValue = val }; } rangeInfos[cnt] = rangeInfo; doubleInputsArray[cnt] = doubleInputs[cnt].DataArray; resultsArray[cnt] = results[cnt].DataArray; fromArray[cnt] = rangeInfo.FromValue; toArray[cnt] = rangeInfo.ToValue; cnt++; } currBS = null; if (useLinearTolerance && predict == false) { if (CacheBox.IsWithinRange(rangeInfos, linearTolerance)) { rneuronProcessor.Execute(CacheBox.CachedRneurons, CacheBox.CachedInputs, fromArray, toArray, false); } else { double[][] cacheBoxRangeInfos = RebuildCacheBoxRangesGPU(inputs, linearTolerance); rneuronsCacheArray = new bool[rneuronIds.DataArray.Length]; var cachedDataArray = rneuronProcessor.Execute(rneuronIds.DataArray, doubleInputsArray, fromArray, toArray, rneuronsCacheArray, cacheBoxRangeInfos[0], cacheBoxRangeInfos[1]); CacheBox.CachedRneurons = cachedDataArray.Rneurons.ToArray(); CacheBox.CachedInputs = cachedDataArray.Inputs.Select(a => a.ToArray()).ToArray(); } } else { rneuronProcessor.Execute(rneuronIds.DataArray, doubleInputsArray, fromArray, toArray, true); } if (currBS != null) { retVal = Solutions[currBS.SolutionId]; } return(retVal); }
/// <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); }
public void StartSA(List <int> initialRoute, List <Adress> listOfAdressesUnique, double temperature, double coolingTemperature, double lambda, int countOfCouriers) { List <int> currentSolution = new List <int>(); List <int> neighbourSolution = new List <int>(); List <double> neighbourDistance = new List <double>(); double currentDistance = 0.0; double shortestDistance = 9999.0; double currentCmax = 9999; double deltaDistance = 0.0; for (int i = 0; i < initialRoute.Count(); i++) { currentSolution.Add(initialRoute[i]); } int size = currentSolution.Count(); for (int i = 0; i < size - 1; i++) { var latitude1 = Decimal.ToDouble((from z in listOfAdressesUnique where z.AdressId == currentSolution[i] select z.Latitude).First()); var longitude1 = Decimal.ToDouble((from z in listOfAdressesUnique where z.AdressId == currentSolution[i] select z.Longitude).First()); GeoCoordinate g1 = new GeoCoordinate(latitude1, longitude1); var latitude2 = Decimal.ToDouble((from z in listOfAdressesUnique where z.AdressId == currentSolution[i + 1] select z.Latitude).First()); var longitude2 = Decimal.ToDouble((from z in listOfAdressesUnique where z.AdressId == currentSolution[i + 1] select z.Longitude).First()); GeoCoordinate g2 = new GeoCoordinate(latitude2, longitude2); currentDistance += g1.GetDistanceTo(g2); } for (int i = 0; i < currentSolution.Count; i++) { BestSolution.Add(currentSolution[i]); } shortestDistance = currentDistance; Random random = new Random(); Random random2 = new Random(); while (temperature > coolingTemperature) { int randomNumber1 = random.Next(1, size - 1); int randomNumber2 = random2.Next(1, size - 1); while (randomNumber1 == randomNumber2) { randomNumber2 = random.Next(1, size - 1); } for (int i = 0; i < currentSolution.Count(); i++) { neighbourSolution.Add(currentSolution[i]); } int temp = neighbourSolution[randomNumber1]; neighbourSolution[randomNumber1] = neighbourSolution[randomNumber2]; neighbourSolution[randomNumber2] = temp; int u = 0; double bufor = 0.0; for (int i = 0; i < countOfCouriers; i++) { neighbourDistance.Add(0); } for (int i = 0; i < size - 1; i++) { var latitude1 = Decimal.ToDouble((from z in listOfAdressesUnique where z.AdressId == neighbourSolution[i] select z.Latitude).First()); var longitude1 = Decimal.ToDouble((from z in listOfAdressesUnique where z.AdressId == neighbourSolution[i] select z.Longitude).First()); GeoCoordinate g1 = new GeoCoordinate(latitude1, longitude1); var latitude2 = Decimal.ToDouble((from z in listOfAdressesUnique where z.AdressId == neighbourSolution[i + 1] select z.Latitude).First()); var longitude2 = Decimal.ToDouble((from z in listOfAdressesUnique where z.AdressId == neighbourSolution[i + 1] select z.Longitude).First()); GeoCoordinate g2 = new GeoCoordinate(latitude2, longitude2); if (neighbourSolution[i] != 1 || i == 0 || i == size - 1) { bufor += g1.GetDistanceTo(g2); } else { neighbourDistance[u] = bufor; bufor = 0.0; bufor += g1.GetDistanceTo(g2); u++; } } neighbourDistance[u] = bufor; u = 0; bufor = 0; neighbourDistance.Sort(); bufor = neighbourDistance.Last(); if (bufor < currentCmax) { currentCmax = bufor; } if (shortestDistance > currentCmax) { shortestDistance = currentCmax; BestSolution.Clear(); for (int i = 0; i < size; i++) { BestSolution.Add(neighbourSolution[i]); } } if (currentCmax <= currentDistance) { currentDistance = currentCmax; currentSolution.Clear(); for (int i = 0; i < size; i++) { currentSolution.Add(neighbourSolution[i]); } } else { deltaDistance = currentCmax - currentDistance; double p = Math.Exp((-deltaDistance) / temperature); Random random3 = new Random(); double z = random3.Next(0, 101); z = z / 100; if (z <= p) { currentSolution.Clear(); for (int i = 0; i < size; i++) { currentSolution.Add(neighbourSolution[i]); } currentDistance = currentCmax; } } neighbourSolution.Clear(); neighbourDistance.Clear(); temperature *= lambda; bufor = 0.0; Iter++; } }
private bool CompareEdges(Edge firstEdge, Edge secondEdge) // Funkcja sprawdzajaca czy zamiana dwoch krawedzi polepszy rozwiazanie { var cost = CalculateCost(BestSolution); // Zapamietanie kosztu dotychczas najlepszego rozwiazania var list = CurrentSolution.ToList(); // Zapamietanie obecnego rozwiazania var edge = new Edge(list[firstEdge.Start], list[firstEdge.End]); // Zapamietanie krawedzi ktora jest pod tymi indeksami, aby pozniej mozna bylo ja zamienic list[firstEdge.Start] = list[secondEdge.Start]; // Zamiana krawedzi list[firstEdge.End] = list[secondEdge.End]; list[secondEdge.Start] = edge.Start; list[secondEdge.End] = edge.End; var cost1 = CalculateCost(list); // Obliczenie kosztu otrzymanego rozwiazania var list1 = CurrentSolution.ToList(); // Zapamietanie obecnego rozwiazania var edge1 = new Edge(list1[firstEdge.Start], list1[firstEdge.End]); // Inna mozliwozc zamiany krawedzi list1[firstEdge.Start] = list1[secondEdge.End]; list1[firstEdge.End] = list1[secondEdge.Start]; list1[secondEdge.Start] = edge.End; list1[secondEdge.End] = edge.Start; var cost2 = CalculateCost(list1); // Obliczenie kosztu otrzymanego rozwiazania if (cost1 < cost2) // Jezeli pierwsze otrzymane rozwiazanie jest lepsze od drugiego { if (cost1 < cost) // Jezeli rozwiazanie jest lepsze od dotychczas najlepszego { if (TabuList.Count != 0) // Jezeli tabu lista nie jest pusta zmniejsz kadencje kazdego elementu { for (int k = TabuList.Count - 1; k >= 0; k--) { TabuList[k].Cadency--; if (TabuList[k].Cadency == 0) { TabuList.RemoveAt(k); } } } var tabu = new TabuElement(Cadency, edge); // Dodanie pierwszej krawedzi z ruchu do tabu listy TabuList.Add(tabu); CurrentSolution = list; // Zapisanie otzrymanego rozwiazania jako najlepsze i aktualne BestSolution.Clear(); foreach (var j in CurrentSolution) { BestSolution.Add(j); } return(true); } } else // Jezeli drugie otrzymane rozwiazanie jest lepsze od pierwszego { if (cost2 < cost) // Jezeli rozwiazanie jest lepsze od dotychczas najlepszego { if (TabuList.Count != 0) // Jezeli tabu lista nie jest pusta zmniejsz kadencje kazdego elementu { for (int k = TabuList.Count - 1; k >= 0; k--) { TabuList[k].Cadency--; if (TabuList[k].Cadency == 0) { TabuList.RemoveAt(k); } } } var tabu = new TabuElement(Cadency, edge1); // Dodanie pierwszej krawedzi z ruchu do tabu listy TabuList.Add(tabu); CurrentSolution = list1; // Zapisanie otzrymanego rozwiazania jako najlepsze i aktualne BestSolution.Clear(); foreach (var j in CurrentSolution) { BestSolution.Add(j); } return(true); } } return(false); }