static void Main(string[] args) { Console.WriteLine("13K3 Trzop Artur (c) 2012 Politechnika Krakowska, Wydział Mechaniczny\n"); Console.WriteLine("====================================================================="); // Każdy chromosom składa się z 10 genów. // Budujemy słownik chromosomów. // Klucz słownika to kolejne liczby naturalne od zera, przyporządkowane do argumentów na osi x, // które to argumenty wyrażone są wartościami od 0, 0.01, 0.02, itd. aż do 10. Dictionary <int, Chromosom> ArrChrom = new Dictionary <int, Chromosom>(); // Warunek do 10.24 ponieważ chcemy mieć wszystkie możliwe do zapisania genotypy od 00 0000 0000 do 11 1111 1111 int key = 0; for (double x = 0; x <= 10.24; x += WAGA) { ArrChrom.Add(key, new Chromosom() { // wagaDoubleToBin zwraca string, który np. dla x=0.01 wyniesie 00 0000 0001 genotyp = wagaDoubleToBin(x), // Wartość funkcji f dla argumentu x będącego kolejnym krokiem o długości 0.01*n, gdzie n to numer kroku pętli for fenotyp = f(x) }); // Drukuj dodany do słownika chromosom // Console.WriteLine("key: " + key + " (" + x + ") => { \n\tgenotyp: " + ArrChrom[key].genotyp + "\n\tfenotyp: " + ArrChrom[key].fenotyp + "\n}"); key++; } // Testowe sprawdzenie poprawności działania metod wagaBinToDouble i wagaDoubleToBin // Console.WriteLine(wagaBinToDouble("0000000001") + " = " + wagaDoubleToBin(0.01)); Random random = new Random(); int r; // przechowuje wylosowaną liczbę int double rd; // przechowuje wylosowaną liczbę double // przechowuje populację List <Chromosom> Populacja = new List <Chromosom>(); // przechowuje najlepszy chromosom jaki udało nam się dotychczas uzyskać ze wszystkich generacji rozwijających się populacji Chromosom NajlepszyChromosom = new Chromosom(); // kontrolny fenotyp przed ostatniego chromosomu do porównywania czy znaleźliśmy lepsze wyniki double?PrzedOstatniNajlepszyFenotyp = null; int LiczebnoscPoczatkowejPopulacji = 20; // ustawienie warunku STOP na true spowoduje przerwanie tworzenia nowych generacji rozwijających się populacji bool STOP = false; int generacja = 0; while (!STOP || generacja <= 10) // uruchamiamy conajmniej 10 generacje rozwijających się populacji { generacja++; // czyścimy populacje przed rozpoczęciem nowej generacji Populacja.Clear(); // startujemy w okolicy x=0.5 czyli np. wylosujemy liczbę 50 * 0.01 = 0,5 //r = random.Next(30, 70); r = random.Next(0, 1024 - LiczebnoscPoczatkowejPopulacji); rd = r * WAGA; key = r; // wybieramy 20 kolejnych po sobie osobników do populacji startowej //double warunek = rd + (LiczebnoscPoczatkowejPopulacji * WAGA); //for (double x = rd; x < warunek; x += WAGA) //{ // //Console.WriteLine(x); // Populacja.Add(ArrChrom[key]); // Console.WriteLine("key: " + key + " (" + x + ") => { \n\tgenotyp: " + ArrChrom[key].genotyp + "\n\tfenotyp: " + ArrChrom[key].fenotyp + "\n}"); // key++; //} // Wybieramy osobników w sposób losowy do populacji startowej. // Daje to lepsze wyniki niż sposób kilka linijek wyżej, który pobiera 20 kolejnych po sobie osobników. for (int i = 0; i < 20; i++) { key = random.Next(0, 1024); // wylosowana zostanie liczba od 0 do 1023 włącznie Populacja.Add(ArrChrom[key]); Console.WriteLine("key: " + key + " => { \n\tgenotyp: " + ArrChrom[key].genotyp + "\n\tfenotyp: " + ArrChrom[key].fenotyp + "\n}"); } int whileWarunek = 0; while (whileWarunek < 1024) // 1024 na sztywno liczba możliwych pętli do przeprowadzenia { whileWarunek++; // szukanie najlepszych osobników Console.WriteLine("\nSzukanie najlepszych osobników w danej populacji:"); // Przy pomocy LINQ budujemy zapytanie wybierające z populacji chromosomy posortowane od największej wartości fenotypu. IEnumerable query = Populacja.OrderByDescending(chrom => chrom.fenotyp); // przygotowanie zmiennych przechowujących genotyp rodzica string rodzic1Genotyp = null; string rodzic2Genotyp = null; var l = 0; foreach (Chromosom i in query) { //Console.WriteLine(i.fenotyp); if (rodzic1Genotyp == null) { rodzic1Genotyp = i.genotyp; NajlepszyChromosom = i; // zapisujemy ten genotyp bo ma najwyższą wartość f(x) if (PrzedOstatniNajlepszyFenotyp != null) { if ((PrzedOstatniNajlepszyFenotyp - i.fenotyp) % WAGA < WAGA) { // możemy zakończyć poszukiwania ponieważ kolejny wynik różni się z dokładnością mniejszą niż 0.01 STOP = true; } } PrzedOstatniNajlepszyFenotyp = i.fenotyp; Console.WriteLine("Rodzic1 => { genotyp: " + i.genotyp + ", fenotyp: " + i.fenotyp + " }"); } else { rodzic2Genotyp = i.genotyp; Console.WriteLine("Rodzic2 => { genotyp: " + i.genotyp + ", fenotyp: " + i.fenotyp + " }"); } // zatrzymujemy foreach po pobraniu dwóch genotypów if (l++ > 0) { break; } } // krzyżowanie rodziców Console.WriteLine("\nKrzyżowanie rodziców:"); string dziecko1Genotyp = rodzic1Genotyp.Substring(0, 5) + rodzic2Genotyp.Substring(5, 5); string dziecko2Genotyp = rodzic2Genotyp.Substring(0, 5) + rodzic1Genotyp.Substring(5, 5); Console.WriteLine("Dziecko1: " + dziecko1Genotyp); Console.WriteLine("Dziecko2: " + dziecko2Genotyp); // mutacja z pewnym prawdopodobieństwem zadanym w metodzie mutacja() string mutacja1 = mutacja(dziecko1Genotyp); if (mutacja1 != null) { dziecko1Genotyp = mutacja1; Console.WriteLine("Mutacja Dziecka1: " + dziecko1Genotyp); } string mutacja2 = mutacja(dziecko2Genotyp); if (mutacja2 != null) { dziecko2Genotyp = mutacja2; Console.WriteLine("Mutacja Dziecka2: " + dziecko2Genotyp); } // znajdujemy obiekty dzieci w słowniku ArrChrom query = from p in Populacja where p.genotyp.Equals(dziecko1Genotyp) || p.genotyp.Equals(dziecko2Genotyp) select p; int dzieckoWarunekStopu = 0; foreach (Chromosom current in query) { // jeśli dany chromosom jeszcze nie istnieje w populacji to możemy go dodać if (!Populacja.Any(chromosom => chromosom.fenotyp == current.fenotyp)) { Populacja.Add(current); Console.WriteLine("+ Dodano chromosom dziecko " + current.genotyp + " do populacji."); } else { Console.WriteLine("- Nie dodano chromosomu dziecka " + current.genotyp + " do populacji ponieważ już w niej istnieje."); dzieckoWarunekStopu++; } } if (dzieckoWarunekStopu == 2) { // Od komentować poniższe 3 linie w /* takim komentarzu */ jeżeli chcemy zatrzymać pętlę w przypadku pojawienia się dzieci o takich // samych genotypach jak osobniki już w populacji. // // Gdy dzieci mają takie same genotypy jak osobniki już istniejące w populacji to nadal ci sami rodzice będą // dominować w populacji. Czynnikiem, który może spowodować pojawienie się potomków nie dublujących się jest: // a) populacja składa się z losowych chromosomów przez co rzadko będą dublować się otrzymane dzieci z osobnikami w populacji. // b) wprowadzono mutacje u dzieci dzięki temu istnieje szansa na pojawienie się dziecka o odmiennym genotypie (to rozwiązanie przyjęto w tym programie). // /* * Console.WriteLine("Koniec tej populacji. Rodzice są dominujący i nie pojawiają się dzieci o lepszych genach."); * Console.WriteLine("----------------------------------"); * break; */ } Console.WriteLine("----------------------------------"); } // koniec while } // koniec while generacji // Wyświetlamy najlepszy chromosom dotychczas znaleziony. Console.WriteLine("\n\nNajlepszy chromosom => { \n\tgenotyp: " + NajlepszyChromosom.genotyp + "\n\tfenotyp: " + NajlepszyChromosom.fenotyp + "\n}"); Console.WriteLine("\nKONIEC"); Console.ReadKey(); }
static void Main(string[] args) { Console.WriteLine("13K3 Trzop Artur (c) 2012 Politechnika Krakowska, Wydział Mechaniczny\n"); Console.WriteLine("====================================================================="); // Każdy chromosom składa się z 10 genów. // Budujemy słownik chromosomów. // Klucz słownika to kolejne liczby naturalne od zera, przyporządkowane do argumentów na osi x, // które to argumenty wyrażone są wartościami od 0, 0.01, 0.02, itd. aż do 10. Dictionary<int, Chromosom> ArrChrom = new Dictionary<int, Chromosom>(); // Warunek do 10.24 ponieważ chcemy mieć wszystkie możliwe do zapisania genotypy od 00 0000 0000 do 11 1111 1111 int key = 0; for (double x = 0; x <= 10.24; x += WAGA) { ArrChrom.Add(key, new Chromosom() { // wagaDoubleToBin zwraca string, który np. dla x=0.01 wyniesie 00 0000 0001 genotyp = wagaDoubleToBin(x), // Wartość funkcji f dla argumentu x będącego kolejnym krokiem o długości 0.01*n, gdzie n to numer kroku pętli for fenotyp = f(x) }); // Drukuj dodany do słownika chromosom // Console.WriteLine("key: " + key + " (" + x + ") => { \n\tgenotyp: " + ArrChrom[key].genotyp + "\n\tfenotyp: " + ArrChrom[key].fenotyp + "\n}"); key++; } // Testowe sprawdzenie poprawności działania metod wagaBinToDouble i wagaDoubleToBin // Console.WriteLine(wagaBinToDouble("0000000001") + " = " + wagaDoubleToBin(0.01)); Random random = new Random(); int r; // przechowuje wylosowaną liczbę int double rd; // przechowuje wylosowaną liczbę double // przechowuje populację List<Chromosom> Populacja = new List<Chromosom>(); // przechowuje najlepszy chromosom jaki udało nam się dotychczas uzyskać ze wszystkich generacji rozwijających się populacji Chromosom NajlepszyChromosom = new Chromosom(); // kontrolny fenotyp przed ostatniego chromosomu do porównywania czy znaleźliśmy lepsze wyniki double? PrzedOstatniNajlepszyFenotyp = null; int LiczebnoscPoczatkowejPopulacji = 20; // ustawienie warunku STOP na true spowoduje przerwanie tworzenia nowych generacji rozwijających się populacji bool STOP = false; int generacja = 0; while (!STOP || generacja <= 10) // uruchamiamy conajmniej 10 generacje rozwijających się populacji { generacja++; // czyścimy populacje przed rozpoczęciem nowej generacji Populacja.Clear(); // startujemy w okolicy x=0.5 czyli np. wylosujemy liczbę 50 * 0.01 = 0,5 //r = random.Next(30, 70); r = random.Next(0, 1024 - LiczebnoscPoczatkowejPopulacji); rd = r * WAGA; key = r; // wybieramy 20 kolejnych po sobie osobników do populacji startowej //double warunek = rd + (LiczebnoscPoczatkowejPopulacji * WAGA); //for (double x = rd; x < warunek; x += WAGA) //{ // //Console.WriteLine(x); // Populacja.Add(ArrChrom[key]); // Console.WriteLine("key: " + key + " (" + x + ") => { \n\tgenotyp: " + ArrChrom[key].genotyp + "\n\tfenotyp: " + ArrChrom[key].fenotyp + "\n}"); // key++; //} // Wybieramy osobników w sposób losowy do populacji startowej. // Daje to lepsze wyniki niż sposób kilka linijek wyżej, który pobiera 20 kolejnych po sobie osobników. for (int i = 0; i < 20; i++) { key = random.Next(0, 1024); // wylosowana zostanie liczba od 0 do 1023 włącznie Populacja.Add(ArrChrom[key]); Console.WriteLine("key: " + key + " => { \n\tgenotyp: " + ArrChrom[key].genotyp + "\n\tfenotyp: " + ArrChrom[key].fenotyp + "\n}"); } int whileWarunek = 0; while(whileWarunek < 1024) // 1024 na sztywno liczba możliwych pętli do przeprowadzenia { whileWarunek++; // szukanie najlepszych osobników Console.WriteLine("\nSzukanie najlepszych osobników w danej populacji:"); // Przy pomocy LINQ budujemy zapytanie wybierające z populacji chromosomy posortowane od największej wartości fenotypu. IEnumerable query = Populacja.OrderByDescending(chrom => chrom.fenotyp); // przygotowanie zmiennych przechowujących genotyp rodzica string rodzic1Genotyp = null; string rodzic2Genotyp = null; var l = 0; foreach(Chromosom i in query) { //Console.WriteLine(i.fenotyp); if (rodzic1Genotyp == null) { rodzic1Genotyp = i.genotyp; NajlepszyChromosom = i; // zapisujemy ten genotyp bo ma najwyższą wartość f(x) if (PrzedOstatniNajlepszyFenotyp != null) { if ((PrzedOstatniNajlepszyFenotyp - i.fenotyp) % WAGA < WAGA) { // możemy zakończyć poszukiwania ponieważ kolejny wynik różni się z dokładnością mniejszą niż 0.01 STOP = true; } } PrzedOstatniNajlepszyFenotyp = i.fenotyp; Console.WriteLine("Rodzic1 => { genotyp: " + i.genotyp + ", fenotyp: " + i.fenotyp + " }"); } else { rodzic2Genotyp = i.genotyp; Console.WriteLine("Rodzic2 => { genotyp: " + i.genotyp + ", fenotyp: " + i.fenotyp + " }"); } // zatrzymujemy foreach po pobraniu dwóch genotypów if (l++ > 0) break; } // krzyżowanie rodziców Console.WriteLine("\nKrzyżowanie rodziców:"); string dziecko1Genotyp = rodzic1Genotyp.Substring(0, 5) + rodzic2Genotyp.Substring(5, 5); string dziecko2Genotyp = rodzic2Genotyp.Substring(0, 5) + rodzic1Genotyp.Substring(5, 5); Console.WriteLine("Dziecko1: " + dziecko1Genotyp); Console.WriteLine("Dziecko2: " + dziecko2Genotyp); // mutacja z pewnym prawdopodobieństwem zadanym w metodzie mutacja() string mutacja1 = mutacja(dziecko1Genotyp); if (mutacja1 != null) { dziecko1Genotyp = mutacja1; Console.WriteLine("Mutacja Dziecka1: " + dziecko1Genotyp); } string mutacja2 = mutacja(dziecko2Genotyp); if (mutacja2 != null) { dziecko2Genotyp = mutacja2; Console.WriteLine("Mutacja Dziecka2: " + dziecko2Genotyp); } // znajdujemy obiekty dzieci w słowniku ArrChrom query = from p in Populacja where p.genotyp.Equals(dziecko1Genotyp) || p.genotyp.Equals(dziecko2Genotyp) select p; int dzieckoWarunekStopu = 0; foreach (Chromosom current in query) { // jeśli dany chromosom jeszcze nie istnieje w populacji to możemy go dodać if (!Populacja.Any(chromosom => chromosom.fenotyp == current.fenotyp)) { Populacja.Add(current); Console.WriteLine("+ Dodano chromosom dziecko " + current.genotyp + " do populacji."); } else { Console.WriteLine("- Nie dodano chromosomu dziecka " + current.genotyp + " do populacji ponieważ już w niej istnieje."); dzieckoWarunekStopu++; } } if (dzieckoWarunekStopu == 2) { // Od komentować poniższe 3 linie w /* takim komentarzu */ jeżeli chcemy zatrzymać pętlę w przypadku pojawienia się dzieci o takich // samych genotypach jak osobniki już w populacji. // // Gdy dzieci mają takie same genotypy jak osobniki już istniejące w populacji to nadal ci sami rodzice będą // dominować w populacji. Czynnikiem, który może spowodować pojawienie się potomków nie dublujących się jest: // a) populacja składa się z losowych chromosomów przez co rzadko będą dublować się otrzymane dzieci z osobnikami w populacji. // b) wprowadzono mutacje u dzieci dzięki temu istnieje szansa na pojawienie się dziecka o odmiennym genotypie (to rozwiązanie przyjęto w tym programie). // /* Console.WriteLine("Koniec tej populacji. Rodzice są dominujący i nie pojawiają się dzieci o lepszych genach."); Console.WriteLine("----------------------------------"); break; */ } Console.WriteLine("----------------------------------"); } // koniec while } // koniec while generacji // Wyświetlamy najlepszy chromosom dotychczas znaleziony. Console.WriteLine("\n\nNajlepszy chromosom => { \n\tgenotyp: " + NajlepszyChromosom.genotyp + "\n\tfenotyp: " + NajlepszyChromosom.fenotyp + "\n}"); Console.WriteLine("\nKONIEC"); Console.ReadKey(); }