예제 #1
0
        //Mutasyon Fonksiyonu

        public void Mutation(TspFile chromosome, double probability)
        {
            Random r = new Random();
            double rndProbability = r.NextDouble();

            if (rndProbability <= probability) //Mutasyon olasiligi, random sayimizdan buyukse mutasyon islemi gerceklesir
            {
                // random pozisyondaki sehri 1 arttiriyoruz ama bunu gecici bir degiskende tutuyoruz.
                int mPosition = r.Next(0, chromosome.cityList.Count);
                int temp      = chromosome.cityList[mPosition].index;
                int temp2     = temp + 1;

                //degisecek sehri bulma
                for (int i = 0; i < chromosome.cityList.Count; i++)
                {
                    //degeri artirilan sehri buldugmuzda ve o sehir, sehir sayimizdan kucuk oldugunda
                    if (chromosome.cityList[i].index == temp2 && temp2 <= chromosome.cityList.Count)
                    {
                        chromosome.cityList[i].index = temp;    //degeri 1 artan sehiri 1 eksiltiyoruz
                        chromosome.cityList[mPosition].index++; //mutasyon gecirecek gercek geni 1 arttiriyoruz
                        break;
                    }
                }
            }
        }
예제 #2
0
        //
        //Ilk populasyonu olusturma
        public List <TspFile> CreateFirstPopulation(TspFile firstTspFile, int populationSize)
        {
            List <TspFile> populationList = new List <TspFile>();

            for (int i = 0; i < populationSize; i++)
            {
                List <City> cityPopulation = new List <City>(firstTspFile.cityList);
                Shuffle <City>(cityPopulation);
                TspFile tspFile = new TspFile();
                tspFile.cityList = cityPopulation;
                populationList.Add(tspFile);
            }
            return(populationList);
        }
예제 #3
0
        void SaveFile(TspFile result, double bestFitness)
        {
            StreamWriter sw = new StreamWriter(tspFile.name + ".tour");

            sw.WriteLine("Name : " + tspFile.name + ".tour");
            sw.WriteLine("Comment : " + bestFitness);
            sw.WriteLine("TYPE : TOUR");
            sw.WriteLine("DIMENSION : " + tspFile.dimension);
            sw.WriteLine("TOUR_SECTION");
            for (int i = 0; i < result.cityList.Count; i++)
            {
                sw.WriteLine(result.cityList[i].index);
            }
            sw.WriteLine("-1");
            sw.WriteLine("EOF");
            sw.Close();
        }
예제 #4
0
        //------Parent seciminde kullandigimiz Rank Selection yontemi-------------
        //Algoritma en kotuden en iyiye fitness degerlerini siralayip,
        //sirasina gore  i.sira / (n(n+1))/2 formulu ile hesapliyor.
        //Boylelikle en iyi fitness en buyuk olasiliga sahip oluyor.
        public TspFile[] RankSelection(List <TspFile> populationList)
        {
            Dictionary <double, double[]> rank = new Dictionary <double, double[]>();

            double n = (populationList.Count * (populationList.Count + 1)) / 2;
            double cumulativeRankSum = 0; // kumulatif toplam urettigimiz random sayinin nereye dustugunu bulmak icin tanimlandi.


            for (int i = 1; i <= populationList.Count; i++)
            {
                rank.Add(i, new double[] { i / n, cumulativeRankSum + i / n });
                cumulativeRankSum += i / n;
            }

            Random r  = new Random();
            double p1 = r.Next(0, int.MaxValue) / (double)int.MaxValue; //0 ile 1 arasinda sayi uretmek icin kullandik.
            double p2 = r.Next(0, int.MaxValue) / (double)int.MaxValue;

            TspFile parent1 = new TspFile();
            TspFile parent2 = new TspFile();

            parent1 = populationList[0];
            parent2 = populationList[0];
            for (int i = rank.Count; i >= 1; i--)
            {
                rank.TryGetValue(i, out double[] value);
                if (p1 >= value[1])
                {
                    parent1 = populationList[i];
                    break;
                }
            }
            for (int i = rank.Count; i >= 1; i--)
            {
                rank.TryGetValue(i, out double[] value);
                if (p2 >= value[1])
                {
                    parent2 = populationList[i];
                    break;
                }
            }

            return(new TspFile[] { parent1, parent2 });
        }
