Python :: Aufgabe #296

2 Lösungen Lösungen öffentlich

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

Lösungen:

vote_ok
von Kryptonos (180 Punkte) - 05.11.2020 um 15:48 Uhr
Quellcode ausblenden Python-Code
import math 

def birthday(no_people=1, chance=1/2):
    """
    Funktion, welche die benoetigte Anzahl von Gaesten auf einer Party errechnet,
    um die Wahrscheinlichkeit p(chance) zu erhalten, dass n Personen(no_people) 
    am gleichen Tag wie der Gastgeber Geburtstag haben. 
    Parameters
    ----------
    no_people : int
        Die Anzahl von Personen, die am gleichen Tag wie der 
        Gastgeber Geburtstag haben sollen.
    
    chance : int/int < 1
        Die Wahrscheinlichkeit, mit der n Personen am gleichen Tag wie der
        Gastgeber Geburtstag haben sollen.
    
    Returns
    -------
    Die Anzahl der Gaeste, welche benötigt wird um die gesuchte Wahrscheinlichkeit
    zu erreichen( aufgerundet auf den nächstgrößeren int-Wert ).
    
    """
    return round((math.log(1-chance)/math.log(1-no_people/365))+0.49)
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()
1988251

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.