public static Specimen InversionMutation(Specimen osobnik, Random random) { int k1 = 1 + random.Next(osobnik.body.GetLength(0) - 2); //Nie chce 'stawiac kreski' przed pierwszym i po ostatnim elemencie int k2 = 1 + random.Next(osobnik.body.GetLength(0) - 2); while (k1 == k2) //Jeżeli wylosuje w tym samym miejscu to losuj dalej { k2 = 1 + random.Next(osobnik.body.GetLength(0) - 2); } int k1temp = Math.Min(k1, k2); int k2temp = Math.Max(k1, k2); k1 = k1temp; k2 = k2temp; //if (k1 < k2) //{ for (int i = k1, j = k2; i < j; i++, j--) { int TempGene = osobnik.body[i]; osobnik.body[i] = osobnik.body[j]; osobnik.body[j] = TempGene; } //} //else //{ // for (int i = k2, j = k1; i < j; i++, j--) // { // int TempGene = osobnik.body[i]; // osobnik.body[i] = osobnik.body[j]; // osobnik.body[j] = TempGene; // } //} osobnik.rate = osobnik.rateSelf(); return(osobnik); }
public Specimen(Specimen specimen) { n = specimen.n; //Długość tablicy; problemu rozwazanego (52 dla Berlin52) body = new int[specimen.body.Length]; //Ciało osobnika; Array.Copy(specimen.body, body, specimen.body.Length); rate = specimen.rate; //Ocena osobnika data = specimen.data; }
public void Populate(Random rnd) { specimen = new Specimen[amountOfSpecimen]; //Stwórz tablice o wielkosci m (arbitralnej) for (int i = 0; i < amountOfSpecimen; i++) { specimen[i] = new Specimen(amountOfPoints, rnd, data); } }
public Specimen[] Repopulate(int SizeOfNewPopulation, int SizeOfTournament) { Specimen[] result = new Specimen[SizeOfNewPopulation]; for (int i = 0; i < SizeOfNewPopulation; i++) { result[i] = Tournament(SizeOfTournament); } return(result); }
public Specimen Tournament(int sizeOfTournament) { Specimen[] specimen = new Specimen[sizeOfTournament]; int[] specimenRated = new int[sizeOfTournament]; for (int i = 0; i < sizeOfTournament; i++) { int temp = random.Next(Population.amountOfSpecimen); specimen[i] = Population.specimen[temp]; specimenRated[i] = Population.ratedSpecimen[temp]; } int currentLowest = specimenRated[0]; int currentLowestIndex = 0; for (int i = 0; i < sizeOfTournament; i++) { if (specimenRated[i] < currentLowest) { currentLowest = specimenRated[i]; currentLowestIndex = i; } } return(specimen[currentLowestIndex]); }
public static Specimen OXCrossOver(Specimen osobnik1, Specimen osobnik2, Random random) { int k1 = 1 + random.Next(osobnik1.body.GetLength(0) - 2); //Nie chce 'stawiac kreski' przed pierwszym i po ostatnim elemencie int k2 = 1 + random.Next(osobnik1.body.GetLength(0) - 2); Queue <int> usedValues = new Queue <int>(); Specimen Offspring = new Specimen(osobnik1.body.GetLength(0), osobnik1.data); while (k1 == k2) //Jeżeli wylosuje w tym samym miejscu to losuj dalej { k2 = 1 + random.Next(osobnik1.body.GetLength(0) - 2); } if (k1 > k2) { int tempK = k1; k1 = k2; k2 = tempK; } for (int i = k1; i <= k2; i++) //Przepisuje ciało { Offspring.body[i] = osobnik1.body[i]; usedValues.Enqueue(Offspring.body[i]); } //Lista (FIFO)dostepnych wartosci Queue <int> aviableValues = new Queue <int>(); //int[] tempArray = new int[Offspring.body.GetLength(0) - (k2 - k1)]; for (int i = k2 + 1; i < Offspring.body.GetLength(0); i++) { //Jezeli Osobnik2.body[i] nie nalezy do listy uzytych wartosci //Spushuj do FIFO if (!(usedValues.Contains(osobnik2.body[i]))) { aviableValues.Enqueue(osobnik2.body[i]); } } for (int i = 0; i < k2 + 1; i++) { //Jezeli Osobnik2.body[i] nie nalezy do listy uzytych wartosci //Spushuj do FIFO if (!(usedValues.Contains(osobnik2.body[i]))) { aviableValues.Enqueue(osobnik2.body[i]); } } ////////////////////// for (int i = k2 + 1; i < Offspring.body.GetLength(0); i++) { //Offspring.body[i] = Pierwszy z FIFO Offspring.body[i] = aviableValues.Dequeue(); } for (int i = 0; i < k1; i++) { //Offspring.body[i] = Pierwszy z FIFO Offspring.body[i] = aviableValues.Dequeue(); } Offspring.rate = Offspring.rateSelf(); return(Offspring); }
static void Main(string[] args) { string path = @"D:\komiwoj\Komiwoj\berlin52.txt"; int amountOfSpecimenToProduce = 100; //20 jest tu arbitralna wielkoscia tablicy specimenow double mutationChance = 0.05; double crossoverChance = 0.95; int sizeOfTournament = 20; //Do ustalania jako paramter int sizeOfNewPopulation = 100; // DataReader data = new DataReader(path); Population population = new Population(amountOfSpecimenToProduce, data); population.Populate(random); //population.Rate(); //Okej paramtery //int amountOfSpecimenToProduce = 600; //double mutationChance = 0.05; //double crossoverChance = 0.55; //int sizeOfTournament = 60; ////////////////////////////// //Debug losowosc populacja////// ////////////////////////////// //for (int i = 0; i < amountOfSpecimenToProduce; i++) //{ // System.Console.WriteLine(population.ratedSpecimen[i]); //} //System.Console.ReadKey(); ////////////////////////////// //Debug seleckja turniejowa/// ////////////////////////////// //CompetetiveSelection cs = new CompetetiveSelection(population, random); //Population newPopulationCompetetive = new Population(cs.Repopulate(sizeOfNewPopulation, sizeOfTournament), data); //newPopulationCompetetive.Rate(); //System.Console.WriteLine("Po selekcji"); //for (int i = 0; i < newPopulationCompetetive.amountOfSpecimen; i++) //{ // System.Console.WriteLine(newPopulationCompetetive.ratedSpecimen[i]); //} //System.Console.ReadKey(); ////////////////////////////// //Debug seleckja ruletki////// ////////////////////////////// //RouletteSelection rs = new RouletteSelection(population, random); //Population newPopulationRoulette = new Population(rs.Roulette(sizeOfNewPopulation), data); //newPopulationRoulette.Rate(); //for (int i = 0; i < newPopulationRoulette.amountOfSpecimen; i++) //{ // System.Console.WriteLine(newPopulationRoulette.ratedSpecimen[i]); //} //System.Console.ReadKey(); ////////////////////////////// //Część właściwa programu///// ////////////////////////////// int LowestRateFound = 35000; //Arbitralnie duza wartosc bo sie kompilator czepia ze mozliwe ze sie nie zincjalizuje Specimen BestSpeciman = new Specimen(); //Przechowam najlepszego osobnika by sprawdzic jaka trase objal ///////////////////////////////////////////// //Selekcja turniejowa; i - liczba iteracji/// ///////////////////////////////////////////// Population iteration = new Population(sizeOfNewPopulation, data); //Zainicjalizowane żeby kompilator sie nie czepial o niezaicjalizowana zmienna (bo powinien być do while zamiast if) CompetetiveSelection selectedPopulation; for (int i = 0; i < 1000; i++) { if (i == 0) { selectedPopulation = new CompetetiveSelection(population, random); iteration = new Population(selectedPopulation.Repopulate(sizeOfNewPopulation, sizeOfTournament), data); iteration.Mutate(mutationChance, random); iteration.CrossOver(crossoverChance, random); for (int j = 0; j < iteration.amountOfSpecimen; j++) { if (iteration.ratedSpecimen[j] < LowestRateFound) { LowestRateFound = iteration.ratedSpecimen[j]; BestSpeciman = iteration.specimen[j]; } } } else { selectedPopulation = new CompetetiveSelection(iteration, random); iteration = new Population(selectedPopulation.Repopulate(sizeOfNewPopulation, sizeOfTournament), data); iteration.Mutate(mutationChance, random); iteration.CrossOver(crossoverChance, random); for (int j = 0; j < iteration.amountOfSpecimen; j++) { if (iteration.specimen[j].rate < LowestRateFound) { LowestRateFound = iteration.specimen[j].rate; BestSpeciman = new Specimen(iteration.specimen[j]); } } } //////////////////////////// //Wyswietlanie iteracji///// //////////////////////////// //if (i % 100 == 0) //{ // System.Console.WriteLine("Po Iteracjach {0}, Mutacja: {1}, Crossover: {2}", i, mutationChance, crossoverChance); // for (int j = 0; j < iteration.amountOfSpecimen; j++) // { // //System.Console.WriteLine(iteration.ratedSpecimen[j]); // } // System.Console.WriteLine("Najlepszy:{0}", LowestRateFound); // System.Console.ReadKey(); //} } //////////////////////////// //Selekcja ruletkowa//////// //////////////////////////// //RouletteSelection selectedPopulation1; //for (int i = 0; i < 10000; i++) //{ // if (i == 0) // { // selectedPopulation1 = new RouletteSelection(population, random); // iteration = new Population(selectedPopulation1.Roulette(sizeOfNewPopulation), data); // iteration.Mutate(mutationChance, random); // iteration.CrossOver(crossoverChance, random); // for (int j = 0; j < iteration.amountOfSpecimen; j++) // { // if (iteration.ratedSpecimen[j] < LowestRateFound) // { // LowestRateFound = iteration.ratedSpecimen[j]; // BestSpeciman = iteration.specimen[j]; // } // } // } // else // { // selectedPopulation1 = new RouletteSelection(iteration, random); // iteration = new Population(selectedPopulation1.Roulette(sizeOfNewPopulation), data); // iteration.Mutate(mutationChance, random); // iteration.CrossOver(crossoverChance, random); // for (int j = 0; j < iteration.amountOfSpecimen; j++) // { // if (iteration.ratedSpecimen[j] < LowestRateFound) // { // LowestRateFound = iteration.ratedSpecimen[j]; // BestSpeciman = iteration.specimen[j]; // } // } // } //} //////////////////////////////// //Wyniki - ostatnia populacja/// //////////////////////////////// System.Console.WriteLine("Po Iteracjach"); for (int i = 0; i < iteration.amountOfSpecimen; i++) { //System.Console.WriteLine(iteration.ratedSpecimen[i]); } System.Console.WriteLine("Najlepszy:{0}", LowestRateFound); String trasa = String.Empty; foreach (int i in BestSpeciman.body) { if (String.IsNullOrEmpty(trasa)) { trasa = trasa + Convert.ToString(i); } else { trasa = trasa + "-" + Convert.ToString(i); } } System.Console.WriteLine(trasa); System.Console.ReadKey(); }
public Specimen[] Roulette(int sizeOfRoulette) { Specimen[] specimen = new Specimen[sizeOfRoulette]; //Tablica na osobników którzy 'przychodzą' z poprzedniej populacji Specimen[] specimenResult = new Specimen[sizeOfRoulette]; //Tablica osobników będących nową populacją int[] specimenRated = new int[sizeOfRoulette]; //Tablica ocen osobników double[] specimenProbability = new double[sizeOfRoulette]; //Tablica prawdopodobienstw kazdego z osobników double[] probabilityTable = new double[sizeOfRoulette]; //Tablica ktora zlacza prawdopodobienstwo kazdgeo z osobnikow double sumOfProbablity = 0; //Suma prawdopodobienstaa (dodaje sie do 1) double highestProbability = 0; int sumOfRoulette = 0; //Suma ruletki (sumuje wszystkie wartosci ocen) for (int i = 0; i < sizeOfRoulette; i++) //Dla wielkości ruletki (wielkość nowej populacji) { int temp = random.Next(Population.amountOfSpecimen); //Wybieram losowego osobnika specimen[i] = Population.specimen[temp]; //To co wyżej specimenRated[i] = Population.specimen[temp].rate; //Zapamiętuje też jego ocenę sumOfRoulette = sumOfRoulette + specimenRated[i]; //Suma ruletki powiększa się o ocenę } for (int i = 0; i < sizeOfRoulette; i++) //Dla wielkosci ruletki (wielkosci nowej populacji) { specimenProbability[i] = (double)specimenRated[i] / (double)sumOfRoulette; //Prawdopodobienstwo i-tego osobnika ze zostanie wylosowany if (specimenProbability[i] > highestProbability) { highestProbability = specimenProbability[i]; } //sumOfProbablity = sumOfProbablity + specimenProbability[i]; //Ile z "1" prawdopodobienstwa juz mam zajęte //probabilityTable[i] = sumOfProbablity; //Jakiej wylosowanej liczbie < 1 będzie odpowiadał i-ty osobnik } for (int i = 0; i < sizeOfRoulette; i++) //Dla wielkosci ruletki (wielkosci nowej populacji) { sumOfProbablity = sumOfProbablity + specimenProbability[i]; //Ile z "1" prawdopodobienstwa juz mam zajęte probabilityTable[i] = highestProbability - sumOfProbablity + 1; //Jakiej wylosowanej liczbie < 1 będzie odpowiadał i-ty osobnik } for (int i = 0; i < sizeOfRoulette; i++) //Dla wielkości ruletki (wielkosci nowej populacji) { double randomNumber = random.NextDouble(); //Losuje losowa liczbe (0,1> for (int j = sizeOfRoulette - 1; j > 0; j--) //Dla całego zakresu (0,1> { if (j - 1 > 0 && randomNumber >= probabilityTable[j] && randomNumber < probabilityTable[j - 1]) //Jeżeli wylosowana liczba jest większa od pierwszej zmapowanej liczby i mniejsza od drugiej; to drugi osobnik jest tym wylosowanym { specimenResult[i] = specimen[j - 1]; break; } else if (randomNumber <= probabilityTable[j]) //Jezeli wylosowana liczba jest mniejsza od rozwazanej liczby to jest szukana liczba { specimenResult[i] = specimen[j]; break; } else if (randomNumber < probabilityTable[0] && randomNumber >= probabilityTable[1]) { specimenResult[i] = specimen[0]; break; } //W przeciwnym razie szukam dalej na prawo } } return(specimenResult); }