/// <summary>
        /// Krzyżuje dwa chromosomy podane na wejściu i zwracam całkowicie nowe chromosomy
        /// </summary>
        public virtual ChromosomeClass[] crossoverOfTwoChromosomesByWeekends(ChromosomeClass chromosome1, ChromosomeClass chromosome2, int fromWhichWeekStartCrossover) //tu pracuje na orginałach chromosomów dlatego nic nie zwracam
        {
            int whichWeekChange = fromWhichWeekStartCrossover;

            NurseClass[][][]  tempTableOnWeek; //to jakby wskaźnik na tablice 3 wymiarową
            ChromosomeClass[] newChromosomes = new ChromosomeClass[2] {
                new ChromosomeClass(), new ChromosomeClass()
            };                                                                                                         // miejsce na 2 nowe chromosomy
            //krzyżuje 2 chromosomy wymieniając między nimi tygodnie

            //najpierw przypisuje do nowych chromosomów stare chromosomy ( bo jak bd puste to co bd Krzyżować ? xd)
            //przypisujemy do tych nowych chromosomów kopie tablic chrosomome vector - musi to byc kopia wartościowa a nie kopia referencyjna
            newChromosomes[0].chromosomeVector = new List <NurseClass[][][]>(chromosome1.chromosomeVector).ToArray(); //tworze liste i pozniej tworze z niej tablice - po wartosciach wszystko kopiuje (czyli mamy całkowicie nowe tablice z tymi samymi wartosciami)
            newChromosomes[1].chromosomeVector = new List <NurseClass[][][]>(chromosome2.chromosomeVector).ToArray();



            while (whichWeekChange < 5)//jak wyjedziemy na 6 tydzien chromosomu to koniec krzyżowania
            {
                tempTableOnWeek = newChromosomes[0].chromosomeVector[whichWeekChange];
                newChromosomes[0].chromosomeVector[whichWeekChange] = newChromosomes[1].chromosomeVector[whichWeekChange]; //wymieniam cały tydzien miedzy dwoma chromosomami
                newChromosomes[1].chromosomeVector[whichWeekChange] = tempTableOnWeek;                                     //tu też wymiana

                whichWeekChange += 2;                                                                                      //bedziemy krzyżować co 2 week - bo krzyżowanie co jeden nie ma sensu bo uzyskalibyśmy 2 identyczne chromosomy takie jak na wejsciu
            }

            //return new ChromosomeClass[2] { chromosome1, chromosome2 }; //zwracam 2 przekrzyżowane juz chromosomy
            return(newChromosomes);
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            //Console.SetBufferSize(200, 100);
            ChromosomeClass obChromosomeClass = new ChromosomeClass();

            obChromosomeClass.writeNursesFromChromosomeFromEachShift();



            GeneticAlgorithmClass obGeneticAlgorithmClass = new GeneticAlgorithmClass(6, 0, 2000, 1000, 1000, 4);

            obChromosomeClass = obGeneticAlgorithmClass.runAlgorithm();

            obChromosomeClass.writeNursesFromChromosomeFromEachShift();  //wypisz ten chromosom ktory jest wynikiem

            Console.ReadLine();
            Console.ReadLine();
        }
        /// <summary>
        /// Funkcja do krzyżowania chromosomów ze sobą , ale tylko z tymczasowej listy bestChromosomesSelectedToCrossover
        /// </summary>
        public virtual void CrossoverOfBestChromosomes(List <ChromosomeClass> bestChromosomesSelectedToCrossover)
        {
            //krzyżowanie musimy przeprowadzać dopóki nie uzyskamy howMuchChromosomeCreate nowych chromosomów
            int howMuchNewChromosomesWasCreated = 0;
            int indexOfFirstChromosome          = -1;
            int indexOfSecondChromosome         = 0;

            Random rnd = new Random();

            ChromosomeClass[] newChromosomesAfterCrossover = new ChromosomeClass[2];



            while (howMuchNewChromosomesWasCreated < howMuchChromosomesCreate)
            {
                if (howMuchNewChromosomesWasCreated >= howMuchChromosomesSelectToCrossover - 1)  //jezeli już skrzyżowaliśmy ze sobą chromosomy parzyście czyli 1 z 2 , 3 z 4 itd
                {
                    //to tutaj wybieramy losowo chromosomy aby stworzyć z nich pozostałe osobniki do populacji - bo paru nam brakuje do howMUchNewChromosomesWasCreated
                    do
                    {
                        indexOfFirstChromosome  = rnd.Next(0, bestChromosomesSelectedToCrossover.Count);
                        indexOfSecondChromosome = rnd.Next(0, bestChromosomesSelectedToCrossover.Count);
                    } while (indexOfFirstChromosome == indexOfSecondChromosome);            //jesli bedą sie powtarzac te indeksy to żeby nie krzyżowało jednego chromosomu ze sobą

                    //no i krzyżuje te dwa losowo wybrane chromosomy i dodaje je do listy
                    newChromosomesAfterCrossover = crossoverOfTwoChromosomesByWeekends(bestChromosomesSelectedToCrossover[indexOfFirstChromosome], bestChromosomesSelectedToCrossover[indexOfSecondChromosome], howMuchNewChromosomesWasCreated % 2);
                    //dodaje do listy nowych
                    bestChromosomesSelectedToCrossover.Add(newChromosomesAfterCrossover[0]); //dodaje
                    bestChromosomesSelectedToCrossover.Add(newChromosomesAfterCrossover[1]);
                }
                else
                {
                    indexOfFirstChromosome++;
                    indexOfSecondChromosome++;
                    //krzyżuje parzyście - czyli pierwszy z drugim , trzeci z czwartym itd i przypisuje je odpowidnio do miejsc w liscie (zastepuje 2 inne chromosomy w liscie tymczasowej)                                                                                      // ↓↓↓ tu na dole w argumencie raz zaczynamy krzyżowanie od 0 week a raz od 1 week - tak żeby było różnorodnie
                    newChromosomesAfterCrossover = crossoverOfTwoChromosomesByWeekends(bestChromosomesSelectedToCrossover[indexOfFirstChromosome], bestChromosomesSelectedToCrossover[indexOfSecondChromosome], howMuchNewChromosomesWasCreated % 2);
                    bestChromosomesSelectedToCrossover[indexOfFirstChromosome]  = newChromosomesAfterCrossover[0]; //przypisuje pierwszy nowy chromosom
                    bestChromosomesSelectedToCrossover[indexOfSecondChromosome] = newChromosomesAfterCrossover[1]; //no i drugi nowy chromosom
                }
                howMuchNewChromosomesWasCreated += 2;                                                              //co iteracje mam 2 nowe chromosomy bo krzyżuje 2 i z nich powstaja 2 nowe
            }
        }