예제 #5
0
        //Fitness degerlerini dosya tipine gore hesaplayan fonksiyon
        //fitness fonksiyonumuz uzaklik hesabi oldugundan problemin tipi fitness fonksiyonumuzu da belirliyor.
        public void CalculateFitnessFunction(TspFile tspFile, EdgeWeightType edgeWeightType)
        {
            switch (edgeWeightType)
            {
            case EdgeWeightType.EUC_2D:
                tspFile.EuclidDistance();
                break;

            case EdgeWeightType.MAX_2D:
                tspFile.MaximumDistance();
                break;

            case EdgeWeightType.MAN_2D:
                tspFile.ManhattanDistance();
                break;

            case EdgeWeightType.CEIL_2D:
                tspFile.CeilDistance();
                break;

            default:
                break;
            }
        }
예제 #6
0
        // Dosya okuma Fonksiyonu
        //Butun satirlari okuyup lines`a atiyor.
        // daha sonra string islemleri ile tspfile classina tanimliyoruz.
        void ReadFile()
        {
            listBox1.Items.Clear();
            OpenFileDialog openFileDialog = new OpenFileDialog();

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string[] lines = File.ReadAllLines(openFileDialog.FileName);
                tspFile = new TspFile();
                bool   startCoordinat = false;
                bool   rightFile      = true;
                char[] seperators     = new char[] { ' ' };

                for (int i = 0; i < lines.Length; i++)
                {
                    string line = lines[i].Trim();

                    if (line != "NODE_COORD_SECTION" && startCoordinat == false)
                    {
                        string before = line.Split(':')[0].Trim();
                        string after  = line.Split(':')[1].Trim();


                        if (before == "NAME")
                        {
                            tspFile.name = after;
                        }
                        else if (before == "TYPE")
                        {
                            if (after == "TSP")
                            {
                                tspFile.type = after;
                            }
                            else
                            {
                                rightFile = false;  /////// Dosya TSP degil ise yanlis dosya tipi
                                break;
                            }
                        }
                        else if (before == "COMMENT")
                        {
                            tspFile.comment = after;
                        }
                        else if (before == "DIMENSION")
                        {
                            tspFile.dimension = int.Parse(after);
                        }
                        else if (before == "EDGE_WEIGHT_TYPE") //tipi 2d olmayanlari okumuyor.
                        {
                            try
                            {
                                tspFile.edgeWeightType = (EdgeWeightType)Enum.Parse(typeof(EdgeWeightType), after);
                            }
                            catch (Exception)
                            {
                                rightFile = false;
                                MessageBox.Show("Yanlış Dosya Formatı. Geçerli formatlar EUC_2D - MAX_2D - MAN_2D - CEIL_2D");
                                break;
                            }
                        }
                    }

                    else if (line == "NODE_COORD_SECTION")
                    {
                        startCoordinat = true;
                    }

                    else if (line != "EOF")
                    {
                        line = lines[i].Trim();
                        string[] splitLine = line.Split(seperators, StringSplitOptions.RemoveEmptyEntries);
                        int      index     = int.Parse(splitLine[0]);
                        double   x         = double.Parse(splitLine[1].Replace('.', ','));
                        double   y         = double.Parse(splitLine[2].Replace('.', ','));
                        tspFile.AddCity(index, x, y);
                    }
                }
                if (rightFile) // Dosya tsp ve tipi 2d ise
                {
                    listBox1.Items.Add(tspFile.name);
                    listBox1.Items.Add(tspFile.comment);
                    listBox1.Items.Add(tspFile.type);
                    listBox1.Items.Add(tspFile.dimension);
                    listBox1.Items.Add(tspFile.edgeWeightType);
                    listBox1.Items.Add(tspFile.MaximumDistance());
                    for (int i = 0; i < tspFile.cityList.Count; i++)
                    {
                        listBox1.Items.Add(tspFile.cityList[i].index + ".city " + tspFile.cityList[i].x + " , " + tspFile.cityList[i].y);
                    }
                }
            }
        }
