首页

▼ 算法合集

▼ 加密算法

▼ 凯撒密码

凯撒密码

▼ Hill密码算法

Hill密码算法

▼ 多项式哈希算法

多项式哈希算法

▼ Rail Fence Cipher

Rail Fence Cipher

▼ Graph算法

▼ 关节点

关节点

▼ Bellman-Ford算法

Bellman-Ford算法

▼ 广度优先搜索

广度优先搜索

▼ GraphBridges

桥接模式

▼ 深度优先搜索

深度优先搜索

▼ 检测循环

检测循环

▼ Dijkstra算法

Dijkstra算法

▼ Eulerian Path

欧拉路径

▼ Floyd-Warshall算法

Floyd-Warshall算法

▼ HamiltonianCycle

Hamiltonian Cycle

▼ Kruskal算法

Kruskal算法

▼ Prim算法

Prim算法

▼ 强连通分量

强连通分量

▼ 拓扑排序

拓扑排序

▼ Travelling Salesman Problem

Travelling Salesman

▼ 图像处理算法

▼ Seam Carving算法

内容感知缩放算法

▼ 链表

▼ 反向遍历

反向遍历

▼ GraphTraversal

GraphTraversal

▼ 数学算法

▼ 二进制浮点数

BinaryFloatingPoint

▼ 位操作

位操作算法

▼ 复数

复数

▼ 欧几里得算法

Euclidean Algorithm

▼ Euclidean Distance

欧几里得距离

▼ 阶乘算法

阶乘算法

▼ 快速幂算法

快速幂算法

▼ Fibonacci数列

斐波那契数列

▼ 傅里叶变换

Fourier变换

▼ Horner法

霍纳法则

▼ 整数划分

整数划分

▼ 判断是否为2的幂

判断是否为2的幂

▼ 最小公倍数

最小公倍数

▼ Liu Hui

Liu Hui

▼ 矩阵

Matrix

▼ Pascal三角形

Pascal三角形

▼ Primality Test

素数测试

▼ 质因数

质因数

▼ 弧度计算

弧度计算

▼ 埃拉托色尼筛法

埃拉托色尼筛法

▼ SquareRoot

SquareRoot

▼ MachineLearning

▼ K均值算法

K均值算法

▼ K近邻算法

K近邻算法

▼ 搜索算法

▼ 二分查找算法

二分查找

▼ 插值搜索算法

插值搜索算法

▼ 跳跃搜索算法

跳跃搜索算法

▼ 线性搜索

线性搜索算法

▼ 集合

▼ 笛卡尔积

笛卡尔积

▼ 组合总和

组合总和

▼ 组合算法

组合算法

▼ Fisher-Yates洗牌算法

Fisher-Yates洗牌算法

▼ 背包问题

背包问题

▼ 最长公共子序列

最长公共子序列

▼ 最长递增子序列

最长递增子序列

▼ 最大子数组

最大子数组

▼ 排列组合

排列组合

▼ 幂集

幂集算法

▼ 最短公共超序列

最短公共超序列

▼ Sorting Algorithms

▼ 冒泡排序

冒泡排序

▼ 桶排序算法

桶排序算法

▼ 计数排序算法

计数排序

▼ 堆排序算法

堆排序

▼ 插入排序

插入排序

▼ 归并排序

归并排序

▼ 快速排序算法

快速排序算法

▼ 基数排序

基数排序

▼ 选择排序算法

选择排序算法

▼ 希尔排序

希尔排序

▼ 统计学

▼ 加权随机

加权随机算法

▼ 字符串算法

▼ Hamming距离

Hamming距离

▼ KnuthMorrisPratt算法

Knuth-Morris-Pratt算法

▼ LevenshteinDistance

Levenshtein距离

▼ 最长公共子串

最长公共子串

▼ 回文检测算法

回文检测算法

▼ Rabin-Karp算法

Rabin-Karp算法

▼ 正则表达式匹配

正则表达式匹配

▼ Z算法

Z算法

▼ Tree Data Structure

▼ 广度优先搜索

广度优先搜索

▼ 深度优先搜索

深度优先搜索

▼ 未分类

▼ 最佳买卖股票时机

最佳买卖股票时机

▼ 汉诺塔算法

HanoiTower

▼ 跳跃游戏算法

跳跃游戏

▼ KnightTour

骑士巡逻

▼ N皇后问题

N皇后问题

▼ 雨水收集

雨水收集

▼ 递归楼梯问题

递归楼梯问题

▼ 方阵旋转

方阵旋转

▼ 独特路径

UniquePaths

▼ 数据结构

▼ BloomFilter算法

布隆过滤器

▼ 不相交集数据结构

Disjoint Set

▼ 双向链表

双向链表

▼ Graph

Graph算法

▼ 哈希表

哈希表

▼ Heap数据结构

Heap数据结构

▼ 链表

链表

▼ LRU缓存

LRU缓存

