实验要求:
使用自己所擅长的程序语言编写布隆过滤算法(近似判断一个查询数据是否属于集合S)。
实验步骤:
1:以stream_for_bm.txt文件的内容做为集合S的元素(元素为1-107)(共104个元素),构建一个比特数组将S的元素存储下来
2:读取stream_for_query.txt文件中的内容,对于每个数据判断其是否属于集合S;
3:精确算法,使用一个数组记录下S中的内容,然后对于每一个查询元素(stream_for_query.txt中的内容),判断其是否属于S;
4:设计并实现书上107页(第二版)的布隆过滤器,来近似查询每个元素是否属于S;
5:使用1000个比特,每个元素使用1个哈希函数,计算此时布隆过滤器的错误率(误是错误率);
6:使用5000个比特,每个元素使用4个哈希函数,计算此时布隆过滤器的错误率(误是错误率);
实验考察要求:
1:分析并讲解自己所编写程序;
2:分析第5步与第6步,误差有区别的原因;
bloom 过滤器的思想
算法:
- 首先需要k个hash函数,每个函数可以把key散列成为1个整数
- 初始化时,需要一个长度为n比特的数组,每个比特位初始化为0
- 某个key加入集合时,用k个hash函数计算出k个散列值,并把数组中对应的比特位置为1
- 判断某个key是否在集合时,用k个hash函数计算出k个散列值,并查询数组中对应的比特位,如果所有的比特位都是1,认为在集合中。
将文件存储到集合S保存
def get_set_s():
s=[]
with open("stream_for_bm.txt") as f:
while True:
temp = f.readline()
if temp=="":
break
temp = int(temp.strip())
s.append(temp)
return s
print(len(get_set_s()))
10000
精确判断一个数据在不在集合s当中
def judge_accurate(x):
s=get_set_s()
if x in s:
return True
else:
return False
用布隆过滤器进行判断
import random
def hash1(num1):
return num1 * random.randint(1,10) % 10000
def hash2(num1):
return num1 * random.randint(1,10) % 10000
def hash3(num1):
return num1 * random.randint(1,10) % 10000
def hash4(num1):
return num1 * random.randint(1,10) % 10000
#定义一个布隆过滤器
class Bloomclass:
def __init__(self):
self.n_bloom = [0 for j in range(10000)]
def bloom_update(self, elem):
hashnum1 = hash1(elem)
hashnum2 = hash2(elem)
hashnum3 = hash3(elem)
hashnum4 = hash4(elem)
self.n_bloom[hashnum1] = 1
self.n_bloom[hashnum2] = 1
self.n_bloom[hashnum3] = 1
self.n_bloom[hashnum4] = 1
def bloom_judge(self, elem):
t = self.n_bloom[hash1(elem)]
t += self.n_bloom[hash2(elem)]
t += self.n_bloom[hash3(elem)]
t += self.n_bloom[hash4(elem)]
if t == 4:
return True
return False
if __name__ == "__main__":
t = (int)(input("请输入时间大小t:"))
f = open('stream_for_query.txt')
count = 0
Bloomtest = Bloomclass()
s=get_set_s()
for i in s:
Bloomtest.bloom_update(i)
for j in range(t):
num = f.readline()
if num == '':
break
num = int(num.strip())
if Bloomtest.bloom_judge(num)==True and judge_accurate(num)==False:
count+=1
print("在{}个比特下,使用四个哈希函数,此时的误是错误率是{}%".format(t,count*100/t))
在5000个比特下,使用四个哈希函数,此时的误是错误率是41.34%
import random
def hash1(num1):
return num1 * random.randint(1,10) % 10000
#定义一个布隆过滤器
class Bloomclass:
def __init__(self):
self.n_bloom = [0 for j in range(10000)]
def bloom_update(self, elem):
hashnum1 = hash1(elem)
self.n_bloom[hashnum1] = 1
def bloom_judge(self, elem):
t = self.n_bloom[hash1(elem)]
if t==1:
return True
return False
if __name__ == "__main__":
t = (int)(input("请输入时间大小t:"))
f = open('stream_for_query.txt')
count = 0
Bloomtest = Bloomclass()
s=get_set_s()
for i in s:
Bloomtest.bloom_update(i)
for j in range(t):
num = f.readline()
if num == '':
break
num = int(num.strip())
if Bloomtest.bloom_judge(num)==True and judge_accurate(num)==False:
count+=1
print("在{}个比特下,使用一个哈希函数,此时的误是错误率是{}%".format(t,count*100/t))
在1000个比特下,使用一个哈希函数,此时的误是错误率是34.8%
import random
#定义一个布隆过滤器
class Bloomclass:
def __init__(self):
self.n_bloom = [0 for j in range(10000)]
def bloom_update(self, elem,k):
for i in range(k):
hashnum1 = elem * hash_parameter[i] % 10000
self.n_bloom[hashnum1] = 1
def bloom_judge(self, elem,k):
count =0
for i in range(k):
hashnum1 = elem * hash_parameter[i] % 10000
count+=self.n_bloom[hashnum1]
if count==k:
return True
return False
if __name__ == "__main__":
t = (int)(input("请输入时间大小t:"))
hash_mum = (int)(input("请输入哈希函数的个数:"))
hash_parameter =[]
for x in range(hash_mum):
hash_parameter.append(random.randint(1,10))
f = open('stream_for_query.txt')
count = 0
Bloomtest = Bloomclass()
s=get_set_s()
for i in s:
Bloomtest.bloom_update(i,hash_mum)
for j in range(t):
num = f.readline()
if num == '':
break
num = int(num.strip())
if Bloomtest.bloom_judge(num,hash_mum)==True and judge_accurate(num)==False:
count+=1
print("在{}个比特下,使用{}个哈希函数,此时的误是错误率是{}%".format(t,hash_mum,count*100/t))
在5000个比特下,使用4个哈希函数,此时的误是错误率是41.92%