C# :: Aufgabe #267 :: Lösung #1

2 Lösungen Lösungen öffentlich
#267

Entwicklung einer Population bishin zur vollständigen Verwandtschaft

Anfänger - C# von hollst - 04.11.2019 um 12:38 Uhr
Gegeben sei eine Startpopulation mit 2N Mitgliedern (z. B. N = 100), N männliche und N weibliche, die N Elternpaare bilden.

Jedes Elternpaar erzeuge genau einen männlichen und einen weiblichen Nachkommen. Diese 2N Nachkommen bilden
anschließend durch Vermischung die nächste Generation von Eltern und so fort bis zur Generation g, die natürlich wieder 2N Populationsmitglieder hat.

Bei einer Vermischung sei Inzest (Bruder-Schwester-Ehe) verboten, eine Ehe zwischen Cousin und Cousine allerdings erlaubt.

Mittels Computersimulation sind zwei Fragen zu beantworten:

Die erste Frage lautet, nach wie vielen Generationen (g1) ist (im Mittel) erstmals ein Nachkomme mit allen Populationsmitgliedern
seiner Generation verwandt.

Die zweite Frage lautet, nach wie vielen Generationen (g2) ist (im Mittel) jeder Nachkomme mit allen Populationsmitgliedern
seiner Generation verwandt.

Viel Spaß!
#1
vote_ok
von hollst (13980 Punkte) - 06.11.2019 um 17:01 Uhr
Quellcode ausblenden C#-Code
using static System.Console;

using COGNATION;

namespace COGNITION_CONSOLE
{
    static class Program
    {
        static void Main()
        {
            int counter = 0, g1 = 0, g2 = 0;
            int NumberOfPopulation = 250, max_loops = 10000;
            while (counter < max_loops)
            {
                COGNATION.GenerationSequence gs = new GenerationSequence(NumberOfPopulation);
                g1 += gs.g1;
                g2 += gs.g2;
                counter++;
                $"g1: {gs.g1}   ng1: {gs.ng1}   g2: {gs.g2}    NumberOfPopulation: {NumberOfPopulation}".Info();
                WriteLine(1.0 * g1 / counter);
                WriteLine(1.0 * g2 / counter);
                $"loops: {counter}".Info();
            }
            "ready".PressKey();
        }
    }
}


Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Text;

using static System.Console;

namespace COGNATION
{
    public class ShuffleClass         //Fisher - Yates shuffle
    {
        private readonly Random rand;
        private readonly bool bo_reset;
        private readonly bool bo_all;
        private readonly int count_cards;

        public int[] Mix { get; private set; }
        public ShuffleClass(int count_cards, bool bo_reset = false, bool bo_all = false)
        {
            this.count_cards = count_cards;
            this.rand = new Random();
            this.bo_all = bo_all;
            this.bo_reset = bo_reset;
            this.Mix = new int[count_cards];
        }

        public void Shuffle()
        {
            for (var i = 0; i < count_cards; i++)
                this.Mix[i] = i;
            if (bo_reset)
                return;

            Stack<int> stack = new Stack<int>();
            for (var j = Mix.Length - 1; j > 0; j--)
            {
                int jj = rand.Next(j + 1);
                if (bo_all && (jj == j)) //Inzest verboten
                    j += 1;//Auslosung wiederholen
                else
                {
                    stack.Push(Mix[jj]);
                    Mix[jj] = Mix[j];
                    Mix[j] = stack.Pop();
                }
            }
        }
    }

    public class GenerationSequence
    {
        public bool[][] result;
        public int g1, g2, ng1;
        public GenerationSequence(int NumberOfPopulation)
        {
            result = new bool[NumberOfPopulation][];
            g1 = 0;
            g2 = 0;
            ng1 = -1;

            for (var i = 0; i < NumberOfPopulation; i++)
            {
                result[i] = new bool[NumberOfPopulation];
                result[i][i] = true;//Zunächst ist jeder nur mit sich selber verwandt.
            }

            bool[][] result_old = result.DeepCopy();
            int generation_counter = 0;

            ShuffleClass s = new ShuffleClass(NumberOfPopulation, bo_all: true);

            bool bo_ready = false;
            while (!bo_ready)
            {
                s.Shuffle();
                for (var i = 0; i < NumberOfPopulation; i++)
                    for (var j = 0; j < NumberOfPopulation; j++)
                        result[i][j] = result_old[i][j] | result_old[s.Mix[i]][j];
                result_old = result.DeepCopy();
                generation_counter++;

                int z2 = 0;
                for (var i = 0; i < NumberOfPopulation; i++)
                {
                    int z1 = 0;
                    for (var j = 0; j < NumberOfPopulation; j++)
                        if (result[i][j])
                            z1++;
                    if (z1 == NumberOfPopulation)
                    {
                        if (g1 == 0)
                        { 
                            g1 = generation_counter;
                            ng1 = i;
                        }
                        z2++;                        
                    }
                }
                if (z2 == NumberOfPopulation)
                    g2 = generation_counter;
                bo_ready = g2 != 0;
            }
        }
    }

    public static class Extentions
    {
        public static void PressKey(this string s)
        {
            WriteLine(s); ReadKey();
        }

        public static void Info(this string s) =>   WriteLine(s);

        public static bool[][] DeepCopy(this bool[][] b)
        {
            bool[][] result = new bool[b.Length][];
            for(var i = 0; i < result.Length; i++)
            {
                result[i] = new bool[b[i].Length];
                for (var j = 0; j < result[i].Length; j++)
                    result[i][j] = b[i][j];
            }
            return result;
        }
    }
}

Kommentare:

Für diese Lösung gibt es noch keinen Kommentar

Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben