예제 #1
0
        private IIndividual Neighbour(IIndividual solution)
        {
            Ttp1Individual neighbour = null;

            neighbour = solution.DeepCopy() as Ttp1Individual;

            if (neighbour == null)
            {
                Console.WriteLine("Solution passed to Neighbour is not of type TabuTtp1Individual");
                return(null);
            }

            var firstRandomSwapIndex  = RandomNumGenerator.Next(0, neighbour.RoadTaken.Count);
            var secondRandomSwapIndex = RandomNumGenerator.Next(0, neighbour.RoadTaken.Count);

            while (firstRandomSwapIndex == secondRandomSwapIndex)
            {
                secondRandomSwapIndex = RandomNumGenerator.Next(0, neighbour.RoadTaken.Count);
            }

            var tmp = neighbour.RoadTaken[firstRandomSwapIndex];

            neighbour.RoadTaken[firstRandomSwapIndex]  = neighbour.RoadTaken[secondRandomSwapIndex];
            neighbour.RoadTaken[secondRandomSwapIndex] = tmp;

            if (!neighbour.Equals(solution))
            {
                return(neighbour);
            }

            Console.WriteLine("Neighbour equals solution.");
            return(null);
        }
예제 #2
0
        private IIndividual CrossPmx(IIndividual parent1, IIndividual parent2)
        {
            var child = parent1.DeepCopy();

            if (!(parent1 is Ttp1Individual parent1Ttp1) || !(parent2 is Ttp1Individual parent2Ttp1) ||
                !(child is Ttp1Individual childTtp1))
            {
                return(child);
            }
            if (parent1Ttp1.RoadTaken.Count != parent2Ttp1.RoadTaken.Count)
            {
                return(childTtp1);
            }

            var roadLength = parent1Ttp1.RoadTaken.Count;
            var road1      = parent1Ttp1.RoadTaken;
            var road2      = parent1Ttp1.RoadTaken;

            var firstChildFirstCutIndex  = RandomNumGenerator.Next(0, roadLength);
            var firstChildSecondCutIndex = RandomNumGenerator.Next(firstChildFirstCutIndex, roadLength);

            var cutValuesFromIndiv1 =
                road1.GetRange(firstChildFirstCutIndex, firstChildSecondCutIndex - firstChildFirstCutIndex);
            var cutValuesFromIndiv2 = road2
                                      .GetRange(firstChildFirstCutIndex, firstChildSecondCutIndex - firstChildFirstCutIndex)
                                      .Where(valueFromIndiv2 => !cutValuesFromIndiv1.Contains(valueFromIndiv2)).ToList();

            foreach (var value in cutValuesFromIndiv2)
            {
                var currentValueFromIndiv2         = value;
                var valueAtTheSamePositionInIndiv1 =
                    road1[road2.IndexOf(currentValueFromIndiv2)];
                var indexOfThatValueInIndiv2 = road2.IndexOf(valueAtTheSamePositionInIndiv1);

                while (indexOfThatValueInIndiv2 >= firstChildFirstCutIndex ||
                       indexOfThatValueInIndiv2 < firstChildSecondCutIndex)
                {
                    currentValueFromIndiv2         = road1[indexOfThatValueInIndiv2];
                    valueAtTheSamePositionInIndiv1 =
                        road1[road2.IndexOf(currentValueFromIndiv2)];
                    indexOfThatValueInIndiv2 = road2.IndexOf(valueAtTheSamePositionInIndiv1);
                }

                childTtp1.RoadTaken[indexOfThatValueInIndiv2] = value;
            }

            var valuesLeftInIndiv2 = road2.Where(value => !cutValuesFromIndiv1.Contains(value) &&
                                                 !cutValuesFromIndiv2.Contains(value)).ToList();

            var indexInIndiv1 = 0;

            foreach (var valueLeftInIndiv2 in valuesLeftInIndiv2)
            {
                var insertedValue = false;

                while (indexInIndiv1 < roadLength && !insertedValue)
                {
                    var valueFromIndiv1 = childTtp1.RoadTaken[indexInIndiv1];
                    if (cutValuesFromIndiv1.Contains(valueFromIndiv1) || cutValuesFromIndiv2.Contains(valueFromIndiv1))
                    {
                        indexInIndiv1++;
                        continue;
                    }

                    childTtp1.RoadTaken[indexInIndiv1] = valueLeftInIndiv2;
                    indexInIndiv1++;
                    insertedValue = true;
                }
            }

            return(childTtp1);
        }