▼ 优先队列

优先队列

▼ 队列

队列

▼ 栈结构

栈结构

▼ Tree Data Structure

树结构

▼ AVL树

AVL树

▼ 二叉搜索树

二叉搜索树

▼ Fenwick树

Fenwick树

▼ 红黑树

红黑树

▼ 线段树

SegmentTree

▼ Trie数据结构

Trie数据结构

Filtro Bloom (Bloom Filter)

O bloom filter é uma estrutura de dados probabilística espaço-eficiente designada para testar se um elemento está ou não presente em um conjunto de dados. Foi projetado para ser incrivelmente rápida e utilizar o mínimo de memória ao potencial custo de um falso-positivo. Correspondências falsas positivas são possíveis, contudo falsos negativos não são - em outras palavras, a consulta retorna "possivelmente no conjunto" ou "definitivamente não no conjunto".

Bloom propôs a técnica para aplicações onde a quantidade de entrada de dados exigiria uma alocação de memória impraticavelmente grande se as "convencionais" técnicas error-free hashing fossem aplicadas.

Descrição do algoritmo

Um filtro Bloom vazio é um bit array de m bits, todos definidos como 0. Também deverá haver diferentes funções de hash k definidas, cada um dos quais mapeia e produz hash para um dos elementos definidos em uma das posições m da array, gerando uma distribuição aleatória e uniforme. Normalmente, k é uma constante, muito menor do que m, pelo qual é proporcional ao número de elements a ser adicionado; a escolha precisa de k e a constante de proporcionalidade de m são determinadas pela taxa de falsos positivos planejado do filtro.

Aqui está um exemplo de um filtro Bloom, representando o conjunto {x, y, z}. As flechas coloridas demonstram as posições no bit array em que cada elemento é mapeado. O elemento w não está definido dentro de {x, y, z}, porque este produz hash para uma posição de array de bits contendo 0. Para esta imagem: m = 18 e k = 3.

Bloom Filter

Operações

Existem duas operações principais que o filtro Bloom pode operar: inserção e pesquisa. A pesquisa pode resultar em falsos positivos. Remoção não é possível.

Em outras palavras, o filtro pode receber itens. Quando vamos verificar se um item já foi anteriormente inserido, ele poderá nos dizer "não" ou "talvez".

Ambas as inserções e pesquisas são operações O(1).

Criando o filtro

Um filtro Bloom é criado ao alocar um certo tamanho. No nosso exemplo, nós utilizamos 100 como tamanho padrão. Todas as posições são initializadas como false.

Inserção

Durante a inserção, um número de função hash, no nosso caso 3 funções de hash, são utilizadas para criar hashes de uma entrada. Estas funções de hash emitem saída de índices. A cada índice recebido, nós simplismente trocamos o valor de nosso filtro Bloom para true.

Pesquisa

Durante a pesquisa, a mesma função de hash é chamada e usada para emitir hash da entrada. Depois nós checamos se todos os indices recebidos possuem o valor true dentro de nosso filtro Bloom. Caso todos possuam o valor true, nós sabemos que o filtro Bloom pode ter tido o valor inserido anteriormente.

Contudo, isto não é certeza, porque é possível que outros valores anteriormente inseridos trocaram o valor para true. Os valores não são necessariamente true devido ao ítem atualmente sendo pesquisado. A certeza absoluta é impossível, a não ser que apenas um item foi inserido anteriormente.

Durante a checagem do filtro Bloom para índices retornados pela nossa função de hash, mesmo que apenas um deles possua valor como false, nós definitivamente sabemos que o ítem não foi anteriormente inserido.

Falso Positivos

A probabilidade de falso positivos é determinado por três fatores: o tamanho do filtro de Bloom, o número de funções de hash que utilizados, e o número de itens que foram inseridos dentro do filtro.

A formula para calcular a probabilidade de um falso positivo é:

( 1 - e -kn/m ) k

k = número de funções de hash

m = tamanho do filtro

n = número de itens inserido

Estas variáveis, k, m e n, devem ser escolhidas baseado em quanto aceitável são os falsos positivos. Se os valores escolhidos resultam em uma probabilidade muito alta, então os valores devem ser ajustados e a probabilidade recalculada.

Aplicações

Um filtro Bloom pode ser utilizado em uma página de Blog. Se o objetivo é mostrar aos leitores somente os artigos em que eles nunca viram, então o filtro Bloom é perfeito para isso. Ele pode armazenar hashes baseados nos artigos. Depois que um usuário lê alguns artigos, eles podem ser inseridos dentro do filtro. Na próxima vez que o usuário visitar o Blog, aqueles artigos poderão ser filtrados (eliminados) do resultado.

Alguns artigos serão inevitavelmente filtrados (eliminados) por engano, mas o custo é aceitável. Tudo bem se um usuário nunca ver alguns poucos artigos, desde que tenham outros novos para ver toda vez que eles visitam o site.

Referências