Example #1
0
        public Tierchen InzestMutation()
        {
            Random randomizer   = new Random();
            var    AllelSize    = GenCode.Select(allel => allel.Size).Distinct();
            var    InterValList = GenCode.Select(allel => allel.Interval).ToList();

            if (AllelSize.Count() == 1)
            {
                var allelLenght = AllelSize.FirstOrDefault();
                var gencode     = CompleteGenCode;
                int Stelle1     = randomizer.Next(gencode.Count);
                int Stelle2     = Stelle1;
                if (Stelle1 < gencode.Count - 1)
                {
                    Stelle2 = randomizer.Next(Stelle1 + 1, gencode.Count);
                }
                var tmpValue = gencode[Stelle1];
                gencode[Stelle1] = gencode[Stelle2];
                gencode[Stelle2] = tmpValue;
                // gesamtliste wieder trennen
                var newTier = new Tierchen(this.Problem, GenCode);
                newTier.CompleteGenCode = gencode;
                return(newTier);
            }
            else
            {
                return(this);
            }
        }
Example #2
0
        public Tierchen Mutation()
        {
            /* Führe eine Mutation aus
             * Bestimme dazu die Allelmenge
             *
             */
            Random randomizer   = new Random();
            var    AllelSize    = GenCode.Select(allel => allel.Size).Distinct();
            var    InterValList = GenCode.Select(allel => allel.Interval).ToList();

            if (AllelSize.Count() == 1)
            {
                var allelLenght = AllelSize.FirstOrDefault();
                var gencode     = CompleteGenCode;
                int Stelle1     = randomizer.Next(gencode.Count);
                int Stelle2     = Stelle1;
                if (Stelle1 < gencode.Count - 1)
                {
                    Stelle2 = randomizer.Next(Stelle1 + 1, gencode.Count);
                }
                gencode.Reverse(Stelle1, Stelle2 - Stelle1);
                // gesamtliste wieder trennen
                var newTier = new Tierchen(this.Problem, GenCode);
                newTier.CompleteGenCode = gencode;
                return(newTier);
            }
            else
            {
                return(this);
            }
        }
Example #3
0
        private void button2_Click(object sender, EventArgs e)
        {
            Random randomizer = new Random();

            Elterngeneration.Clear();
            Kindgeneration.Clear();
            TierchenHistory.Clear();
            BesteFitness.Clear();
            DurchschnittsFitness.Clear();
            BesterDerHistoryFitness.Clear();
            // erzeuge Elterngeneration

            Int32.TryParse(textBox1.Text, out elternSize);
            Int32.TryParse(textBox5.Text, out binärStringLenght);
            Int32.TryParse(textBox3.Text, out gene);
            problem = new Problem(Int32.Parse(comboBox1.SelectedItem.ToString().Substring(1, 1)));

            var matches = Regex.Matches(textBox2.Text, @"\[(.*?)\]");

            intervalle.Clear();
            foreach (Match m in matches)
            {
                Intervall intervall;
                Intervall.TryParse(m.Groups[1].Value, out intervall);
                intervalle.Add(intervall);
            }
            if (checkBox1.Checked && intervalle.Count() == 1)
            {
                while (intervalle.Count() < gene)
                {
                    intervalle.Add(intervalle[0]);
                }
            }
            progressBar1.Enabled = true;
            progressBar1.Value   = 0;
            while (Elterngeneration.Count < elternSize)
            {
                Elterngeneration.Add(Tierchen.RandomTier(randomizer, binärStringLenght, intervalle, gene, problem));

                /*
                 * ### Wie kommt das mit dem Distinct zustande ? ###
                 * ### Ist ToList() eine Methode einer über TierchenComparer liegenden Klasse ? ###
                 * ### Welche voraussetzungen müssen erfüllt sein ? ###
                 * !!! Hatten wir ja geklärt, oder?
                 */
                Elterngeneration   = Elterngeneration.Distinct(new TierchenComparer()).ToList();
                progressBar1.Value = Elterngeneration.Count() * 100 / elternSize;
            }
            SaveGeneration("last.xml");
            progressBar1.Enabled = false;
            m_Generator          = new generator(Elterngeneration, Kindgeneration, TierchenHistory, problem, BesteFitness, DurchschnittsFitness, BesterDerHistoryFitness);
        }
        public static List <Tierchen> NPunktRekombination(Random randomizer, int recombinations, int pointOfRecombination, List <Tierchen> kindGen, List <Tierchen> elternGen)
        {
            // Füge zur Kindgeneration zwei Kinder über eine Ein-Punkt-Rekombination hinzu
            // Wiederhole solange bis die Anzahl der Rekombinationen erreicht
            bool verbieteDoppelte = true;
            int  lastCount        = 0;
            int  versuchsZähler   = 0;

            while (kindGen.Count() < recombinations)
            {
                var index1 = randomizer.Next(0, elternGen.Count);
                var index2 = index1;
                while (index2 == index1)
                {
                    index2 = randomizer.Next(0, elternGen.Count);
                }

                Tierchen Kind1;
                Tierchen Kind2;
                Tierchen.NPointRecombination(randomizer, elternGen[index1], elternGen[index2], out Kind1, out Kind2, pointOfRecombination);
                kindGen.Add(Kind1);
                kindGen.Add(Kind2);
                if (verbieteDoppelte)
                {
                    kindGen = kindGen.Distinct(new TierchenComparer()).ToList();
                    if (kindGen.Count() == lastCount)
                    {
                        if (versuchsZähler <= MAX_VERSUCHE_ZUM_FINDEN_NICHT_DOPPELTEN)
                        {
                            versuchsZähler++;
                        }
                        else
                        {
                            verbieteDoppelte = false;
                        }
                    }
                    else
                    {
                        versuchsZähler = 0;
                    }
                }
                lastCount = kindGen.Count();
            }
            return(kindGen);
        }