예제 #7
0
        private void btn_run_Click(object sender, EventArgs e)
        {
            chart1.Series.Clear();
            Series series              = chart1.Series.Add("Distance");
            int    iterationNumber     = int.Parse(txt_iterationNumber.Text);
            int    populationSize      = int.Parse(txt_populationSize.Text);
            double mutationProbability = double.Parse(txt_mutationProbability.Text);
            double elitismRatio        = double.Parse(txt_elitismRatio.Text);
            string crossoverType       = combo_crossoverOperator.Text;



            GeneticOperations geneticOperations = new GeneticOperations();
            List <TspFile>    populationList    = geneticOperations.CreateFirstPopulation(tspFile, populationSize);
            List <TspFile>    newPopulationList = new List <TspFile>();
            TspFile           parent1;
            TspFile           parent2;


            for (int j = 0; j < populationList.Count; j++)
            {
                //populasyonun fitness degerlerinin hesaplanmasi
                geneticOperations.CalculateFitnessFunction(populationList[j], tspFile.edgeWeightType);
            }

            // burada popülasyon sıralanacak fitness değerine göre
            populationList.Sort();

            double maxFitness = 0, minFitness = double.MaxValue, meanFitness = 0;


            for (int i = 0; i < iterationNumber; i++)
            {
                newPopulationList.Clear();

                // elitizm
                int elitismCount = (int)(elitismRatio * populationSize);
                for (int j = 1; j <= elitismCount; j++)
                {
                    newPopulationList.Add(populationList[populationList.Count - j]);
                }

                // popülasyonlar oluşturuluyor
                while (newPopulationList.Count <= populationSize)
                {
                    // Popülasyona genetik algoritmalar uygulanıyor
                    TspFile[] parents = geneticOperations.RankSelection(populationList); //Rank Selection yapilmasi, geriye 2 parent donuyor.


                    parent1 = parents[0];
                    parent2 = parents[1];

                    switch (crossoverType)
                    {
                    case "One Point":
                        parents = geneticOperations.OnePointCrossover(parents);
                        break;

                    case "Two Point":
                        parents = geneticOperations.TwoPointCrossover(parents);
                        break;

                    case "Position Based Crossover":     // Bu caprazlama da tek cocuk elde ettigimiz icin 2 kere yapiyoruz
                        parent1    = geneticOperations.PositionBasedCrossover(parents)[0];
                        parent2    = geneticOperations.PositionBasedCrossover(parents)[0];
                        parents[0] = parent1;
                        parents[1] = parent2;
                        break;
                    }

                    geneticOperations.Mutation(parent1, mutationProbability);
                    geneticOperations.Mutation(parent2, mutationProbability);
                    newPopulationList.AddRange(parents);
                }

                for (int j = 0; j < newPopulationList.Count; j++)
                {
                    geneticOperations.CalculateFitnessFunction(newPopulationList[j], tspFile.edgeWeightType);

                    maxFitness   = Math.Max(maxFitness, newPopulationList[j].distance);
                    minFitness   = Math.Min(minFitness, newPopulationList[j].distance);
                    meanFitness += newPopulationList[j].distance;

                    meanFitness /= newPopulationList.Count;
                }

                populationList = new List <TspFile>(newPopulationList);
                populationList.Sort();


                series.Points.Add(minFitness);
            }

            TspFile result = new TspFile();

            minFitness = double.MaxValue;
            for (int k = 0; k < populationList.Count; k++)
            {
                listBox1.Items.Add(populationList[k].distance);
                if (minFitness > populationList[k].distance)
                {
                    minFitness = populationList[k].distance;
                    result     = populationList[k];
                }
            }

            /*
             * double max = 0, min = double.MaxValue, mean = 0;
             * for (int k = 0; k < populationList.Count; k++)
             * {
             *  max = Math.Max(max, populationList[k].distance);
             *  min = Math.Min(min, populationList[k].distance);
             *  mean += populationList[k].distance;
             * }
             * mean /= populationList.Count;
             * listBox1.Items.Add("maximum fitness " + max);
             * listBox1.Items.Add("minimum fitness " + min);
             * listBox1.Items.Add("mean fitness " + mean);
             *
             */

            /*
             * for (int j = 0; j < populationList.Count; j++)
             * {
             *  geneticOperations.CalculateFitnessFunction(populationList[j], tspFile.edgeWeightType);
             * }
             */
            this.Text = "Bitti";
            SaveFile(result, minFitness);
        }
