LoginSignup
2
3

More than 5 years have passed since last update.

Goでのアルゴリズムクイックリファレンス第2版(ブルームフィルタ)

Posted at

Goに慣れるためとアルゴリズムの復習の為に週1ぐらいで更新していきます。アルゴリズムクイックリファレンス 第2版を読んで各種アルゴリズムをGoで実装して行きます。

前回: Goでのアルゴリズムクイックリファレンス第2版(ハッシュに基づいた探索)

今回はブルームフィルタ

ブルームフィルタ(Bloom Filter)は、1970年に Burton H. Bloom が考案した空間効率の良い確率的データ構造であり、要素が集合のメンバーであるかどうかのテストに使われる。偽陽性(False Positive)による誤検出の可能性があるが、偽陰性(False Negative)はない。要素を集合に追加することができるが、削除することはできない(Counting filter を使えば削除できる)。集合に要素が追加されればされるほど、偽陽性の可能性が高くなる。

  • アルゴリズム
    • 全て 0 に設定された m ビットのビット配列
    • k 個のハッシュ関数が定義されており、それぞれがキー値を m 個の配列位置のいずれかにマッピング

package main

import "fmt"

const SIZE = 1999

func hashes(a *[]int) []int {
    xs := []int{0, 0, 0}
    for _, v := range *a {
        xs[0] = xs[0]*137 + v
        xs[1] = xs[1]*69 + v
        xs[2] = xs[2]*545 + v
    }

    hashes := make([]int, 3)
    for i, _ := range xs {
        hashes[i] = xs[i] % SIZE
    }

    return hashes
}

type BloomFilter struct {
    BitArray *[]int
}

func (bf *BloomFilter) add(a *[]int) {
    for _, v := range hashes(a) {
        (*bf.BitArray)[v] = 1
    }
}

func (bf *BloomFilter) query(a *[]int) bool {
    for _, v := range hashes(a) {
        if (*bf.BitArray)[v] == 0 {
            return false
        }
    }
    return true
}

func main() {
    ba := make([]int, 0)
    for i := 0; i < SIZE; i++ {
        ba = append(ba, 0)
    }
    bf := &BloomFilter{&ba}

    ary := []int{1, 2, 3}

    bf.add(&ary)

    if bf.query(&ary) {
        fmt.Println("ok")
    }

    ary2 := []int{1, 2, 3, 4}

    if !bf.query(&ary2) {
        fmt.Println("ng")
    }
}

西尾さんのblogにあった実装を参考にさせていただきました。

次回は二分探索木です。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3