private ScheduleChromosome RunOnce(LineSeries lineSeries = null) { var adamChromosome = new ScheduleChromosome(jobShop); var population = new Population(Global.Config.MinPopulationSize, Global.Config.MaxPopulationSize, adamChromosome); var fitness = new ScheduleFitness(); var selection = new NonDeterministicTournamentSelection(Global.Config.TournamentSelectionProbability); var crossover = new SchedulesCrossover(new CycleCrossover()); var mutation = new ScheduleMutation(Global.Config.MutationPerGeneProbability, new ReverseSequenceMutation()); var geneticAlgorithm = new GeneticSharp.Domain.GeneticAlgorithm(population, fitness, selection, crossover, mutation) { Termination = new GenerationNumberTermination(Global.Config.GenerationsCount), MutationProbability = Global.Config.MutationProbability, CrossoverProbability = Global.Config.CrossoverProbability, OperatorsStrategy = new JobShopOperatorStrategy(), Reinsertion = new JobShopReinsertion( new EliteSelection(), new Elitism(Global.Config.ElitismPercent), fitness ) }; var stopWatch = new Stopwatch(); if (adaptive) { geneticAlgorithm.GenerationRan += (sender, e) => AdaptMutationProbability(geneticAlgorithm);; } geneticAlgorithm.GenerationRan += (sender, e) => { Print(geneticAlgorithm.Population, stopWatch.Elapsed); }; // plot the model if (PlotModel != null) { geneticAlgorithm.GenerationRan += (sender, e) => { lineSeries.Points.Add(new DataPoint(geneticAlgorithm.Population.GenerationsNumber, ((ScheduleChromosome)geneticAlgorithm.Population.BestChromosome).ScheduleLength.Value)); }; } geneticAlgorithm.GenerationRan += (o, e) => GenerationRan?.Invoke(geneticAlgorithm.Population.CurrentGeneration); if (Global.Config.ThreadsCount > 1) { geneticAlgorithm.TaskExecutor = new ParallelTaskExecutor() { MinThreads = 1, MaxThreads = Global.Config.ThreadsCount }; } stopWatch.Start(); geneticAlgorithm.Start(); stopWatch.Stop(); return((ScheduleChromosome)geneticAlgorithm.BestChromosome); }
public void SetUp() { var jobShop = new JobShopLoader().Load("TestExamples/test1.in", false); chromosome = new ScheduleChromosome(jobShop); var machineChromosome1 = new MachineChromosome(new int[] { 4, 5, 0, 2 }.Select(x => jobShop.Operations[x]).ToArray()); chromosome.ReplaceGene(0, new Gene(machineChromosome1)); var machineChromosome2 = new MachineChromosome(new int[] { 1, 3 }.Select(x => jobShop.Operations[x]).ToArray()); chromosome.ReplaceGene(1, new Gene(machineChromosome2)); }
/// <summary> /// Creates graph from specified chromosome. /// </summary> /// <param name="chromosome"></param> /// <returns></returns> public DiGraph <Operation> CreateGraph(ScheduleChromosome chromosome) { // dictionary mapping first operation to its successor var machineOperationsDictionary = new Dictionary <Operation, List <Operation> >(); foreach (var machineChromosome in chromosome.GetGenes().Select(x => x.Value).Cast <MachineChromosome>().Where(x => x.Length >= 2)) { var machineOperations = machineChromosome.GetGenes().Select(x => x.Value).Cast <Operation>().ToArray(); for (int i = 0; i < machineOperations.Length; i++) { var operations = new List <Operation>(); for (int j = i + 1; j < machineOperations.Length; j++) { // do not add operations on the same jobs (they have no reason) if (machineOperations[j].JobId == machineOperations[i].JobId) { continue; } operations.Add(machineOperations[j]); } machineOperationsDictionary.Add(machineOperations[i], operations); } } var graph = new DiGraph <Operation>(); // create source and target var source = graph.AddVertex(new Operation(int.MinValue, int.MinValue, int.MinValue, int.MinValue, 0)); var target = graph.AddVertex(new Operation(int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, 0)); // create vertices according to jobs descriptions and connect them to each other and to the source and target foreach (var job in chromosome.JobShop.Jobs) { var lastOperationVertex = source; // connect one path foreach (var operation in job.Operations) { var currentOperationVertex = graph.AddVertex(operation); graph.AddEdge(lastOperationVertex.Value, currentOperationVertex.Value); lastOperationVertex = currentOperationVertex; } // add edge from last on the path to target graph.AddEdge(lastOperationVertex.Value, target.Value); } // add edges between all machines oriented base on the schedule // we need to add edges between all of them so if we rotate an edge we don't have to add new missing edges // between some machines foreach (var operation in chromosome.JobShop.Operations) { if (machineOperationsDictionary.TryGetValue(operation, out var nextMachineOperations)) { foreach (var nextMachineOperation in nextMachineOperations) { graph.AddEdge(operation, nextMachineOperation); } } } return(graph); }