Python :: Aufgabe #296 :: Lösung #2

2 Lösungen Lösungen öffentlich
#296

Geburtstags-Paradoxon

Fortgeschrittener - Python von JKooP - 24.10.2020 um 18:45 Uhr
Du feierst eine Geburtstagsparty. Nach und nach kommen immer mehr Gäste.
Während des Wartens stellst du dir die Frage, wie viele der anwesenden Personen ebenfalls heute Geburtstag haben könnten.

Schreibe eine Methode/Funktion, die einen Wert zurückliefert, ab wie vielen Gästen die Wahrscheinlich bei größer 50% liegt, dass mindestens noch ein Gast am gleichen Tag Geburtstag hat.

Bedingungen:
- nur der Tag des Jahres, nicht zusätzlich das Geburtsjahr sollen übereinstimmen
- das Jahr hat konstant 365 Tage
- saisonal bedingte Geburtenraten sollen nicht betrachtet werden
#2
vote_ok
von Klaus (1960 Punkte) - 11.12.2020 um 08:59 Uhr
Eine sehr gute theoretische Einführung in das Thema findet ihr beim Mathe-Guru

Link zur Seite auf Mathe-Guru

Meine Lösung beinhaltet sowohl die exakte stochastische Berechnung, als auch einen Lösungsansatz über eine Simulation.
Obwohl die Komplexität des Problems natürlich keinen OOP-Ansatz erforderlich macht, habe ich diesen aus Spaß umgesetzt.

Falls noch nicht geschehen, müsst ihr euch bitte die Library Matplotlib zur Visualisierung installieren.

Quellcode ausblenden Python-Code
import random as rnd
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['font.family'] = 'arial'


class BirthdayParadoxon:

    def __init__(self, probability, max_nof_guests, type):
        self.probability = probability
        self.max_nof_guests = max_nof_guests
        self.type = type
        self.result = None
        self.prob_data = {}
        for index in range(1, self.max_nof_guests + 1):
            self.prob_data[index] = 0

    def start(self):
        self.get_data()
        self.get_result()
        self.show()

    def get_data(self):
        raise Exception('no implementation of the __get_data-function')

    def get_result(self):
        for element in self.prob_data:
            if self.prob_data[element] >= self.probability:
                self.result = element
                break

    def show(self):

        x = list(self.prob_data.keys())
        y = list(self.prob_data.values())

        plt.plot(x, y, 'b')
        plt.plot(x, [self.probability]*len(x), 'r--')
        plt.title(
            f'{self.type} der Wahrscheinlichkeit des identischen Geburtstages', fontsize=10)
        plt.xlabel('Anzahl der Gäste', fontsize=8)
        plt.ylabel('Wahrscheinlichkeit', fontsize=8)

        if self.result:
            plt.text(self.result, self.probability - self.probability/2,
                     f'Die {self.type} hat ergeben, dass die \nWahrscheinlichkeit '
                     f'von {self.probability * 100}% ab \ndem {self.result} Gast erreicht wurde.',
                     fontsize=9)
        else:
            plt.text(self.max_nof_guests//4, 0.25, f'Es konnte kein Ergebnis ermittelt werden. \nDie maximale Anzahl an Gästen von '
                     f'{self.max_nof_guests} ist zu gering. \nBitte erhöhe den Wert.')
        plt.show()


class Calculation(BirthdayParadoxon):

    def __init__(self, probability=0.5, max_nof_guests=1000):
        super().__init__(probability, max_nof_guests, 'Kalkulation')

    def get_data(self):
        for element in self.prob_data:
            self.prob_data[element] = 1-((365-1)/365)**element


class Simulation(BirthdayParadoxon):

    def __init__(self, probability=0.5, max_nof_guests=1000, nof_iteration=1000):
        super().__init__(probability, max_nof_guests, 'Simulation')
        self.nof_iteration = nof_iteration

    def get_data(self):
        for iteration in range(self.nof_iteration):
            birthday_list = []
            for guest in range(1, self.max_nof_guests+1):
                birthday_list.append(rnd.randint(1, 365))
                if 1 in birthday_list:
                    self.prob_data[guest] += 1

        for element in self.prob_data:
            self.prob_data[element] = self.prob_data[element] / \
                self.nof_iteration


test_data = [Calculation(), Simulation(), Calculation(
    0.2, 200), Simulation(0.2, 200), Calculation(0.95, 2000)]

if __name__ == "__main__":
    for test in test_data:
        test.start()

Kommentare:

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

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