// Rulet Tekerleği => Uygunluk Değerlerine Göre işlem Yapılır. İlk olarak bütün bireylerin uygunluk değerler toplanır. // Bireyin Uygunluk değerli / Toplam uygunluk değerleri toplamı oranlanır, her bir birey için oran belirlenir // Bu oranlar en küçükten başlayarak sırasıyla yüzdelik dilime pay edilir. // Örn: x1 = 6/359 = 3.67 ,x2 = 25/359 = 62.67 ... bu şekilde ortaya çıkan oranlara göre doldurulur. // Rulet Tekerleği Hazırlandıktan sonra populasyon yeniden oluşturulur. // Populasyon Sayısı kadar random değer üretiriz bu değerler 0-100 arasında olur. // Random değerin isabe ettiği dairenin kısmına karışık gelen birey , yeni populasyona eklenir. // Örn: RandomSay = 75 olsun bu değer yüzdelik kısmında x2 bireyine dekkeliyor çünkü yüzde 60'lık kısmı karışılıyor(küçüklerden başlayarak daireye eklendiği için) // Bu şekilde yeni populasyon oluşturulur private void RouletteWheelMethod() { // Yüzdelik oranın kurulması için bireylerin uygunluk değerlerini topladık double total = PersonList.Sum(s => s.AccordanceValue); // Her birey için yüzdelik kısım hesaplancak // Oranlar RateByTotalAccordanceValues propuna yazılır PersonList.ForEach(person => person.RateByTotalAccordanceValues = (person.AccordanceValue / total));// Uygunluk Değeri / Toplam // Yeniden Populasyon Oluşturulacak , o yüzden ilk önce populasyon temizlenir // Oranları Belirledikten sonra Populasyondaki birey sayısı kadar random değer üretilip 1-100 arasında // Rulet Tekerleğindeki , Üretilen random değere karşılık gelen birey populasyona eklenir List <Person> temp = new List <Person>(); temp.AddRange(PersonList); temp = temp.OrderByDescending(s => s.RateByTotalAccordanceValues).ToList(); // Orana Göre Sıraladık Çünkü Rulet Tekerleğine Bu Şekilde yerleştireceğiz PersonList.Clear(); for (int i = 0; i < PopulationCount; i++) { Person newPerson = new Person(); double randomValue = rn.NextDouble();// 0-1 arasında random değer oluşturuldu, rulet tekerleğide 0-1 arasında // Random değerin işaret ettiği birey bulunarak yeni populasyona eklenir newPerson.Value = PersonForRouletteWheelPoint(randomValue, temp); PersonList.Add(newPerson); // Bireyi populasyona Ekledik } this.PurposeFunction(); // Uygunluk değerleri yeni bireylere göre güncellendi }
// Amaç Fonksiyonu => "PersonList" Listesindeki Değerlere göre Uygunluk değerini hesaplar private void PurposeFunction() { // Her bir birey için uygunluk değeri hesaplanır PersonList.ForEach(person => person.AccordanceValue = PurposeFunctionCalculate(person.Value)); // Uygunluk değerine Göre Sıralama PersonList = PersonList.OrderByDescending(s => s.AccordanceValue).ToList(); }
// Çaprazlama => Tek noktalı çaprazlama yapılıyor. // Çaprazlama yaparken Sayılar Bit'e dönüştürülür. Ve bu orana göre bir çaprazlama yapılır // Örn: x1 = [1,1,1,1,1] ile x2 = [0,0,0,0,0] iki bireyimiz olsun. Bu oran da 0.6 olsun bu durumda ; // Yeni Birey(x1)=> x1'in 0.6sına kadar olan kısmı ve x2'in 0.6'sından sonra olan kısmı yani => [1,1,1,0,0] // Yeni Birey(x2))=> [0,0,0,1,1] olur // Her 2 Birey İçin Yapılır, bundan Önce hepsi büyükten küçüğe sıralanır private void CrossOver() { // İlk önce bireylerin kromozom yapısı çıkartılır // Her bir birey bite dönüştürülür ve değeri tanımlanır // Önemli => Bireyleri çaprazlarken uygunluk değerine göre çaprazlancağı için ilk önce uygunluk değerlerine göre sıralandı PersonList = PersonList.OrderByDescending(s => s.AccordanceValue).ToList(); PersonList.ForEach(person => person.BitsValue = ConverToBinary(Math.Abs(person.Value))); List <Person> temp = new List <Person>(); // Çaprazlamayı 2 birey arasında yapacağımız için populasyon sayısı tek ise sondaki elemanı almıyacağız, o yüzden tek olur ise 1 eksilttik int length = PopulationCount % 2 == 0 ? PopulationCount : PopulationCount - 1; // Girilen Çaprazlama oranına göre kromozomdaki bölüm noktası // => Örn: 5 bitlik ise crossRate = 0.6 ise 3.bit hedef noktaso olur // Anlamı ilk bireyin => ilk 3 bitini al , 2.bireyin => 3.bitten sonrakini al int targetPoint = Convert.ToInt32(Math.Round((CrossProbability * BitCount), 0)); // 2 Birey Çaprazlamaya tutulacağı için döngüyü 2 şer arttırdık for (int i = 0; i < length; i = i + 2) { // Çaprazlama İşlemine tabi tutlacak Bireyler Person p1 = PersonList.ElementAt(i); // İlk birey Person p2 = PersonList.ElementAt(i + 1); // Bir sonraki birey // Yeni Bireyler // Tek noktalı çaprazlama ile yeni bireyler oluşturulup, yeni değerleri hesaplanır // populasyona eklenir // Yeni bireyler eski bireyden kalıtım aldıkları için ilk bireyin işaretini taşırlar => "Negatif" yada "Pozitif" Person firstPerson = new Person(); firstPerson.BitsValue = SinglePointCrossover(p1, p2, targetPoint, true); //Negatiflik Kontrolü if (Math.Abs(p1.Value) == p1.Value) { firstPerson.Value = BinaryToInt(firstPerson.BitsValue); } else // Negaitf Yapma { firstPerson.Value = BinaryToInt(firstPerson.BitsValue) * -1; } temp.Add(firstPerson); Person secondPerson = new Person(); secondPerson.BitsValue = SinglePointCrossover(p1, p2, targetPoint, false); // 2. Birey oldugu için False //Negatiflik Kontrolü if (Math.Abs(p2.Value) == p2.Value) { secondPerson.Value = BinaryToInt(secondPerson.BitsValue); } else // Negaitf Yapma { secondPerson.Value = BinaryToInt(secondPerson.BitsValue) * -1; } temp.Add(secondPerson); } PersonList.Clear(); PersonList.AddRange(temp); // Yeni Bireyler Oluşturuldukta sonra Uygunluk Değerleri Yeniden Hesaplanır this.PurposeFunction(); }