Esempio n. 1
0
        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);
        }