BloomFilter(布隆過濾器)的C#實現
阿新 • • 發佈:2019-02-12
BloomFilterTest的程式碼如下:
BloomFilter類如下:static void Main() { BloomFilter<string> bf = new BloomFilter<string>(20, 3); bf.Add("testing"); bf.Add("nottesting"); bf.Add("testingagain"); Console.WriteLine(bf.Contains("badstring")); // False Console.WriteLine(bf.Contains("testing")); // True List<string> testItems = new List<string>() { "badstring", "testing", "test" }; Console.WriteLine(bf.ContainsAll(testItems)); // False Console.WriteLine(bf.ContainsAny(testItems)); // True //誤檢率: 0.040894188143892 Console.WriteLine("False Positive Probability: " + bf.FalsePositiveProbability()); Console.ReadKey(); }
結果如圖:/// <summary> /// 一個布隆過濾器是一個空間有效的概率資料結構 /// 用於測試一個元素是否是一個集合的成員。誤檢率是可能的,但漏檢率是不存在的。元素可以被新增到集合,但不能從集合刪除。 /// </summary> /// <typeparam name="Type">泛型資料型別</typeparam> public class BloomFilter<T> { Random _random; int _bitSize, _numberOfHashes, _setSize; BitArray _bitArray; #region Constructors /// <summary> /// 初始化bloom濾波器並設定hash雜湊的最佳數目 /// </summary> /// <param name="bitSize">布隆過濾器的大小(m)</param> /// <param name="setSize">集合的大小 (n)</param> public BloomFilter(int bitSize, int setSize) { _bitSize = bitSize; _bitArray = new BitArray(bitSize); _setSize = setSize; _numberOfHashes = OptimalNumberOfHashes(_bitSize, _setSize); } //<param name="numberOfHashes">hash雜湊函式的數量(k)</param> public BloomFilter(int bitSize, int setSize, int numberOfHashes) { _bitSize = bitSize; _bitArray = new BitArray(bitSize); _setSize = setSize; _numberOfHashes = numberOfHashes; } #endregion #region 屬性 public int NumberOfHashes { set { _numberOfHashes = value; } get { return _numberOfHashes; } } public int SetSize { set { _setSize = value; } get { return _setSize; } } public int BitSize { set { _bitSize = value; } get { return _bitSize; } } #endregion #region 公共方法 public void Add(T item) { _random = new Random(Hash(item)); for (int i = 0; i < _numberOfHashes; i++) _bitArray[_random.Next(_bitSize)] = true; } public bool Contains(T item) { _random = new Random(Hash(item)); for (int i = 0; i < _numberOfHashes; i++) { if (!_bitArray[_random.Next(_bitSize)]) return false; } return true; } //檢查列表中的任何項是否可能是在集合。 //如果布隆過濾器包含列表中的任何一項,返回真 public bool ContainsAny(List<T> items) { foreach (T item in items) { if (Contains(item)) return true; } return false; } //檢查列表中的所有專案是否都在集合。 public bool ContainsAll(List<T> items) { foreach (T item in items) { if (!Contains(item)) return false; } return true; } /// <summary> /// 計算遇到誤檢率的概率。 /// </summary> /// <returns>Probability of a false positive</returns> public double FalsePositiveProbability() { return Math.Pow((1 - Math.Exp(-_numberOfHashes * _setSize / (double)_bitSize)), _numberOfHashes); } #endregion #region 私有方法 private int Hash(T item) { return item.GetHashCode(); } //計算基於布隆過濾器雜湊的最佳數量 private int OptimalNumberOfHashes(int bitSize, int setSize) { return (int)Math.Ceiling((bitSize / setSize) * Math.Log(2.0)); } #endregion }