改进DGIM,减少内存开销(Python)

程序编写用的是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()

#传统与改进的桶的数量比较,随着最大相似桶数量的变化

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖人称王某人的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值