Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Birthday Paradox - Tính số người trùng sinh nhật Python

Mô tả bài toán

Birthday Paradox: Xác suất ít nhất 2 người cùng sinh nhật trong nhóm n người.

Công thức xấp xỉ số người cần cho xác suất p:

N ≈ √(2 × 365 × ln(1/(1-p)))

Giải pháp

import math

def findPeople(p):
    """Trả về số người tối thiểu để xác suất trùng sinh nhật >= p."""
    if p <= 0 or p >= 1:
        raise ValueError("Xác suất p phải trong (0, 1)")
    return math.ceil(math.sqrt(2 * 365 * math.log(1 / (1 - p))))

# Test
probabilities = [0.5, 0.7, 0.9, 0.99]
for p in probabilities:
    n = findPeople(p)
    print(f"P ≥ {p:.0%}: cần ít nhất {n} người")

# Kiểm tra chính xác bằng công thức chính xác
def exact_probability(n):
    """Tính xác suất chính xác không ai trùng sinh nhật."""
    prob = 1.0
    for i in range(n):
        prob *= (365 - i) / 365
    return 1 - prob

print("\nSo sánh xấp xỉ vs chính xác:")
for n in [23, 30, 41, 57]:
    approx = findPeople(exact_probability(n))
    print(f"n={n}: P_exact={exact_probability(n):.4f}, approx_n={approx}")

Đầu ra

P ≥ 50%: cần ít nhất 23 người
P ≥ 70%: cần ít nhất 30 người
P ≥ 90%: cần ít nhất 41 người
P ≥ 99%: cần ít nhất 57 người

So sánh xấp xỉ vs chính xác:
n=23: P_exact=0.5073, approx_n=23
n=30: P_exact=0.7063, approx_n=30
n=41: P_exact=0.9032, approx_n=41
n=57: P_exact=0.9901, approx_n=57

Giải thích công thức

Xác suất KHÔNG ai trùng sinh nhật:

P(different) = 365/365 × 364/365 × 363/365 × ... × (365-n+1)/365

Xấp xỉ: P(different) ≈ e^(-n²/(2×365))

→ P(same) = 1 - P(different) ≈ 1 - e^(-n²/730)

Giải n: n ≈ √(-730 × ln(1-p)) = √(2×365×ln(1/(1-p)))

Ứng dụng: Kỹ thuật tấn công birthday attack trong mật mã học (hash collision).