public (List <int> jobOrder, int minTardiness) Solve(IMethodOptions imethodoptions, Stopwatch stopwatch) { var options = imethodoptions as SimulatedAnnealingOptions; List <int> bestOrder = options.Data.Select(x => x.Index).ToList(); var minTardiness = int.MaxValue; var count = 0; int step = 2; options.GuiConnection?.LogText?.Invoke($"Start : {DateTime.Now:HH:mm:ss.fff}"); stopwatch.Start(); try { while (count < options.IterationCount) { options.GuiConnection?.LogText?.Invoke($"Iteracja: {count}"); List <int> candidateOrder = new List <int>(bestOrder); candidateOrder.Swap(ThreadSafeRandom.ThisThreadsRandom.Next(0, bestOrder.Count), ThreadSafeRandom.ThisThreadsRandom.Next(0, bestOrder.Count)); options.GuiConnection?.LogText?.Invoke($"Kandydat: {string.Join(",", candidateOrder)}"); var delta = options.Data.JobsFromIndexList(candidateOrder).CountPenalty() - options.Data.JobsFromIndexList(bestOrder).CountPenalty(); options.GuiConnection?.LogText?.Invoke($"Zmiana sumy opóźnień: {delta}"); var alpha = 10 + count * step * 2; // control parameter var acceptanceProbability = Math.Exp(-alpha * delta); options.GuiConnection?.LogText?.Invoke($"Szansa akceptacji = { acceptanceProbability}"); if (acceptanceProbability > ThreadSafeRandom.GetRandomDouble(0, 1)) { bestOrder = candidateOrder; options.GuiConnection?.LogText?.Invoke($"Zaakceptowano{Environment.NewLine}"); } count += 1; options.CancellationToken.ThrowIfCancellationRequested(); } } catch (OperationCanceledException) { imethodoptions.GuiConnection?.LogText("Przerwano wykonwanie zadania"); } stopwatch.Stop(); minTardiness = options.Data.JobsFromIndexList(bestOrder).CountPenalty(); return(bestOrder, minTardiness); }
public (List <int> jobOrder, int minTardiness) Solve(IMethodOptions imethodoptions, Stopwatch stopwatch) { var options = imethodoptions as AlphaDominantGeneticOptions; var minTardiness = options.Data.CountPenalty(); int dataCount = options.Data.Count; List <int> best = options.Data.Select(x => x.Index).ToList(); List <(List <int> indiv, double fitness)> pop; string prev = ""; options.OldPopCount = (int)(options.PopulationSize * (1 - options.CrossoverRate)); options.GuiConnection?.LogText?.Invoke($"Wielkość starej populacji: {options.OldPopCount}"); options.GuiConnection?.LogText?.Invoke($"Start : {DateTime.Now:HH:mm:ss.fff}"); stopwatch.Start(); try { options.GuiConnection?.LogText?.Invoke("Generowanie populacji startowej"); pop = GenerateStartingPopulation(options.Data, options.PopulationSize); options.GuiConnection?.LogText?.Invoke("Sortowanie"); pop.Sort((x, y) => y.fitness.CompareTo(x.fitness)); best = pop[0].indiv; int iter = 0; while (iter < options.IterationCount) { options.GuiConnection?.LogText?.Invoke($"Osobnik alpha o F = {pop[0].fitness}"); options.GuiConnection?.LogText?.Invoke($"Iteracja: {iter}, generowanie nowej populacji"); pop = GenerateNewPopulation(pop, options); for (int i = 0; i < pop.Count; i++) { if (ThreadSafeRandom.GetRandomDouble() < options.MutationChance) { if (options.GuiConnection != null) { prev = $"{string.Join(',', pop[i].indiv)}, F = {pop[i].fitness}"; } int index1 = ThreadSafeRandom.ThisThreadsRandom.Next(dataCount); int index2 = ThreadSafeRandom.ThisThreadsRandom.Next(dataCount); pop[i].indiv.Swap(index1, index2); pop[i] = (pop[i].indiv, CalculateFitness(pop[i].indiv, options.Data)); options.GuiConnection?.LogText?.Invoke($" Mutacja: i = {i} | {prev} -> {string.Join(',', pop[i].indiv)}, F = {pop[i].fitness}"); } } options.GuiConnection?.LogText?.Invoke(" Sortowanie"); pop.Sort((x, y) => y.fitness.CompareTo(x.fitness)); best = pop[0].indiv; iter += 1; options.CancellationToken.ThrowIfCancellationRequested(); } } catch (OperationCanceledException) { imethodoptions.GuiConnection?.LogText("Przerwano wykonwanie zadania"); } stopwatch.Stop(); options.GuiConnection?.LogText?.Invoke($"Koniec : {DateTime.Now:HH:mm:ss.fff}"); minTardiness = options.Data.JobsFromIndexList(best).CountPenalty(); return(best, minTardiness); }