Example #1
0
        public static void Main()
        {
            // define cost matrix

            Double INF = Double.PositiveInfinity;
               /* Double[,] costMatrix = new Double[,]
            {
                { INF,   2.0,    4.0,   22.0,    2.0,    INF},
                { 2.0,   INF,    8.0,   15.0,   13.0,   10.0},
                { 4.0,   8.0,    INF,    5.0,    2.0,    INF},
                {22.0,  15.0,    5.0,    INF,   11.0,   12.0},
                { 2.0,  13.0,    2.0,   11.0,    INF,   14.0},
                { INF,  10.0,    INF,   12.0,   14.0,    INF},
            };
            */
            Double[,] costMatrix = new Double[,]
            {
                { INF,   2.0,    INF,   INF,    7.0},
                { 2.0,   INF,    1.0,   3.0,   INF},
                { INF,   1.0,    INF,    1.0,    5.0},
                { INF,  3.0,    1.0,    INF,   INF},
                { 7.0,  INF,    5.0,   INF,    INF},
            };
            costMatrix = new Double[,]
            {
                { INF,   20.0,  INF,  70.0},
                { 20.0,   INF,    40.0,  INF},
                { INF,   40.0,    INF,50.0},
                { 70.0, INF,    50.0,INF},
            };
            // create prototype chromosome
            PermutationChromosome prototype = new PermutationChromosome(0, costMatrix.GetLength(0) - 1);

            // set prototype's parameters
            prototype.CrossOverStrategy = new PermutationChromosome.CycleCrossOverStrategy();
            prototype.RandomGenerator = new ThreadSafeRandomGenerator();
            prototype.MutationStrategy = new PermutationChromosome.InsertMutationStrategy();
            prototype.Fitness = new TSPFitness(costMatrix);

            // stop condition, keep reference for selecting the leader
            NoChangeStopCondion stopCondition = new NoChangeStopCondion(10);

            // create population
            DefaultPopulation population = new DefaultPopulation(prototype, 40);

            // set population's parameters
            population.SelectionStrategy
                = new StochasticUniversalSamplingStrategy(new FixedSizeStrategy(40), new ThreadSafeRandomGenerator());
            population.RandomGenerator = new ThreadSafeRandomGenerator();
            population.StopCondition = stopCondition;

            // perform util the stop condition returns false
            while (population.NextGeneration())
                ;

            // print the result
            System.Console.WriteLine("Best fitness: " + (1.0 / stopCondition.Leader.Evaluate()));
            System.Console.WriteLine(stopCondition.Leader.ToString());
            System.Console.ReadKey();
        }
            /// <summary>
            /// Realizuje algorytm mutacji na zadanym chromosomie.
            /// </summary>
            /// <param name="chromosome">Chromosom, który zostanie poddany mutacji.</param>
            public void Mutate(PermutationChromosome chromosome)
            {
                Int32 mutationPoint1 = chromosome.RandomGenerator.Next(0, chromosome.Data.Length);
                Int32 mutationPoint2 = chromosome.RandomGenerator.Next(0, chromosome.Data.Length);

                if (mutationPoint1 != mutationPoint2)
                {
                    Int32 mpLower = Math.Min(mutationPoint1, mutationPoint2);
                    Int32 mpUpper = Math.Max(mutationPoint1, mutationPoint2);

                    Array.Reverse(chromosome.Data, mpLower, mpUpper - mpLower);
                }
            }
