• 乘法散列表的分析


    构造乘法散列表的乘法方法包含了两个步骤:

    1. 用关键字 K 乘上常数 A (0<A<1),并抽取出 kA 的小数部分

    2. 然后再用 m 乘以这个值,再向下去整

    总之散列函数为:

    h(k) = |_ (m*(k*Amod1)) _|

    这里对m没有太大的要求,一般选择他为2的某个幂次方( m 的取值规定了hash的长度)

    Knuth提出 A 的最佳选择为 A ≈ (√5-1)/2 = 0.618 033 988 7....

    这里引出了我对这个 A 的值的思考。于是我写了程序来对 A 的选择做了测试。

    首先我以 A={0, 0.01, 0.02 ...... 0.98, 0.99} 这些数字做了测试,并且m的取值为1000。

    从而得出以下的结果:

    Case 1000:
    	a:0.010000	 num:0
    	a:0.020000	 num:49
    	a:0.030000	 num:0
    	a:0.040000	 num:74
    	a:0.050000	 num:79
    	a:0.060000	 num:50
    	a:0.070000	 num:0
    	a:0.080000	 num:74
    	a:0.090000	 num:0
    	a:0.100000	 num:89
    	a:0.110000	 num:0
    	a:0.120000	 num:74
    	a:0.130000	 num:0
    	a:0.140000	 num:49
    	a:0.150000	 num:79
    	a:0.160000	 num:74
    	a:0.170000	 num:0
    	a:0.180000	 num:50
    	a:0.190000	 num:0
    	a:0.200000	 num:95
    	a:0.210000	 num:0
    	a:0.220000	 num:50
    	a:0.230000	 num:0
    	a:0.240000	 num:75
    	a:0.250000	 num:96
    	a:0.260000	 num:50
    	a:0.270000	 num:0
    	a:0.280000	 num:75
    	a:0.290000	 num:0
    	a:0.300000	 num:90
    	a:0.310000	 num:0
    	a:0.320000	 num:75
    	a:0.330000	 num:0
    	a:0.340000	 num:50
    	a:0.350000	 num:80
    	a:0.360000	 num:75
    	a:0.370000	 num:0
    	a:0.380000	 num:50
    	a:0.390000	 num:0
    	a:0.400000	 num:95
    	a:0.410000	 num:0
    	a:0.420000	 num:50
    	a:0.430000	 num:0
    	a:0.440000	 num:75
    	a:0.450000	 num:80
    	a:0.460000	 num:50
    	a:0.470000	 num:0
    	a:0.480000	 num:75
    	a:0.490000	 num:0
    	a:0.500000	 num:98
    	a:0.510000	 num:0
    	a:0.520000	 num:75
    	a:0.530000	 num:0
    	a:0.540000	 num:50
    	a:0.550000	 num:80
    	a:0.560000	 num:75
    	a:0.570000	 num:0
    	a:0.580000	 num:50
    	a:0.590000	 num:0
    	a:0.600000	 num:95
    	a:0.610000	 num:0
    	a:0.620000	 num:50
    	a:0.630000	 num:0
    	a:0.640000	 num:75
    	a:0.650000	 num:80
    	a:0.660000	 num:50
    	a:0.670000	 num:0
    	a:0.680000	 num:75
    	a:0.690000	 num:0
    	a:0.700000	 num:90
    	a:0.710000	 num:0
    	a:0.720000	 num:75
    	a:0.730000	 num:0
    	a:0.740000	 num:50
    	a:0.750000	 num:96
    	a:0.760000	 num:75
    	a:0.770000	 num:0
    	a:0.780000	 num:50
    	a:0.790000	 num:0
    	a:0.800000	 num:95
    	a:0.810000	 num:0
    	a:0.820000	 num:50
    	a:0.830000	 num:0
    	a:0.840000	 num:75
    	a:0.850000	 num:80
    	a:0.860000	 num:50
    	a:0.870000	 num:0
    	a:0.880000	 num:75
    	a:0.890000	 num:0
    	a:0.900000	 num:90
    	a:0.910000	 num:0
    	a:0.920000	 num:75
    	a:0.930000	 num:0
    	a:0.940000	 num:50
    	a:0.950000	 num:80
    	a:0.960000	 num:75
    	a:0.970000	 num:0
    	a:0.980000	 num:50
    	a:0.990000	 num:0
    


    这里 hash 长度是1000,插入数字为 0~100, num 表示碰撞次数,可以看到一个明显的现象:对于a的末尾为奇数时,大部分均有很低的概率发生碰撞,而当为偶数的时候碰撞次数均很大,而且很多均是 50 或者是 75。

    分析发现,这里和末尾那个偶数有关,因为这里是两位小数,乘数是10x 级,所以只要是偶数,当对 1 取模后就必然会和前面某个数重复。

    例如:a = 0.22 时, k = 1 和 k = 51结果是一样的,均为 0.2 ,那么自然就会发生重复了。

    之后我又进行更改,hash长度仍是 1000,但是插入数据也是1000个,即是全部插入,A 每次递增 0.001 结果发现在碰撞次数低的依旧很多

    当我将A每次递增改为0.000 001 ,我等了10多分钟都没跑完。。。。最后强行终止了,打开文件后发现这里面碰撞次数低的依旧还是很多,由此可见,A值的选取方式是很多的,取黄金分割比只是一个建议~

  • 相关阅读:
    让Web站点崩溃最常见的七大原因
    git常用命令
    VMware 虚拟网卡介绍和使用说明
    jQuery 发送 ajax 跨域请求,java 后端配置允许跨域
    svn 提交报错,提示:locked,需要 cleanup
    设置mysql允许外部连接访问
    Splunk和ElasticSearch深度对比解析(转)
    elastalert新增自定义警告推送
    nodejs(log4js)服务中应用splunk进行Log存储、搜索、分析、监控、警告
    elasticsearch License 到期后更新步骤
  • 原文地址:https://www.cnblogs.com/pangblog/p/3278403.html
Copyright © 2020-2023  润新知