当前位置: 首页 > news >正文

从生日悖论看哈希函数的冲突问题

在讨论这个问题之前,先回顾一下哈希表是什么

1. 哈希表是什么?

哈希表(Hash Table)是一种 键–值对存储结构。

形象理解:
👉 就像一个“大柜子”,有很多小格子(桶)。
👉 你把名字(键)交给管理员(哈希函数),管理员告诉你“放到第 17 号格子”。
👉 下次再来找,只要去第 17 号格子就能拿到对应的值。

2. 哈希函数是什么?

哈希函数(Hash Function)就是一个 把任意输入映射到固定范围整数 的函数。

常见形式:

h(k)=kmod  mh(k) = k \mod mh(k)=kmodm

(对整数键取模)

好的哈希函数要满足:

均匀性:让键尽可能分布均匀

确定性:相同输入必然映射到相同输出

高效性:计算要快

3. 哈希表的优势

查找、插入、删除平均时间复杂度为 O(1)

实现简单,底层就是数组 + 哈希函数

4. 哈希表的问题:冲突

因为桶的数量有限,不同的键可能映射到同一个位置,这叫 冲突 (Collision)。

常见的解决冲突的方法有:

链地址法(Chaining)开放寻址法(Open Addressing)双重哈希 / 再哈希Cuckoo Hashing

什么是生日悖论

最简单的想法就是 每个人的生日不相同的概率与直觉相违背。
比如:

我们知道 367 个人里必然有两个人同生日;

但很少人知道其实 23 个人时概率就超过 50%;

当人数达到 100 人时概率接近 99.997%。

生日悖论(Birthday Paradox) 指的是这样一个现象:
在只有 23 个人的群体里,至少有两个人生日相同的概率就超过 50%;当人数达到 100 时,这个概率几乎是 100%。

之所以叫“悖论”,是因为直觉认为要接近 365 人才会撞生日,但实际上由于 人数一多,两两比较的组合数急剧增加,重复的可能性比想象大得多。

数学推导(不计闰年)

设房间里有n个人,一年有m=365天。
所有人互不相同的概率:
Pdistinct(n)=m!(m−n)! mn P_{\text{distinct}}(n)=\frac{m!}{(m-n)!\,m^n} Pdistinct(n)=(mn)!mnm!
至少两人同生日的概率:
Pcollision(n)=1−Pdistinct(n) P_{\text{collision}}(n) = 1 - P_{\text{distinct}}(n) Pcollision(n)=1Pdistinct(n)
关键在于这个排列数,增长速度是飞快的。
下面给出一个python模拟代码可以看看这个小例子:

import random
from collections import Counterdef simulate_birthdays(n_people=100, n_days=365):# 随机生成 n_people 个生日(取值 1 到 n_days)birthdays = [random.randint(1, n_days) for _ in range(n_people)]return birthdaysdef has_duplicate(birthdays):c = Counter(birthdays)# 如果有任何一个生日出现次数 > 1,就说明有重复return any(count > 1 for count in c.values()), cdef main(trials=10000):duplicate_count = 0for _ in range(trials):bb = simulate_birthdays()dup, cnt = has_duplicate(bb)if dup:duplicate_count += 1print(f"在 {trials} 次模拟中,至少一对生日相同的频率是 {duplicate_count/trials:.6f}")# 这里再展示一次单次模拟的具体生日分布example = simulate_birthdays()print("一次模拟生成的 100 人生日样本如下:")print(sorted(example))if __name__ == "__main__":main()

如何估计生日悖论概率超过50%的数量?

事件:在 nnn 次独立投掷到 mmm 个等概率“格子”里,出现 至少一对碰撞(两次落同格)。

用泊松/指数近似:

P(碰撞)≈1−exp⁡ ⁣(−n(n−1)2m) P(\text{碰撞}) \approx 1-\exp\!\Big(-\tfrac{n(n-1)}{2m}\Big) P(碰撞)1exp(2mn(n1))

P(碰撞)=0.5P(\text{碰撞})=0.5P(碰撞)=0.5,得门槛 n50n_{50}n50