예제 #8
0
        //Pozisyon bazli Crossover Fonksiyonu
        //Parent1`den Rastgele secilen pozisyonlardaki genler(sehirler) cocuk kromozoma aktarilir.
        //parent2`den sirasiyla cocukta olmayan genler aktarilirken olanlar goz ardi edilir.
        public TspFile[] PositionBasedCrossover(TspFile[] parents)
        {
            TspFile    parent1       = parents[0];
            TspFile    parent2       = parents[1];
            Random     r             = new Random();
            List <int> positionArray = new List <int>();
            int        randomNumber  = r.Next(0, parent1.cityList.Count); // random kac tane sayi gelecegini yine random seciyoruz.

            for (int i = 0; i < randomNumber; i++)
            {
                positionArray.Add(r.Next(0, parent1.cityList.Count)); // Bu listeye random sayilari atiyoruz.
            }

            //Rank Selection`dan gelen cocuklar
            TspFile child1 = new TspFile();
            TspFile child2 = new TspFile();

            for (int i = 0; i < parent1.cityList.Count; i++)
            {
                City city = new City
                {
                    index = 0
                };
                child1.cityList.Add(city);
            }

            //Burda sehrin tekrar edip etmedigini kontrol ediyoruz.
            for (int i = 0; i < parent1.cityList.Count; i++)
            {
                if (positionArray.Exists(find =>
                {
                    if (find == i)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }))
                {
                    child1.cityList[i] = parent1.cityList[i];
                }
            }

            for (int j = 0; j < parent1.cityList.Count; j++)
            {
                if (!child1.cityList.Exists(city =>
                {
                    if (city.index == parent2.cityList[j].index)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }))
                {
                    for (int k = 0; k < child1.cityList.Count; k++)
                    {
                        if (child1.cityList[k].index == 0)
                        {
                            child1.cityList[k] = parent2.cityList[j];
                            break;
                        }
                    }
                }
            }
            // child2 yapılacak?
            return(new TspFile[] { child1, child2 });
        }