Example #3
0
 /// <summary>
 /// Dokonuje oceny dopasowania.
 /// </summary>
 /// <param name="chromosome">Oceniany chromosom.</param>
 /// <returns>Ocena dopasowania.</returns>
 public double Evaluate(PermutationChromosome chromosome)
 {
     Int32[] permutation = chromosome.Data;
     #if DEBUG
     Debug.Assert(costMatrix.GetLength(0) == costMatrix.GetLength(1));
     Debug.Assert(costMatrix.GetLength(0) == permutation.Length);
     Debug.Assert(permutation.Min() == 0);
     Debug.Assert(permutation.Max() == permutation.Length - 1);
     #endif
     Double cost = 0.0;
     for (Int32 i = 1; i < permutation.Length; ++i)
     {
         cost += costMatrix[permutation[i - 1], permutation[i]];
     }
     cost += costMatrix[permutation[permutation.Length - 1], permutation[0]];
     return Double.IsInfinity(cost) ? 0.0 : 1.0 / cost;
 }
            /// <summary>
            /// Realizuje algorytm mutacji na zadanym chromosomie.
            /// </summary>
            /// <param name="chromosome">Chromosom, który zostanie poddany mutacji.</param>
            public void Mutate(PermutationChromosome chromosome)
            {
                Int32 mutationPoint1 = chromosome.RandomGenerator.Next(0, chromosome.Data.Length);
                Int32 mutationPoint2 = chromosome.RandomGenerator.Next(0, chromosome.Data.Length);

                if (mutationPoint1 != mutationPoint2)
                {
                    Int32 mpLower = Math.Min(mutationPoint1, mutationPoint2);
                    Int32 mpUpper = Math.Max(mutationPoint1, mutationPoint2);

                    for (Int32 i = mpLower; i < mpUpper; ++i)
                    {
                        Int32 value = chromosome.Data[i];
                        Int32 point = chromosome.RandomGenerator.Next(i, mpUpper);
                        chromosome.Data[i] = chromosome.Data[point];
                        chromosome.Data[point] = value;
                    }
                }
            }
            /// <summary>
            /// Krzyżuje dwa osobniki modyfikując je.
            /// </summary>
            /// <param name="ch1">Osobnik pierwszy.</param>
            /// <param name="ch2">Osobnik drugi.</param>
            public void CrossOver(PermutationChromosome ch1, PermutationChromosome ch2)
            {
                #if DEBUG
                Debug.Assert(ch1.RandomGenerator.GetType() == ch2.RandomGenerator.GetType());
                Debug.Assert(ch1.CrossOverStrategy.GetType() == ch2.CrossOverStrategy.GetType());
                Debug.Assert(ch1.HasSameData(ch2));
                #endif
                Int32[] child1 = new Int32[ch1.Data.Length];
                Int32[] child2 = new Int32[ch2.Data.Length];

                Boolean[] visited = new Boolean[ch2.Data.Length];

                Int32 pos = 0;
                do
                {
                    // odd circle
                    pos = Array.IndexOf(visited, false);
                    while (pos >= 0 && false == visited[pos])
                    {
                        visited[pos] = true;

                        child1[pos] = ch1.Data[pos];
                        child2[pos] = ch2.Data[pos];

                        pos = Array.IndexOf(ch1.Data, ch2.Data[pos]);
                    }

                    // even circle
                    pos = Array.IndexOf(visited, false);
                    while (pos >= 0 && false == visited[pos])
                    {
                        visited[pos] = true;

                        child1[pos] = ch2.Data[pos];
                        child2[pos] = ch1.Data[pos];

                        pos = Array.IndexOf(ch2.Data, ch1.Data[pos]);
                    }
                } while (Array.IndexOf(visited, false) >= 0);

                ch1.Data = child1;
                ch2.Data = child2;
            }
            /// <summary>
            /// Krzyżuje dwa osobniki modyfikując je.
            /// </summary>
            /// <param name="ch1">Osobnik pierwszy.</param>
            /// <param name="ch2">Osobnik drugi.</param>
            public void CrossOver(PermutationChromosome ch1, PermutationChromosome ch2)
            {
                #if DEBUG
                Debug.Assert(ch1.RandomGenerator.GetType() == ch2.RandomGenerator.GetType());
                Debug.Assert(ch1.CrossOverStrategy.GetType() == ch2.CrossOverStrategy.GetType());
                Debug.Assert(ch1.HasSameData(ch2));
                #endif
                Int32 crossOverPoint1 = ch1.RandomGenerator.Next(0, ch1.Data.Length);
                Int32 crossOverPoint2 = ch1.RandomGenerator.Next(0, ch1.Data.Length);

                if (crossOverPoint1 != crossOverPoint2)
                {
                    Int32 copLower = Math.Min(crossOverPoint1, crossOverPoint2);
                    Int32 copUpper = Math.Max(crossOverPoint1, crossOverPoint2);

                    Int32[] data1 = PartiallyMappedCrossOver(ch1.Data, ch2.Data, copLower, copUpper);
                    Int32[] data2 = PartiallyMappedCrossOver(ch2.Data, ch1.Data, copLower, copUpper);

                    ch1.Data = data1;
                    ch2.Data = data2;
                }
            }
            /// <summary>
            /// Realizuje algorytm mutacji na zadanym chromosomie.
            /// </summary>
            /// <param name="chromosome">Chromosom, który zostanie poddany mutacji.</param>
            public void Mutate(PermutationChromosome chromosome)
            {
                Int32 mutationPoint1 = chromosome.RandomGenerator.Next(0, chromosome.Data.Length);
                Int32 mutationPoint2 = chromosome.RandomGenerator.Next(0, chromosome.Data.Length);

                if (mutationPoint1 != mutationPoint2)
                {
                    Int32 mpLower = Math.Min(mutationPoint1, mutationPoint2);
                    Int32 mpUpper = Math.Max(mutationPoint1, mutationPoint2);

                    Int32 mutationValueLower = chromosome.Data[mpLower];
                    Int32 mutationValueUpper = chromosome.Data[mpUpper];

                    Int32 position = mpUpper;
                    while ((--position) > mpLower)
                    {
                        chromosome.Data[position + 1] = chromosome.Data[position];
                    }
                    chromosome.Data[mpLower + 0] = mutationValueLower;
                    chromosome.Data[mpLower + 1] = mutationValueUpper;
                }
            }
 /// <summary>
 /// Porównuje allele dwóch chromosomów.
 /// </summary>
 /// <param name="chromosome">Chromosom, z którym jest realizowane porównywanie.</param>
 /// <returns>True, jeżeli oba chromosomy mają takie same allele na odpowiadających sobie pozycjach.</returns>
 private bool HasSameData(PermutationChromosome chromosome)
 {
     foreach (Int32 value in chromosome.Data)
     {
         if (false == Data.Contains(value))
         {
             return false;
         }
     }
     return true;
 }
        /// <summary>
        /// Kopiuje instancję obiektu chromosomu.
        /// </summary>
        /// <returns></returns>
        public IChromosome Clone()
        {
            PermutationChromosome chromosome = new PermutationChromosome(Data);

            chromosome.RandomGenerator = RandomGenerator;
            chromosome.MutationStrategy = MutationStrategy;
            chromosome.CrossOverStrategy = CrossOverStrategy;
            chromosome.Fitness = Fitness;

            return chromosome;
        }