Example #5
0
        public static Tierchen RandomTier(Random randomizer, int AllelLenght, List <Intervall> interval, int GenLenght, Problem problem)
        {
            var genCode = new List <Allel>();

            for (int i = 0; i < GenLenght; i++)
            {
                var allel    = new Allel(AllelLenght, interval[i]);
                var allelVal = new List <byte>();
                for (int j = 0; j < AllelLenght; j++)
                {
                    allelVal.Add((byte)randomizer.Next(0, 2));
                }
                allel.Add(allelVal);
                genCode.Add(allel);
            }
            var tier = new Tierchen(problem, genCode);

            tier.Bewerte();
            return(tier);
        }
Example #6
0
 public static bool OnePointRecombination(Random randomizer, Tierchen mutter, Tierchen vater, out Tierchen kind1, out Tierchen kind2)
 {
     /* Ein-Punkt-Rekombination wählt zwei Tierchen sowie zufällig je ein Allel ihres Gens.
      * Kinder setzen sich aus einem Teil der Mutter/Vater sowie einem Teil des Vaters zusammen.
      * Übergeben den Kindern zunächst den vollständigen Gencode und Entferne anschließend
      * an einer zufälligen Stelle den übergebliebenen Code, füge anschließend einen anderen Code
      * (des Vaters/Mutter) in das gleiche Tierchen ein.
      */
     kind1 = null;
     kind2 = null;
     if (mutter.GenCode.Count() == vater.GenCode.Count() &&
         mutter.GenCode.Count() > 0 &&
         mutter.CompleteGenCode.Count() == vater.CompleteGenCode.Count() &&
         mutter.CompleteGenCode.Count() > 0)
     {
         // Gib eine Folge von eindeutigen (unsortierten?) Allelen des jew. Tierchens aus
         // mehrere Allele in einem Tierchen sind möglich - müssen aber extra berücksichtigt werden
         var AllelSizeMutter = mutter.GenCode.Select(allel => allel.Size).Distinct();
         var AllelSizeVater  = mutter.GenCode.Select(allel => allel.Size).Distinct();
         if (AllelSizeMutter.Count() == 1 && AllelSizeVater.Count() == 1)
         {
             var genCodeKind1 = mutter.CompleteGenCode;
             var genCodeKind2 = vater.CompleteGenCode;
             int splitIndex   = randomizer.Next(0, genCodeKind1.Count());
             int GenCodeSize  = genCodeKind1.Count();
             genCodeKind1.RemoveRange(splitIndex, GenCodeSize - splitIndex);
             genCodeKind1.AddRange(vater.CompleteGenCode.GetRange(splitIndex, GenCodeSize - splitIndex));
             genCodeKind2.RemoveRange(splitIndex, GenCodeSize - splitIndex);
             genCodeKind2.AddRange(mutter.CompleteGenCode.GetRange(splitIndex, GenCodeSize - splitIndex));
             kind1 = new Tierchen(mutter.Problem, mutter.GenCode);
             kind1.CompleteGenCode = genCodeKind1;
             kind2 = new Tierchen(vater.Problem, vater.GenCode);
             kind2.CompleteGenCode = genCodeKind2;
         }
     }
     return(false);
 }
        static void Main(string[] args)
        {
            while (restart)
            {
                restart = false;
                repeat  = true;
                Console.Clear();
                TierchenHistory = new List <Tierchen>();
                intervalle      = new List <Intervall>();

                bool couldParsed  = false;
                bool loadDocument = false;
                int  gene         = 0;

                // Überspringe, falls keine start Generation übergeben wurde
                if ((args.Length > 0))
                {
                    Console.WriteLine("Soll das übergebenene Dokument geladen werden? (y/n)");
                    string answer = Console.ReadLine();
                    if (answer == "y")
                    {
                        loadDocument = true;
                        try
                        {
                            // Elterngeneration einladen
                            XDocument doc = XDocument.Load(args[0]);
                            Elterngeneration =
                                // lade alle "tier"-Elemente
                                doc.Root.Descendants("tier").Select(tier =>
                                                                    // erzeuge für jedes ein Tierchen Object
                                                                    new Tierchen(
                                                                        // lade Problem
                                                                        new Problem(int.Parse(tier.Attribute("problemType").Value)),
                                                                        // lade innerhalb des "tier"-Elementes alle "gen"-Elemente
                                                                        tier.Descendants("gen").Select(gen =>
                                                                                                       // erzeuge für jedes ein Allel
                                                                                                       new Allel(
                                                                                                           // lade innerhalb des "gen"-Elementes alle "allel"-Elemente
                                                                                                           gen.Descendants("allel").Select(allel =>
                                                                                                                                           // parse den bool-Wert
                                                                                                                                           bool.Parse(allel.Value)).ToList(),
                                                                                                           // Intervall steht als Attribut innerhalb des "gen"-Elementes
                                                                                                           new Intervall(
                                                                                                               int.Parse(gen.Attribute("interval_start").Value),
                                                                                                               int.Parse(gen.Attribute("interval_end").Value))
                                                                                                           )
                                                                                                       ).ToList()
                                                                        )
                                                                    ).ToList();
                            elternSize = Elterngeneration.Count();
                            Console.WriteLine("gelesene Größe der Elterngeneration:");
                            Console.WriteLine(elternSize);
                        }
                        catch (Exception) { loadDocument = false; }
                    }
                }

                /*
                 * Programmbereiche auskommentiert um die Parametereingabe zu vereinfachen
                 */
                if (!loadDocument)
                {
                    // Problem abfragen
                    couldParsed = false;
                    while (!couldParsed)
                    {
                        Console.WriteLine("Welches Problem soll gelöst werden?\r\n"
                                          + "[1] lineares Gleichungssystem\r\n"
                                          + "[2] Griewank-Funktion\r\n"
                                          + "[3] Ackley-Funktion\r\n"
                                          + "[4] C-Funktion\r\n"
                                          + "[5] Nullstellen-Funktion");
                        string lenght = Console.ReadLine();
                        couldParsed = Problem.TryParse(lenght, out problem);
                    }
                }

                if (!loadDocument)
                {
                    couldParsed = false;
                    while (!couldParsed)
                    {
                        Console.WriteLine("Größe der Elterngeneration?");
                        string lenght = Console.ReadLine();
                        couldParsed = Int32.TryParse(lenght, out elternSize);
                    }
                    //elternSize = 100;
                    Console.WriteLine("Größe Elterngeneration = {0}", elternSize);
                }
                couldParsed = false;
                while (!couldParsed)
                {
                    Console.WriteLine("Wie viele werden davon Rekombiniert?");
                    string lenght = Console.ReadLine();
                    couldParsed = Int32.TryParse(lenght, out countOfRecombinations);
                    couldParsed = couldParsed ? countOfRecombinations < elternSize : false;
                }
                //countOfRecombinations = 50;
                Console.WriteLine("Anzahl Rekombinationen = {0}", countOfRecombinations);
                couldParsed = false;

                /*
                 * Für N-Punkt-Rekombination die Anzahl der Rekombinationspunkte
                 */
                while (!couldParsed)
                {
                    Console.WriteLine("Wie viele Rekombinationspunkte sollen verwendet werden?");
                    string lenght = Console.ReadLine();
                    couldParsed = Int32.TryParse(lenght, out pointOfRecombination);
                }
                couldParsed = false;

                /*
                 * gibt die Anzahl der stellen innerhalb eines Allels an
                 * Bsp: Länge = 6 -> Gen: [001001] [011011] [010010]
                 */
                if (!loadDocument)
                {
                    while (!couldParsed)
                    {
                        Console.WriteLine("Länge des Binärstrings?");
                        string lenght = Console.ReadLine();
                        couldParsed = Int32.TryParse(lenght, out binärStringLenght);
                    }
                    // binärStringLenght = 9;
                    // Console.WriteLine("Binärstringlänge = {0}", binärStringLenght);
                }

                couldParsed = false;
                if (!loadDocument)
                {
                    while (!couldParsed)
                    {
                        Console.WriteLine("Anzahl der Gene?");
                        string lenght = Console.ReadLine();
                        couldParsed = Int32.TryParse(lenght, out gene);
                    }
                    //gene = 1;
                    //Console.WriteLine("Anzahl der Gene = {0}", gene);
                }


                couldParsed = false;
                if (!loadDocument)
                {
                    Console.WriteLine("Möchten Sie verschiedene Intervalle für jedes Gen angeben? [y/n]");
                    string input = Console.ReadLine();
                    if (input == "y")
                    {
                        while (!couldParsed)
                        {
                            Console.WriteLine("Größe des {0}. Intervals?", (intervalle.Count() + 1));
                            string    lenght = Console.ReadLine();
                            Intervall actInterval;
                            couldParsed = Intervall.TryParse(lenght, out actInterval);
                            if (couldParsed)
                            {
                                intervalle.Add(actInterval);
                                couldParsed = (intervalle.Count() >= gene);
                            }
                        }
                    }
                    else
                    {
                        while (!couldParsed)
                        {
                            Console.WriteLine("Größe aller Intervalle?");
                            string    lenght = Console.ReadLine();
                            Intervall actInterval;
                            couldParsed = Intervall.TryParse(lenght, out actInterval);
                            if (couldParsed)
                            {
                                while (intervalle.Count() < gene)
                                {
                                    intervalle.Add(actInterval);
                                }
                            }
                        }
                    }
                    //Intervall actIntervall;
                    //couldParsed = Intervall.TryParse("3", out actIntervall);
                    //intervall.Add(actIntervall);
                    //couldParsed = Intervall.TryParse("3", out actIntervall);
                    //intervall.Add(actIntervall);
                    //couldParsed = Intervall.TryParse("3", out actIntervall);
                    //intervall.Add(actIntervall);

                    // ### hier funktioniert noch die Ausgabe nicht richtig ###
                    // !!! liegt daran, dass interval ein Object ist und c# keine automatische object ausgabe hat
                    // !!! lösung wäre entweder die toString Methode im Object zu deklarieren oder per hand den Start und das ende auszugeben
                    // !!! HINWEIS: die Methode TryParse in der Intervall Klasse versucht aus einem String wie: "[-1,1]" oder "-1,1" ein Intervall auszulesen
                    //couldParsed = Intervall.TryParse("3,5", out actIntervall);
                    //intervall.Add(actIntervall);
                    Console.WriteLine("Intervalle = {0}", String.Join(",", intervalle.Select(o => o.ToString()).ToArray()));
                }

                couldParsed = false;
                while (!couldParsed)
                {
                    Console.WriteLine("Größe der History?");
                    string lenght = Console.ReadLine();
                    couldParsed = Int32.TryParse(lenght, out historySize);
                }
                couldParsed = false;

                /*
                 * ### Wie definiert sich die Größe? Sind es Mengen von Tierchen oder Mengen von Generationen? ###
                 * !!! Größe der History bestimmt, wie viel besten Tierchen gesoeichert werden sollen, damit die History nicht unnötig voll läuft
                 * !!! Beispiel: Größe der History auf 10 gesetzt bewirkt, dass die History ( nach Wertigkeit sortiert ) die besten 10 Tierchen enthält
                 */
                //historySize = 2;

                while (!couldParsed)
                {
                    Console.WriteLine("Generationen die erzeugt werden sollen?");
                    string lenght = Console.ReadLine();
                    couldParsed = Int32.TryParse(lenght, out countOfGenerations);
                }
                // es wurde keine Anfangs-Generation übergeben
                if (!loadDocument)
                {
                    Elterngeneration = new List <Tierchen>();
                    // erzeuge Elterngeneration
                    while (Elterngeneration.Count < elternSize)
                    {
                        Elterngeneration.Add(Tierchen.RandomTier(binärStringLenght, intervalle, gene, problem));

                        /*
                         * ### Wie kommt das mit dem Distinct zustande ? ###
                         * ### Ist ToList() eine Methode einer über TierchenComparer liegenden Klasse ? ###
                         * ### Welche voraussetzungen müssen erfüllt sein ? ###
                         * !!! Hatten wir ja geklärt, oder?
                         */
                        Elterngeneration = Elterngeneration.Distinct(new TierchenComparer()).ToList();
                    }
                    try
                    {
                        // Elterngeneration im Programm Verzeichnis unter dem Namen "last.xml" speichern
                        // xml-Dokument erzeugen
                        XDocument doc = new XDocument(
                            // erzeuge des Wurzelelement "generation"
                            new XElement("generation",
                                         // für jedes tier in der Generation
                                         Elterngeneration.Select(tier =>
                                         // erzeuge "tier"-Element
                                                                 new XElement("tier",
                                         // erzeuge Problem-Attribute
                                                                              new XAttribute("problemType",
                                                                                             (int)(tier.Problem.ProblemType)
                                                                                             ),
                                                                              // für jedes gen im tierchen
                                                                              tier.GenCode.Select(gen =>
                                                                              // erzeuge "gen"-Element
                                                                                                  new XElement("gen",
                                                                              // füge "interval_start"-Attribut hinzu
                                                                                                               new XAttribute("interval_start",
                                                                                                                              gen.Interval.start
                                                                                                                              ),
                                                                                                               // füge "interval_end"-Attribut hinzu
                                                                                                               new XAttribute("interval_end",
                                                                                                                              gen.Interval.end
                                                                                                                              ),
                                                                                                               // für jedes allel (Bit) im Gen
                                                                                                               gen.BinärCode.Select(allel =>
                                                                                                               // speichere bool'schen Wert
                                                                                                                                    new XElement("allel",
                                                                                                                                                 allel.ToString()
                                                                                                                                                 )
                                                                                                                                    )
                                                                                                               )
                                                                                                  )
                                                                              )
                                                                 )
                                         )
                            );
                        // dokument speichern
                        doc.Save("last.xml");
                    }
                    catch (Exception) { }
                }

                foreach (var tier in Elterngeneration)
                {
                    Console.WriteLine("Tier: {0} | Wert:\t{1}", tier.ToString(), tier.Wert.ToString("####0.#####"));
                }

                /*
                 * Ab hier beginnen die Methoden
                 * Zunächst wird Selektiert
                 */
                Random randomizer = new Random();
                int    counter    = 0;
                while (repeat)
                {
                    repeat = false;
                    // Sichere die aktuelle Elterngeneration in die History
                    TierchenHistory.AddRange(Elterngeneration);

                    //Eliminiere die Doppelten
                    TierchenHistory = TierchenHistory.Distinct(new TierchenComparer()).OrderBy(tier => tier.Wert).Take(historySize).ToList();

                    Kindgeneration = new List <Tierchen>();

                    //Rufe Ein-Punkt-Rekombination auf
                    Kindgeneration = EvolutionAlgorithms.NPunktRekombination(randomizer, countOfRecombinations, pointOfRecombination, Kindgeneration, Elterngeneration);

                    Kindgeneration = EvolutionAlgorithms.mutiereKinder(randomizer, Kindgeneration, Elterngeneration, elternSize);

                    /*
                     * Der folgende Bereich sollte nicht direkt beschritten werden
                     * Die Methoden sollten aufrufbar / wählbar sein
                     */
                    // ### [NEW] ist ein wenig Kritisch, da diese Frage vor jedem Erteugen einer neuen Generation gestellt wird
                    // ### das heißt wenn man auf einen Schlag 100 Generationen erzeugen will wird diese Schleife immer durch diese Frage unterbrochen
                    // ### Frage Stellen, bevor ein neuen Durchlauf beginnt (siehe Frage nach Wiederholung)
                    repeat2 = true;
                    while (repeat2)
                    {
                        /*
                         * Console.WriteLine("Welche Selektion soll ausgeführt werden?\r\n[n]: keine (Kinder als Elten übernehmen)\r\n[k]: Komma\r\n[p]: Plus\r\n[...]");
                         * var input = Console.ReadLine();
                         * if (input == "n")
                         * {*/
                        repeat2 = false;
                        //Lösche alle Eltern
                        Elterngeneration.Clear();

                        //Kindgeneration ist neue Elterngeneration
                        Elterngeneration.AddRange(Kindgeneration);

                        //Jetzt kann die Kindgeneration gelöscht werden
                        Kindgeneration.Clear();    /*
                                                    * }
                                                    * else if (input == "k")
                                                    * {
                                                    * repeat2 = false;
                                                    * EvolutionAlgorithms.commaSelection(Kindgeneration, Wahlverfahren.determenistic);
                                                    * //KommaSelektion(randomizer);
                                                    * }
                                                    * else if (input == "p")
                                                    * {
                                                    * repeat2 = false;
                                                    * EvolutionAlgorithms.plusSelection(Elterngeneration,Kindgeneration, Wahlverfahren.determenistic);
                                                    * //KommaSelektion(randomizer);
                                                    * }*/
                    }


                    //foreach (var tier in Elterngeneration)
                    //{
                    //    Console.WriteLine("Tier: {0} | Wert:\t{1}", tier.ToString(), tier.Wert.ToString("####0.#####"));
                    //}
                    if (counter != 0 && (countOfGenerations / counter) % 10 == 0)
                    {
                        Console.WriteLine("{0}% Verbleibend", countOfGenerations / counter);
                    }
                    counter++;
                    if (counter >= countOfGenerations)
                    {
                        // letzte Sicherung der Elterngeneration in die History
                        TierchenHistory.AddRange(Elterngeneration);

                        //Eliminiere die Doppelten
                        TierchenHistory = TierchenHistory.Distinct(new TierchenComparer()).OrderBy(tier => tier.Wert).Take(historySize).ToList();

                        counter = 0;
                        Console.WriteLine("Soll das Beste aller erzeugten Individuen gezeigt werden? (y/n)");
                        var input = Console.ReadLine();
                        if (input == "y")
                        {
                            int countOfShownTierchen = 0;
                            couldParsed = false;
                            while (!couldParsed)
                            {
                                Console.WriteLine("Wie viele sollen gezeigt werden?");
                                string lenght = Console.ReadLine();
                                couldParsed = Int32.TryParse(lenght, out countOfShownTierchen);
                            }
                            foreach (var tier in TierchenHistory.OrderBy(tier => tier.Wert).Take(countOfShownTierchen).ToList())
                            {
                                Console.WriteLine("Tier: {0}", tier.ToNicerString());
                            }
                        }

                        Console.WriteLine("Wiederholen? (y/n)");
                        input = Console.ReadLine();
                        if (input == "y")
                        {
                            repeat = true;
                        }
                        else
                        {
                            repeat = false;
                            Console.WriteLine("Neustarten? (y/n)");
                            input = Console.ReadLine();
                            if (input == "y")
                            {
                                restart = true;
                            }
                            else
                            {
                                restart = false;
                            }
                        }
                    }
                    else
                    {
                        repeat = true;
                    }
                }
            }
        }