예제 #9
0
        //Iki Noktali Caprazlama Fonksiyonu
        //Rank`tangelen 2 adet parent, random iki noktadan bolunuyor.
        public TspFile[] TwoPointCrossover(TspFile[] parents)
        {
            TspFile parent1 = parents[0];
            TspFile parent2 = parents[1];
            Random  r       = new Random();
            int     positionMin;
            int     positionMax;

            do
            {
                positionMin = r.Next(1, parent1.cityList.Count); // İlk kesme noktası
                positionMax = r.Next(1, parent1.cityList.Count); // İkinci kesme noktası
            } while (positionMax == positionMin);                //eger iki noktada esit gelirse diye

            if (positionMin > positionMax)                       //eger min deger max degerden buyuk olursa isimler dogru olmasi adina yer degistirme yapiyoruz.
            {
                int temp = positionMin;
                positionMin = positionMax;
                positionMax = temp;
            }

            TspFile child1 = new TspFile();
            TspFile child2 = new TspFile();

            // Crossover Child 1
            //child1 = [----parent1----/----parent2----/----parent1---]  yapisinin olusmasi icin gerekli ayristirma
            //         [0--------------min-------------max---------sehirSayisi]
            child1.cityList.AddRange(parent1.cityList.GetRange(0, positionMin));
            // child1.cityList.AddRange(parent2.cityList.GetRange(positionMin + 1, positionMax - positionMin));
            child1.cityList.AddRange(parent1.cityList.GetRange(positionMax, parent2.cityList.Count - positionMax));
            int location = positionMin;

            for (int i = 0; i < parent2.cityList.Count; i++)
            {
                if (!child1.cityList.Exists(city =>
                {
                    if (city.index == parent2.cityList[i].index)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }))
                {
                    child1.cityList.Insert(location++, parent2.cityList[i]);
                }
            }

            // Crossover Child 2
            //child2 = [----parent2----/----parent1----/----parent2---]
            child2.cityList.AddRange(parent2.cityList.GetRange(0, positionMin));
            // child2.cityList.AddRange(parent1.cityList.GetRange(positionMin + 1, positionMax - positionMin));
            child2.cityList.AddRange(parent2.cityList.GetRange(positionMax, parent2.cityList.Count - positionMax));
            location = positionMin;
            for (int i = 0; i < parent1.cityList.Count; i++)
            {
                if (!child2.cityList.Exists(city =>
                {
                    if (city.index == parent1.cityList[i].index)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }))
                {
                    child2.cityList.Insert(location++, parent1.cityList[i]);
                }
            }
            return(new TspFile[] { child1, child2 });
        }
예제 #10
0
        //Tek Noktali Caprazlama Fonksiyonu
        //Rank`tangelen 2 adet parent, random bir noktadan bolunuyor.
        public TspFile[] OnePointCrossover(TspFile[] parents)
        {
            TspFile parent1  = parents[0];
            TspFile parent2  = parents[1];
            Random  r        = new Random();
            int     position = r.Next(1, parent1.cityList.Count);
            TspFile child1   = new TspFile();
            TspFile child2   = new TspFile();

            // Crossover Child 1
            //ilk cocuga 1. parent`in ilk parcasi + 2.parent`in ikinci parcasi ekleniyor + 2. parent'in seçilmeyen parçaları da ekleniyor
            child1.cityList.AddRange(parent1.cityList.GetRange(0, position));
            for (int i = position; i < parent2.cityList.Count; i++)
            {
                //Bu surecte tekrar eden sehirlerin kontrolu saglaniyor.
                if (!child1.cityList.Exists(city =>
                {
                    if (city.index == parent2.cityList[i].index)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }))
                {
                    child1.cityList.Add(parent2.cityList[i]);
                }
            }
            for (int i = 0; i < position; i++)
            {
                if (!child1.cityList.Exists(city =>
                {
                    if (city.index == parent2.cityList[i].index)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }))
                {
                    child1.cityList.Add(parent2.cityList[i]);
                }
            }


            // Crossover Child 2
            child2.cityList.AddRange(parent2.cityList.GetRange(0, position));
            for (int i = position; i < parent2.cityList.Count; i++)
            {
                if (!child2.cityList.Exists(city =>
                {
                    if (city.index == parent1.cityList[i].index)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }))
                {
                    child2.cityList.Add(parent1.cityList[i]);
                }
            }
            for (int i = 0; i < position; i++)
            {
                if (!child2.cityList.Exists(city =>
                {
                    if (city.index == parent1.cityList[i].index)
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }))
                {
                    child2.cityList.Add(parent1.cityList[i]);
                }
            }

            return(new TspFile[] { child1, child2 });
        }