n50  ≈  2mln⁡2  =  1.1774 m n_{50} \;\approx\; \sqrt{2m\ln 2} \;=\; 1.1774\,\sqrt{m} n502mln2=1.1774m

  • 生日问题m=365m=365m=365
    n50≈1.1774365≈22.5 n_{50}\approx 1.1774\sqrt{365}\approx 22.5 n501.177436522.5
    四舍五入就是 23

  • bbb 位哈希m=2bm=2^bm=2b
    n50≈1.1774⋅2b/2 n_{50}\approx 1.1774\cdot 2^{b/2} n501.17742b/2

    例:64 位哈希
    n50≈1.1774⋅232≈5.05×109 n_{50}\approx 1.1774\cdot 2^{32}\approx 5.05\times 10^9 n501.17742325.05×109

简单来说,对于哈希函数来说,虽然可以增加很多键值对内存空间,但是当处于sqrt(n)时,冲突的概率就会超过50%,这样就是冲突的来源。
我们可以通过构建双重哈希的方式避免一些冲突问题,即把哈希的键再当成值,建立了新的哈希表这样。


文章转载自:

http://nHYb4rqN.htbbp.cn
http://BheRNzrX.htbbp.cn
http://C6URjNwR.htbbp.cn
http://qwan01dx.htbbp.cn
http://rTIa7MQx.htbbp.cn
http://iuuPfSSL.htbbp.cn
http://OZ177FRe.htbbp.cn
http://4NQ7e6KY.htbbp.cn
http://m5iVRJld.htbbp.cn
http://eknMqmES.htbbp.cn
http://OEBbGq9u.htbbp.cn
http://JJ6uEKG9.htbbp.cn
http://H4oVnWqx.htbbp.cn
http://fm183YtE.htbbp.cn
http://b3FSmmrx.htbbp.cn
http://MJSkuXrt.htbbp.cn
http://UkbNvvV3.htbbp.cn
http://Jlna28PE.htbbp.cn
http://4s08vpNa.htbbp.cn
http://FldIMxhW.htbbp.cn
http://B1zgqf9d.htbbp.cn
http://1d6nm3aH.htbbp.cn
http://uzpAG76j.htbbp.cn
http://KuiKWANH.htbbp.cn
http://aHtd3LJ3.htbbp.cn
http://b1N4PmIt.htbbp.cn
http://KKjDUj29.htbbp.cn
http://wMuAX5Vy.htbbp.cn
http://oAc811y2.htbbp.cn
http://ijkaArnP.htbbp.cn
http://www.dtcms.com/a/375710.html

相关文章:

  • UDS诊断详解(二)27服务安全访问流程
  • 如何解决Ubuntu下vi编辑器方向键变字母的问题?
  • [硬件电路-172]:浮空、单点接地、多点接地的比较
  • DNS协议
  • 网络编程---UDP
  • 深入了解linux系统—— 线程同步
  • 基于Mysql+SpringBoot+vue框架-桂林旅游景点导游平台源码
  • 案例二:登高千古第一绝句
  • 将「本地仓库」推送(关联)到「远程仓库」 远程仓库的修改 Pull 到关联的本地仓库
  • 玄机--IIS日志分析
  • ART的GC算法
  • 【CAD.NET】dwg存储为png
  • 前端日志回捞系统的性能优化实践|得物技术
  • 基于R语言机器学习方法在生态经济学领域中的实践技术应用
  • 【1分钟速通】 HTML快速入门
  • Spring IocDI(二)
  • 《QT 108好类》之16 QComboBox类
  • 物联网平台中的MongoDB(一)服务模块设计与架构实现
  • QT里的QSlider滑块样式设计【记录】
  • HTTP/3.0:网络通信的技术革新与性能飞跃
  • Spring Boot--yml配置信息书写和获取
  • 笔记7 FreeRTOS低功耗模式和内存管理
  • 慧荣SM770新一代USB显示接口芯片方案,支持三路并行4K显示扩展方案
  • 嵌入式基础知识——关键字
  • 小红书卡片制作源码后台
  • MySQL,SQL Server,PostgreSQL三种数据库的区别
  • 基于Yolov8实现在Label-Studio实现半自动标注
  • Spring Boot---自动配置原理和自定义Starter
  • NFS资源共享服务
  • 新手向:Python网络编程,搭建简易HTTP服务器