Example #8
0
        public static bool NPointRecombination(Random randomizer, Tierchen mutter, Tierchen vater, out Tierchen kind1, out Tierchen kind2, int recombinationPoints = 1)
        {
            /* N-Punkt-Rekombination wählt zwei Tierchen sowie zufällig je n Allele ihres Gens.
             * Kinder setzen sich aus einem Teil der Mutter/Vater sowie einem Teil des Vaters zusammen.
             * Übergeben den Kindern zunächst den vollständigen Gencode und Entferne anschließend
             * an einer zufälligen Stelle den übergebliebenen Code, füge anschließend einen anderen Code
             * (des Vaters/Mutter) in das gleiche Tierchen ein.
             */

            kind1 = null;
            kind2 = null;
            if (mutter.GenCode.Count() == vater.GenCode.Count() &&
                mutter.GenCode.Count() > 0 &&
                mutter.CompleteGenCode.Count() == vater.CompleteGenCode.Count() &&
                mutter.CompleteGenCode.Count() > 0)
            {
                if (recombinationPoints <= mutter.CompleteGenCode.Count())
                {
                    bool chooseFirstFromMother = true;
                    // Gib eine Folge von eindeutigen (unsortierten?) Allelen des jew. Tierchens aus
                    // mehrere Allele in einem Tierchen sind möglich - müssen aber extra berücksichtigt werden
                    var AllelSizeMutter = mutter.GenCode.Select(allel => allel.Size).Distinct();
                    var AllelSizeVater  = mutter.GenCode.Select(allel => allel.Size).Distinct();
                    if (AllelSizeMutter.Count() == 1 && AllelSizeVater.Count() == 1)
                    {
                        var genCodeKind1 = mutter.CompleteGenCode;
                        var genCodeKind2 = vater.CompleteGenCode;

                        // erstelle Split-indizes
                        var SplitIndizes = new List <int>();
                        for (int i = 0; i < recombinationPoints; i++)
                        {
                            SplitIndizes.Add(randomizer.Next(i == 0?0:SplitIndizes.LastOrDefault() + 1, genCodeKind1.Count() + 1 - (recombinationPoints - i)));
                        }
                        int GenCodeSize = genCodeKind1.Count();
                        SplitIndizes.Sort();
                        // für jeden Splitindex  gencode zusammensetzen
                        foreach (var splitIndex in SplitIndizes)
                        {
                            if (chooseFirstFromMother)
                            {
                                genCodeKind1.RemoveRange(splitIndex, GenCodeSize - splitIndex);
                                genCodeKind1.AddRange(vater.CompleteGenCode.GetRange(splitIndex, GenCodeSize - splitIndex));
                                genCodeKind2.RemoveRange(splitIndex, GenCodeSize - splitIndex);
                                genCodeKind2.AddRange(mutter.CompleteGenCode.GetRange(splitIndex, GenCodeSize - splitIndex));
                            }
                            else
                            {
                                genCodeKind1.RemoveRange(splitIndex, GenCodeSize - splitIndex);
                                genCodeKind1.AddRange(mutter.CompleteGenCode.GetRange(splitIndex, GenCodeSize - splitIndex));
                                genCodeKind2.RemoveRange(splitIndex, GenCodeSize - splitIndex);
                                genCodeKind2.AddRange(vater.CompleteGenCode.GetRange(splitIndex, GenCodeSize - splitIndex));
                            }
                            chooseFirstFromMother = !chooseFirstFromMother;
                        }
                        kind1 = new Tierchen(mutter.Problem, mutter.GenCode);
                        kind1.CompleteGenCode = genCodeKind1;
                        kind2 = new Tierchen(vater.Problem, vater.GenCode);
                        kind2.CompleteGenCode = genCodeKind2;
                    }
                }
            }
            return(false);
        }