1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7 using System.Web;
8
9 namespace ConsoleApplication2
10 {
11 class Program
12 {
13 static void Main(string[] args)
14 {
15 BloomFilter<string> bf = new BloomFilter<string>(20, 3);
16
17 bf.Add("testing");
18 bf.Add("nottesting");
19 bf.Add("testingagain");
20
21 Console.WriteLine(bf.Contains("badstring")); // False
22 Console.WriteLine(bf.Contains("testing")); // True
23
24 List<string> testItems = new List<string>() { "badstring", "testing", "test" };
25
26 Console.WriteLine(bf.ContainsAll(testItems)); // False
27 Console.WriteLine(bf.ContainsAny(testItems)); // True
28
29 //误检率: 0.040894188143892
30 Console.WriteLine("False Positive Probability: " + bf.FalsePositiveProbability());
31
32 Console.ReadKey();
33
34
35 }
36
37 /// <summary>
38 /// 一个布隆过滤器是一个空间有效的概率数据结构
39 /// 用于测试一个元素是否是一个集合的成员。误检率是可能的,但漏检率是不存在的。元素可以被添加到集合,但不能从集合删除。
40 /// </summary>
41 /// <typeparam name="Type">泛型数据类型</typeparam>
42 public class BloomFilter<T>
43 {
44 Random _random;
45 int _bitSize, _numberOfHashes, _setSize;
46 BitArray _bitArray;
47
48 #region Constructors
49 /// <summary>
50 /// 初始化bloom滤波器并设置hash散列的最佳数目
51 /// </summary>
52 /// <param name="bitSize">布隆过滤器的大小(m)</param>
53 /// <param name="setSize">集合的大小 (n)</param>
54 public BloomFilter(int bitSize, int setSize)
55 {
56 _bitSize = bitSize;
57 _bitArray = new BitArray(bitSize);
58 _setSize = setSize;
59 _numberOfHashes = OptimalNumberOfHashes(_bitSize, _setSize);
60 }
61
62 //<param name="numberOfHashes">hash散列函数的数量(k)</param>
63 public BloomFilter(int bitSize, int setSize, int numberOfHashes)
64 {
65 _bitSize = bitSize;
66 _bitArray = new BitArray(bitSize);
67 _setSize = setSize;
68 _numberOfHashes = numberOfHashes;
69 }
70 #endregion
71
72 #region 属性
73 public int NumberOfHashes
74 {
75 set
76 {
77 _numberOfHashes = value;
78 }
79 get
80 {
81 return _numberOfHashes;
82 }
83 }
84 public int SetSize
85 {
86 set
87 {
88 _setSize = value;
89 }
90 get
91 {
92 return _setSize;
93 }
94 }
95 public int BitSize
96 {
97 set
98 {
99 _bitSize = value;
100 }
101 get
102 {
103 return _bitSize;
104 }
105 }
106 #endregion
107
108 #region 公共方法
109 public void Add(T item)
110 {
111 _random = new Random(Hash(item));
112
113 for (int i = 0; i < _numberOfHashes; i++)
114 _bitArray[_random.Next(_bitSize)] = true;
115 }
116 public bool Contains(T item)
117 {
118 _random = new Random(Hash(item));
119
120 for (int i = 0; i < _numberOfHashes; i++)
121 {
122 if (!_bitArray[_random.Next(_bitSize)])
123 return false;
124 }
125 return true;
126 }
127
128 //检查列表中的任何项是否可能是在集合。
129 //如果布隆过滤器包含列表中的任何一项,返回真
130 public bool ContainsAny(List<T> items)
131 {
132 foreach (T item in items)
133 {
134 if (Contains(item))
135 return true;
136 }
137 return false;
138 }
139
140 //检查列表中的所有项目是否都在集合。
141 public bool ContainsAll(List<T> items)
142 {
143 foreach (T item in items)
144 {
145 if (!Contains(item))
146 return false;
147 }
148
149 return true;
150 }
151
152 /// <summary>
153 /// 计算遇到误检率的概率。
154 /// </summary>
155 /// <returns>Probability of a false positive</returns>
156 public double FalsePositiveProbability()
157 {
158 return Math.Pow((1 - Math.Exp(-_numberOfHashes * _setSize / (double)_bitSize)), _numberOfHashes);
159 }
160 #endregion
161
162 #region 私有方法
163 private int Hash(T item) {
164 return item.GetHashCode();
165 }
166
167 //计算基于布隆过滤器散列的最佳数量
168 private int OptimalNumberOfHashes(int bitSize, int setSize)
169 {
170 return (int)Math.Ceiling((bitSize / setSize) * Math.Log(2.0));
171 }
172 #endregion
173 }
174 }
175
176
177 }