Example #10
0
        private void startProcessingButton_Click(object sender, EventArgs e)
        {
            if (worker.IsBusy)
            {
                worker.CancelAsync();
                return;
            }
            if (costMatrix == null)
            {
                MessageBox.Show("Macierz jest pusta. Uzupełnij graf.");
                return;
            }

            /*
             * Prototyp chromosomu.
             */
            PermutationChromosome chromosomePrototype = new PermutationChromosome(0, costMatrix.GetLength(0) - 1);
            chromosomePrototype.MutationStrategy = (PermutationChromosome.IMutationStrategy)mutationAlgorithmComboBox.SelectedItem;
            chromosomePrototype.CrossOverStrategy = (PermutationChromosome.ICrossOverStrategy)crossoverAlgorithmComboBox.SelectedItem;
            chromosomePrototype.RandomGenerator = new ThreadSafeRandomGenerator();
            chromosomePrototype.Fitness = new TSPFitness(costMatrix);

            /*
             * Populacja
             */
            population = new DefaultPopulation(chromosomePrototype, (UInt32)populationSpinner.Value);
            population.RandomGenerator = new ThreadSafeRandomGenerator();
            population.StopCondition = stopCondition;

            /*
             * Selekcja
             */
            ISelectionSizeStrategy selectionSizeStrategy = selectionSizeCheckBox.Checked ? (ISelectionSizeStrategy)new ProportionalSizeStrategy((Double)selectionSizeSpinner.Value) : (ISelectionSizeStrategy)new FixedSizeStrategy((UInt32)selectionSizeSpinner.Value);
            switch ((SelectionStrategies)selectionAlgorithmComboBox.SelectedValue)
            {
                case SelectionStrategies.NoSelectionStrategy:
                    population.SelectionStrategy = new NoSelectionStrategy();
                    break;
                case SelectionStrategies.RouletteWheelSelectionStrategy:
                    population.SelectionStrategy = new RouletteWheelSelectionStrategy(selectionSizeStrategy, new ThreadSafeRandomGenerator());
                    break;
                case SelectionStrategies.StochasticUniversalSamplingStrategy:
                    population.SelectionStrategy = new StochasticUniversalSamplingStrategy(selectionSizeStrategy, new ThreadSafeRandomGenerator());
                    break;
                case SelectionStrategies.TournamentSelectionStrategy:
                    ISelectionSizeStrategy tournamentGroupSizeStrategy = tournamentGroupSizeCheckBox.Checked ? (ISelectionSizeStrategy)new ProportionalSizeStrategy((Double)tournamentGroupSizeSpinner.Value) : (ISelectionSizeStrategy)new FixedSizeStrategy((UInt32)tournamentGroupSizeSpinner.Value);
                    population.SelectionStrategy = new TournamentSelectionStrategy(selectionSizeStrategy, tournamentGroupSizeStrategy, new ThreadSafeRandomGenerator());
                    break;
                default:
                    return;
            }

            ISelectionSizeStrategy eliteSizeStrategy = eliteSizeCheckBox.Checked ? (ISelectionSizeStrategy)new ProportionalSizeStrategy((Double)eliteSizeSpinner.Value) : (ISelectionSizeStrategy)new FixedSizeStrategy((UInt32)eliteSizeSpinner.Value);
            ISelectionSizeStrategy survivorSizeStrategy = eliteSizeCheckBox.Checked ? (ISelectionSizeStrategy)new ProportionalSizeStrategy((Double)survivorSizeSpinner.Value) : (ISelectionSizeStrategy)new FixedSizeStrategy((UInt32)survivorSizeSpinner.Value);
            switch ((ModifierCombination)selecitonModifierComboBox.SelectedValue)
            {
                case ModifierCombination.None:
                    break;
                case ModifierCombination.Elite:
                    population.SelectionStrategy = new EliteSelectionStrategyAdapter(population.SelectionStrategy, eliteSizeStrategy);
                    break;
                case ModifierCombination.Survivor:
                    population.SelectionStrategy = new SurvivorSelectionStrategyAdapter(population.SelectionStrategy, survivorSizeStrategy);
                    break;
                case ModifierCombination.EliteSurvivor:
                    population.SelectionStrategy = new EliteSelectionStrategyAdapter(population.SelectionStrategy, eliteSizeStrategy);
                    population.SelectionStrategy = new SurvivorSelectionStrategyAdapter(population.SelectionStrategy, survivorSizeStrategy);
                    break;
                case ModifierCombination.SurvivorElite:
                    population.SelectionStrategy = new SurvivorSelectionStrategyAdapter(population.SelectionStrategy, survivorSizeStrategy);
                    population.SelectionStrategy = new EliteSelectionStrategyAdapter(population.SelectionStrategy, eliteSizeStrategy);
                    break;
            }

            /*
             * Warunek stopu. Zachować referencję dla wskazania lidera.
             */
            stopCondition = new NoChangeStopCondion((UInt32)stopSpinner.Value);
            population.StopCondition = stopCondition;

            /*
             * Rozpocznij przetwarzanie.
             */
            startProcessingButton.Text = "Stop";
            TimeStart = DateTime.Now;
            worker.RunWorkerAsync(stopCondition);
        }