-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFMSPS.py
More file actions
297 lines (261 loc) · 13.7 KB
/
FMSPS.py
File metadata and controls
297 lines (261 loc) · 13.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# -*- coding:utf-8 -*-
# Author:wzy
# Date : 2023-5-10
import math
import matplotlib.pyplot as plt
import numpy as np
import random
import xlwt
import pdb
#定义量子比特类
class qubit:
ED = 0 #纠缠距离
location1 = 0 #所属节点位置
location2 = 0 #所属另一个节点位置
index1 = 0 #列表位置 所属节点位置
index2 = 0 #列表位置 所属另一个节点位置
fidelity = 0 #保真度
def __init__(self):
pass
def clear_qubit(self):
self.ED = 0
self.fidelity = 0
self.location1 = 0
self.location2 = 0
self.index1 = 0
self.index2 = 0
#节点类
class node:
EDL = 0 #该节点应该发生的纠缠交换的左边跳数
EDR = 0 #该节点应该发生的纠缠交换的右边跳数
location = 0 # 节点位置
left_qubits = [] # 存储量子比特
right_qubits = [] # 存储量子比特
def __init__(self,location, memory_capcaity):
self.location = location+1
self.EDL = 0
self.EDR = 0
self.left_qubits = list(range(memory_capcaity))
self.right_qubits = list(range(memory_capcaity))
pass
#计算得到根据节点位置得到的左边纠缠交换的距离
def EDL_node(location):
for l in range(1,10):
for k in range(0,10):
if location == pow(2,l-1) + k*(pow(2,l))+1:
return pow(2,l-1)
#定义概率函数
def possible(p):
if(random.random() <= p):
return True
else:
return False
#确定路径各节点的ED,并返回列表信息
def path_ED(node_num:int):
ED_list = []
for i in range(2,node_num):
EDL = EDL_node(i)
EDR = min(node_num-i,EDL)
ED_list.append({i:(EDL,EDR)})
return ED_list
#路径上各节点的初始化,以及节点上存储空间的初始化
def init_path(node_num:int,capcaity:int):
path_list = list(range(node_num))
for i in range(0,node_num):
new_node = node(i,capcaity)
for j in range(capcaity):
new_qubit_1 = qubit()
new_node.left_qubits[j] = new_qubit_1
new_qubit_2 = qubit()
new_node.right_qubits[j] = new_qubit_2
del new_qubit_1,new_qubit_2
pass
path_list[i] = new_node
del new_node
ED_list = path_ED(node_num)
for i in range(1,node_num-1):
path_list[i].EDL = ED_list[i-1][i+1][0]
path_list[i].EDR = ED_list[i-1][i+1][1]
return path_list
#定义初始分发函数
def init_pair(path_list:list,node_num:int,init_num:int,capacity:int,fidelity_list:list,threshold:float):
for i in range(0, node_num-1):
num = 0
for j in range(capacity):
#保真度为0代表并未有真实的纠缠对占用该存储单元
if(path_list[i].right_qubits[j].fidelity == 0):
flag = 0 #找到一个就可以
for k in range(capacity):
if(path_list[i+1].left_qubits[k].fidelity == 0):
#左右两边都找到空闲的空间了
path_list[i].right_qubits[j].fidelity = fidelity_list[i]
path_list[i].right_qubits[j].location1 = i
path_list[i].right_qubits[j].location2 = i + 1
path_list[i].right_qubits[j].index1 = j
path_list[i].right_qubits[j].index2 = k
path_list[i].right_qubits[j].ED = 1
path_list[i+1].left_qubits[k].fidelity = fidelity_list[i]
path_list[i+1].left_qubits[k].location1 =i + 1
path_list[i+1].left_qubits[k].location2 =i
path_list[i+1].left_qubits[k].index1 = k
path_list[i+1].left_qubits[k].index2 = j
path_list[i+1].left_qubits[k].ED = 1
num += 1
flag = 1
if(flag == 1):
break
pass
pass
pass
if (num >= init_num):
break
def swap_one_round(node_num:int,path_list:list,threshold:float,capacity:int,P_swap:float):
for i in range(1, node_num-1):
EDL = path_list[i].EDL
EDR = path_list[i].EDR
for j in range(capacity):
if(path_list[i].left_qubits[j].fidelity > threshold and path_list[i].left_qubits[j].ED == EDL):
for k in range(capacity):
if(path_list[i].right_qubits[k].fidelity > threshold and path_list[i].right_qubits[k].ED == EDR):
left_loc = path_list[i].left_qubits[j].location2
right_loc = path_list[i].right_qubits[k].location2
left_index = path_list[i].left_qubits[j].index2
right_index = path_list[i].right_qubits[k].index2
lf = path_list[i].left_qubits[j].fidelity
rf = path_list[i].right_qubits[k].fidelity
new_fidelity = lf*rf
#纠缠交换成功
if possible(P_swap):
path_list[left_loc].right_qubits[left_index].fidelity = new_fidelity
path_list[left_loc].right_qubits[left_index].location2 = right_loc
path_list[left_loc].right_qubits[left_index].index2 = right_index
path_list[left_loc].right_qubits[left_index].ED = EDL+EDR
path_list[right_loc].left_qubits[right_index].fidelity = new_fidelity
path_list[right_loc].left_qubits[right_index].location2 = left_loc
path_list[right_loc].left_qubits[right_index].index2 = left_index
path_list[right_loc].left_qubits[right_index].ED = EDL+EDR
path_list[i].left_qubits[j].clear_qubit()
path_list[i].right_qubits[k].clear_qubit()
#纠缠交换失败
else:
path_list[i].left_qubits[j].clear_qubit()
path_list[i].right_qubits[k].clear_qubit()
path_list[left_loc].right_qubits[left_index].clear_qubit()
path_list[right_loc].left_qubits[right_index].clear_qubit()
break
return None
def pur_one_round(node_num:int,path_list:list,threshold:float,capacity:int,final_fidelity:float):
#中间节点做纯化
for i in range(1, node_num-1):
EDL = path_list[i].EDL
EDR = path_list[i].EDR
#纯化左边的纠缠对
for j in range(capacity):
if(path_list[i].left_qubits[j].fidelity <= threshold and path_list[i].left_qubits[j].ED == EDL and path_list[i].left_qubits[j].fidelity !=0):
#再找一个可用的纯化纠缠对
for k in range(j+1,capacity):
if(path_list[i].left_qubits[k].fidelity <= threshold and path_list[i].left_qubits[k].ED == EDL and path_list[i].left_qubits[k].fidelity !=0):
left_loc = path_list[i].left_qubits[j].location2
left_index_1 = path_list[i].left_qubits[j].index2
left_index_2 = path_list[i].left_qubits[k].index2
f1 = path_list[i].left_qubits[j].fidelity
f2 = path_list[i].left_qubits[k].fidelity
p_pur = f1*f2+(1-f1)*(1-f2)
new_fidelity = f1*f2/p_pur
#纠缠纯化成功
if possible(p_pur):
path_list[i].left_qubits[j].fidelity = new_fidelity
path_list[left_loc].right_qubits[left_index_1].fidelity = new_fidelity
path_list[i].left_qubits[k].clear_qubit()
path_list[left_loc].right_qubits[left_index_2].clear_qubit()
else:
path_list[i].left_qubits[j].clear_qubit()
path_list[left_loc].right_qubits[left_index_1].clear_qubit()
path_list[i].left_qubits[k].clear_qubit()
path_list[left_loc].right_qubits[left_index_2].clear_qubit()
break
#纯化右边的纠缠对
for j in range(capacity):
if(path_list[i].right_qubits[j].fidelity <= threshold and path_list[i].right_qubits[j].ED == EDR and path_list[i].right_qubits[j].fidelity !=0):
#再找一个可用的纯化纠缠对
for k in range(j+1,capacity):
if(path_list[i].right_qubits[k].fidelity <= threshold and path_list[i].right_qubits[k].ED == EDR and path_list[i].right_qubits[k].fidelity !=0):
right_loc = path_list[i].right_qubits[j].location2
right_index_1 = path_list[i].right_qubits[j].index2
right_index_2 = path_list[i].right_qubits[k].index2
f1 = path_list[i].right_qubits[j].fidelity
f2 = path_list[i].right_qubits[k].fidelity
p_pur = f1*f2+(1-f1)*(1-f2)
new_fidelity = f1*f2/p_pur
#纠缠纯化成功
if possible(p_pur):
path_list[i].right_qubits[j].fidelity = new_fidelity
path_list[right_loc].left_qubits[right_index_1].fidelity = new_fidelity
path_list[i].right_qubits[k].clear_qubit()
path_list[right_loc].left_qubits[right_index_2].clear_qubit()
else:
path_list[i].right_qubits[j].clear_qubit()
path_list[right_loc].left_qubits[right_index_1].clear_qubit()
path_list[i].right_qubits[k].clear_qubit()
path_list[right_loc].left_qubits[right_index_2].clear_qubit()
break
#端节点做纯化
for i in range(capacity):
if path_list[0].right_qubits[i].fidelity <= final_fidelity and path_list[0].right_qubits[i].ED == node_num-1 and path_list[0].right_qubits[i].fidelity !=0:
for j in range(i+1,capacity):
if path_list[0].right_qubits[j].fidelity <= final_fidelity and path_list[0].right_qubits[j].ED == node_num-1 and path_list[0].right_qubits[j].fidelity != 0:
right_index_1 = path_list[0].right_qubits[i].index2
right_index_2 = path_list[0].right_qubits[j].index2
f1 = path_list[0].right_qubits[i].fidelity
f2 = path_list[0].right_qubits[j].fidelity
p_pur = f1*f2+(1-f1)*(1-f2)
new_fidelity = f1*f2/p_pur
if possible(p_pur):
path_list[0].right_qubits[i].fidelity = new_fidelity
path_list[node_num-1].left_qubits[right_index_1].fidelity = new_fidelity
path_list[0].right_qubits[j].clear_qubit()
path_list[node_num-1].left_qubits[right_index_2].clear_qubit()
else:
path_list[0].right_qubits[i].clear_qubit()
path_list[node_num-1].left_qubits[right_index_1].clear_qubit()
path_list[0].right_qubits[j].clear_qubit()
path_list[node_num-1].left_qubits[right_index_2].clear_qubit()
break
return None
def check(path_list:list,final_fidelity:float,node_num:int,capacity:int):
available_pair_1 = 0
available_pair_2 = 0
for i in range(capacity):
if path_list[0].right_qubits[i].ED == node_num-1 and path_list[0].right_qubits[i].fidelity > final_fidelity:
available_pair_1 += 1
path_list[0].right_qubits[i].clear_qubit()
for i in range(capacity):
if path_list[node_num-1].left_qubits[i].ED == node_num-1 and path_list[node_num-1].left_qubits[i].fidelity > final_fidelity:
available_pair_2 += 1
path_list[node_num-1].left_qubits[i].clear_qubit()
return available_pair_1,available_pair_2
def A_slot(path_list:list,node_num:int,fidelity_list:list,P_swap:float,init_num:int,threshold:float,final_fidelity:float):
ETE_pair1,ETE_pair2 = check(path_list,final_fidelity,node_num,capacity)
init_pair(path_list,node_num,init_num,capacity,fidelity_list,threshold)
pur_one_round(node_num,path_list,threshold,capacity,final_fidelity)
swap_one_round(node_num,path_list,threshold,capacity,P_swap)
return ETE_pair1,ETE_pair2
if __name__ == '__main__':
init_num = 10
capacity = 150
threshold = 0.72
p_swap = 0.9
slot_num = 200
final_fidelity = 0.85
round = 10
init_fidelity = 0.9
for node_num in range(5,20):
total_ETE_pair = 0
fidelity_list = (node_num-1)*[init_fidelity]
for k in range(round):
path_list = init_path(node_num,capacity)
for i in range(slot_num):
ETE_pair1,ETE_pair2 = A_slot(path_list,node_num,fidelity_list,p_swap,init_num,threshold,final_fidelity)
total_ETE_pair += ETE_pair1
# print(ETE_pair1,ETE_pair2)
print(total_ETE_pair/round)