public void FixChromosomeTest() { var randomizationProviderMock = new Mock <IRandomization>(); randomizationProviderMock.Setup(x => x.GetDouble()).Returns(Global.Config.BackEdgeSwitchOrientationProbability - 10e-6); // fix random sort order of AsShuffledEnumerable randomizationProviderMock.Setup(x => x.GetInt(0, int.MaxValue)).Returns(0); RandomizationProvider.Current = randomizationProviderMock.Object; // breaking the cycle switches orientation of edges (4, 0) and (5, 0) chromosome.FixChromosome(); var topologicalOrder = chromosome.TopologicalOrder; var operations = chromosome.JobShop.Operations; Assert.That(topologicalOrder[0], Is.EqualTo(new Operation(int.MinValue, 0, 0, 0, 0))); Assert.That(topologicalOrder[1], Is.EqualTo(operations[0])); Assert.That(topologicalOrder[2], Is.EqualTo(operations[1])); Assert.That(topologicalOrder[3], Is.EqualTo(operations[3])); Assert.That(topologicalOrder[4], Is.EqualTo(operations[4])); Assert.That(topologicalOrder[5], Is.EqualTo(operations[5])); Assert.That(topologicalOrder[6], Is.EqualTo(operations[2])); Assert.That(topologicalOrder[7], Is.EqualTo(new Operation(int.MaxValue, 0, 0, 0, 0))); var machineChromosomes = chromosome.GetGenes().Select(x => x.Value).Cast <MachineChromosome>().ToList(); var machineChromosome1 = machineChromosomes[0].GetGenes().Select(x => x.Value).Cast <Operation>().ToList(); Assert.That(machineChromosome1[0], Is.EqualTo(operations[0])); Assert.That(machineChromosome1[1], Is.EqualTo(operations[4])); Assert.That(machineChromosome1[2], Is.EqualTo(operations[5])); Assert.That(machineChromosome1[3], Is.EqualTo(operations[2])); var machineChromosome2 = machineChromosomes[1].GetGenes().Select(x => x.Value).Cast <Operation>().ToList(); Assert.That(machineChromosome2[0], Is.EqualTo(operations[1])); Assert.That(machineChromosome2[1], Is.EqualTo(operations[3])); }
/// <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); }