程序编写用的是jupyter,在下面给的例子中,对于传统的算法和改进之后的做了对比。因为改变了桶结构,导致桶的数量减少,在遍历桶列表时,时间自然减少。
# 传统的DGIM算法的桶结构
# 精确统计,返回时间和统计的 1 的数目
def Count_bit_act():
bit_sum=0 # 统计1-bit个数
start_time = time.time()
with open('./物联网课程设计/01stream.txt', 'r') as f:
f.seek(0 if time_location<=window_size else 2*(time_location-window_size))#跳转到窗口大小之前行位置
for i in range(time_location if time_location<=window_size else window_size):
temp=f.readline()#读取值
if temp and temp=='1\n':
#if temp and int(temp.strip('\n'))==1:
bit_sum+=1
return bit_sum,time.time()-start_time
# 判断桶是否到期,如果到期则删除桶
def Is_due(time_now):
if bucket_list and time_now-window_size==bucket_list[0]['t']:#最左边的桶的时间戳等于当前时间减去窗口大小,到期了
del bucket_list[0]
# 桶合并,连续的桶是相似的
def Merge():
for i in range(len(bucket_list)-1,max_same_bucket-1,-1):
if bucket_list[i]['b']==bucket_list[i-max_same_bucket]['b']:
#存在n_max_bucket个大小相同的桶
bucket_list[i-max_same_bucket]['b']+=bucket_list[i-max_same_bucket+1]['b']
bucket_list[i-max_same_bucket]['t']=bucket_list[i-max_same_bucket+1]['t']
del bucket_list[i-max_same_bucket+1]
# 估计 1 的数量
def Count_bit():
bit_sum=0
flag_half=1 #
start_time=time.time()
with open('./物联网课程设计/01stream.txt', 'r') as f:
for i in range(time_location):
temp=f.readline()#读取文件的值
if temp:
Is_due(i+1)#判断是否有桶到期
if temp=='1\n':
#if int(temp.strip('\n'))==1:
bucket={"t":i+1,"b":1}#桶的结构
bucket_list.append(bucket)
Merge()#合并大小相同的桶
for i in range(len(bucket_list)):
#print(bucket_n[i])
bit_sum+=bucket_list[i]['b']
bit_sum-=bucket_list[0]['b']/2
return bit_sum if bucket_list else 0,time.time()-start_time
# 传统DGIM算法,相同 位置,相同 窗体大小,不同相似桶大小
bit_sum_list=[]
bit_time_list=[]
time_location=100000
window_size = 10000
max_same_bucket_list=[x for x in range(2,22)]
bit_act_sum,bit_act_time=Count_bit_act()
bucket_length_list_1=[]
for max_same_bucket in max_same_bucket_list:
bucket_list = []#桶的列表
bit_sum,bit_time=Count_bit()
bit_sum_list.append(bit_sum)
bit_time_list.append(bit_time)
print(max_same_bucket)
bucket_length_list_1.append(len(bucket_list))
for index in bucket_list:
print(index)
运算结果:
2 {'t': 90179, 'b': 1024} {'t': 93700, 'b': 1024} {'t': 95399, 'b': 512} {'t': 97210, 'b': 512} {'t': 98097, 'b': 256} {'t': 98996, 'b': 256} {'t': 99506, 'b': 128} {'t': 99723, 'b': 64} {'t': 99826, 'b': 32} {'t': 99889, 'b': 16} {'t': 99946, 'b': 16} {'t': 99966, 'b': 8} {'t': 99987, 'b': 4} {'t': 99990, 'b': 2} {'t': 99996, 'b': 2} {'t': 99997, 'b': 1} {'t': 99998, 'b': 1}
改进之后的桶结构
# 减少内存开销 ,bucket 这样定义 {b:number,t:[]}
def Count_bit_act():
bit_sum=0 # 统计1-bit个数
start_time = time.time()
with open('./物联网课程设计/01stream.txt', 'r') as f:
f.seek(0 if time_location<=window_size else 2*(time_location-window_size))#跳转到窗口大小之前行位置
for i in range(time_location if time_location<=window_size else window_size):
temp=f.readline()#读取值
if temp and temp=='1\n':
#if temp and int(temp.strip('\n'))==1:
bit_sum+=1
return bit_sum,time.time()-start_time
# 判断桶是否到期,如果到期则删除桶
def Is_due(time_now):
#print(bucket_list)
if bucket_list and time_now-window_size>=bucket_list[-1]['t'][0]:
del bucket_list[-1]["t"][0]
if bucket_list[-1]["t"]==[]:
del bucket_list[-1]
# 桶合并,连续的桶是相似的
def Merge():
for i in range(len(bucket_list)):
#print(len(bucket_list[i]['t'])==max_same_bucket+1)
if len(bucket_list[i]['t'])==max_same_bucket+1:
#存在n_max_bucket个大小相同的桶
if bucket_list[i] == bucket_list[-1]:
bucket_list.append({'b':bucket_list[i]['b']*2,'t':[bucket_list[i]['t'][1]]})
else:
bucket_list[i+1]['t'].append(bucket_list[i]['t'][1])
del bucket_list[i]['t'][0]
del bucket_list[i]['t'][1]
# 估计 1 的数量
def Count_bit():
bit_sum=0
flag_half=1 #
start_time=time.time()
with open('./物联网课程设计/01stream.txt', 'r') as f:
for i in range(time_location):
temp=f.readline()#读取文件的值
if temp:
Is_due(i+1)#判断是否有桶到期
if temp=='1\n':
#if int(temp.strip('\n'))==1:
if bucket_list:
bucket_list[0]["t"].append(i+1)
Merge()#合并大小相同的桶
else:
bucket_list.append({"b":1,"t":[i+1]})
for bucket in bucket_list:
#print(bucket_n[i])
bit_sum+=(bucket['b']*len(bucket["t"]))
bit_sum-=bucket_list[-1]['b']/2
return bit_sum if bucket_list else 0,time.time()-start_time
#下面将从两个维度去判断其准确率
# 改进DGIM算法,相同 位置,相同 窗体大小,不同相似桶大小
bit_sum_list=[]
bit_time_list=[]
time_location=100000
window_size = 10000
bucket_length_list_3=[]
max_same_bucket_list=[x for x in range(2,22)]
bit_act_sum,bit_act_time=Count_bit_act()
for max_same_bucket in max_same_bucket_list:
bucket_list = []#桶的列表
bit_sum,bit_time=Count_bit()
bit_sum_list.append(bit_sum)
bit_time_list.append(bit_time)
print(max_same_bucket)
bucket_length_list_3.append(len(bucket_list))
for index in bucket_list:
print(index)
部分运行结果:当最大相似桶个数为二时
2
{'b': 1, 't': [99996, 99998]}
{'b': 2, 't': [99987, 99996]}
{'b': 4, 't': [99966]}
{'b': 8, 't': [99946]}
{'b': 16, 't': [99826, 99946]}
{'b': 32, 't': [99723]}
{'b': 64, 't': [99506]}
{'b': 128, 't': [98996]}
{'b': 256, 't': [97210, 98996]}
{'b': 512, 't': [93700, 97210]}
{'b': 1024, 't': [90179, 93700]}
plt.figure(figsize=(12,4))
plt.plot(max_same_bucket_list, [bit_act_sum for i in range(20)],label="act",marker='*', linestyle='solid')
plt.plot(max_same_bucket_list, bit_sum_list,label="about",marker='.', linestyle='solid')
plt.xlabel("max_same_bucket")
plt.ylabel("count")
plt.legend()
plt.show()
# 准确与估计的结果随着最大相似桶数量的变化而变化
plt.figure(figsize=(12,4))
plt.plot(max_same_bucket_list, bit_time_list,label="about_time",marker='.', linestyle='solid')
plt.xlabel("max_same_bucket")
plt.ylabel("time/s")
plt.legend()
plt.show()
bit_time_list_3 = bit_time_list
#运行的时间,随着最大相似桶数目的变化
plt.figure(figsize=(12,4))
plt.plot(max_same_bucket_list, [abs((bit_act_sum-x)/bit_act_sum) for x in bit_sum_list ],label="abs((act-about)/act",marker='.', linestyle='solid')
plt.plot(max_same_bucket_list, [1/x for x in max_same_bucket_list],label="1/max_same_bucket",marker='.', linestyle='solid')
plt.xlabel("max_same_bucket")
plt.ylabel(" ")
plt.legend()
plt.show()
#误差值随着最大相似桶数量的变化
# 改进DGIM算法,相同 相似桶大小,相同 位置,不同窗体
bit_sum_list=[]
bit_time_list=[]
bit_act_sum_list=[]
time_location=200000
max_same_bucket = 2
bucket_length_list_4=[]
window_size_list = [x*1000 for x in range(1,21)]
for window_size in window_size_list:
bucket_list = []#桶的列表
bit_act_sum,bit_act_time=Count_bit_act()
bit_act_sum_list.append(bit_act_sum)
bit_sum,bit_time=Count_bit()
bit_sum_list.append(bit_sum)
bit_time_list.append(bit_time)
print(window_size)
bucket_length_list_4.append(len(bucket_list))
for index in bucket_list:
print(index)
部分运行结果:当窗体大小为1000时
1000
{'b': 1, 't': [199996]}
{'b': 2, 't': [199986, 199996]}
{'b': 4, 't': [199974]}
{'b': 8, 't': [199927, 199974]}
{'b': 16, 't': [199837, 199927]}
{'b': 32, 't': [199736]}
{'b': 64, 't': [199317, 199736]}
{'b': 128, 't': [199317]}
plt.figure(figsize=(12,4))
plt.plot(window_size_list, bit_act_sum_list,label="act",marker='*', linestyle='solid')
plt.plot(window_size_list, bit_sum_list,label="about",marker='.', linestyle='solid')
plt.xlabel("window_size")
plt.ylabel("count")
plt.legend()
plt.show()
#估计值与真实值随着窗口大小的变化
plt.figure(figsize=(12,4))
plt.plot(window_size_list, bit_time_list,label="about_time",marker='.', linestyle='solid')
plt.xlabel("window_size")
plt.ylabel("time/s")
plt.legend()
plt.show()
bit_time_list_4 = bit_time_list
#运算时间随着窗口大小的变化
plt.figure(figsize=(12,4))
plt.plot(window_size_list, [abs((y-x)/y) for x,y in zip(bit_sum_list,bit_act_sum_list)],label="abs((act-about)/act",marker='.', linestyle='solid')
plt.plot(window_size_list, [1/max_same_bucket for x in bit_sum_list],label="1/max_same_bucket",marker='.', linestyle='solid')
plt.xlabel("window_size")
plt.ylabel(" ")
plt.legend()
plt.show()
#误差值随着窗口大小的变化
#接下来比较传统与改进的部分参数,本例程代码不完全,对于传统的DGIM没给出分析,相应的结果没有写进去,如要尝试,请自行替换相应函数即刻。
plt.figure(figsize=(12,4))
plt.plot(max_same_bucket_list_1,bit_time_list_1 ,label="tradition",marker='.', linestyle='solid')
plt.plot(max_same_bucket_list_1,bit_time_list_3 ,label="improve",marker='.', linestyle='solid')
plt.xlabel("max_same_bucket")
plt.ylabel(" ")
plt.legend()
plt.show()
# 传统与改进的时间比较
plt.figure(figsize=(12,4))
plt.plot(window_size_list_1,bit_time_list_2 ,label="tradition",marker='.', linestyle='solid')
plt.plot(window_size_list_1,bit_time_list_4 ,label="improve",marker='.', linestyle='solid')
plt.xlabel("window_size")
plt.ylabel(" ")
plt.legend()
plt.show()
#传统与改进的时间比较
plt.figure(figsize=(12,4))
plt.plot(window_size_list_1,bucket_length_list_2 ,label="tradition",marker='.', linestyle='solid')
plt.plot(window_size_list_1,bucket_length_list_4 ,label="improve",marker='.', linestyle='solid')
plt.xlabel("window_size")
plt.ylabel(" ")
plt.legend()
plt.show()
#传统与改进的桶的数量比较
plt.figure(figsize=(12,4))
plt.plot(max_same_bucket_list_1,bucket_length_list_1 ,label="tradition",marker='.', linestyle='solid')
plt.plot(max_same_bucket_list_1,bucket_length_list_3 ,label="improve",marker='.', linestyle='solid')
plt.xlabel("max_same_bucket")
plt.ylabel(" ")
plt.legend()
plt.show()
#传统与改进的桶的数量比较,随着最大相似桶数量的变化