-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
171 lines (136 loc) · 6.62 KB
/
main.py
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
# -*- coding: utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt
import NetworkModel
import RandomGraph
import LatencyCount
import DynamicProgram
import MigrationPathStatus
import json
import numpy as np
import pickle
if __name__ == '__main__':
# 对比实验,设置标志以控制操作
new_user = False # 如果需要重新生成随机用户数据则设为 True,否则设为 False
backup_count = 5 # vnf备份数量
case = 6 # 使用的算法
new_G = False # 新生成边缘网络图
p = 0.9 # 图的连通率
num_nodes = 20 # 图的节点数
"""
case = 1:# 随机算法 :效果远差于其余算法,不用
case = 2:# 动态规划,KM算法 :追求成本最小 基准方案3
case = 3:# 机器学习算法 :后续想法
case = 4:# 重部署算法 :基准方案2
case = 5:# 动态规划,KM算法 :在尽可能满足时延的情况下追求成本最小 基准方案1
case = 6:# 结合基准方案2和3,所设计的方案。需要先运行case 2和4,以及array_compare
"""
if new_G:
G = RandomGraph.NewRandomGraph(num_nodes, p) # 随机生成图
# 可选:进行图处理
G = NetworkModel.dijkstra(G)
nx.write_graphml(G, "my_graph_50.graphml") # 保存图到文件
else:
G = nx.read_graphml("my_graph_50.graphml", node_type=int) # 读取图
# 对图的操作
# NetworkModel.ShowGraph(G)
# print(G.get_edge_data(4, 8)['weight'])
# print(G.get_edge_data(4, 3)['weight'])
# 随机实例化一组用户请求
if new_user:
# 随机生成并保存用户请求
R = NetworkModel.generate_user_requests(G, 1000,backup_count) # 生成用户请求
with open('user_request_1000.pkl', 'wb') as f:
pickle.dump(R, f)
else:
with open('user_request_1000.pkl', 'rb') as f:
R = pickle.load(f) # 加载用户请求
with open('result_compare.json', 'r') as f:
result_compare = json.load(f)
sumMigCost_all = 0 # 所有请求迁移后的迁移成本总和
aflBackupMig_all = 0 # 所有vnf备份迁移后的平均故障恢复时延
satisfied_num = 0 # 备份迁移后,能满足用户时延需求的请求的个数
comparison = []
result_compare_i = -1 # 用于case = 6时的混合方案
for r in R:
result_compare_i += 1
# print("\n")
# 已知主VNF部署在vnf_loc,备份部署位置保存在列表 bvnf_loc中
vnf_loc = r.F[0]
bvnf_loc = r.F[1:]
# 迁移前的平均时延:
afl_pre = LatencyCount.get_average_failure_latency(G, r, vnf_loc)
# print("迁移前的afl:", afl_pre, "用户能接受的afl:", r.T_err)
# 求用户迁移后(备份迁移前)的平均故障时延afl
afl = LatencyCount.get_average_failure_latency(G, r, r.Vnf_mig)
# print("迁移后的afl:", afl, "用户能接受的afl:", r.T_err)
# 如果迁移后的平均故障时延afl比用户所能容忍的高,则需要迁移
sumMigCost_r = 0 # 单个请求迁移后的迁移成本总和
timeMigCost_r = 0 # 单个用户请求迁移后,vnf备份的迁移花费的时长(和迁移路径的长度正相关)
aflMigTime_decrease = 0
if afl > r.T_err:
if case == 6:
# print("result_compare_i=",result_compare_i)
if result_compare[result_compare_i] == 1:
s = MigrationPathStatus.migration_status(G, r, r.Vnf_mig, case=2)
else:
s = MigrationPathStatus.migration_status(G, r, r.Vnf_mig, case=4)
else:
# 确定出状态$s_i=(u_i,v_i)$
s = MigrationPathStatus.migration_status(G, r, r.Vnf_mig, case=case)
# 计算出该选择哪些状态来使收益最大化
if case == 4:
s_chose = s
elif case == 6:
if result_compare[result_compare_i] == 1:
s_chose, aflMigTime_decrease = DynamicProgram.chose_status(G, s, r, afl)
else:
s_chose = s
else:
s_chose, aflMigTime_decrease = DynamicProgram.chose_status(G, s, r, afl)
for i in s_chose:
# print("从点", i.NodeName_pre, "迁移到点", i.NodeName_after, "降低了", i.MigTime_decrease, "的延迟", "优先度为:",
# i.priority,"成本为:", i.MigCost) 同步迁移,取最大迁移耗时
timeMigCost_r_tmp = G.get_edge_data(i.NodeName_pre, i.NodeName_after)['weight']
if timeMigCost_r_tmp >= timeMigCost_r:
timeMigCost_r = timeMigCost_r_tmp
sumMigCost_r += i.MigCost # 求和单个请求总迁移成本
if case == 4:
sum_afl = 0
for i in s_chose:
sum_afl += (-i.MigTime_decrease)
aflBackupMig_r = sum_afl / (len(s_chose))
elif case == 6:
if result_compare[result_compare_i] == 1:
aflBackupMig_r = afl - aflMigTime_decrease # vnf备份迁移后的平均故障恢复时延
else:
sum_afl = 0
for i in s_chose:
sum_afl += (-i.MigTime_decrease)
aflBackupMig_r = sum_afl / (len(s_chose))
else:
aflBackupMig_r = afl - aflMigTime_decrease # vnf备份迁移后的平均故障恢复时延
#print("迁移花费时长:", timeMigCost_r)
#print("vnf备份迁移后的平均故障恢复时延:", aflBackupMig_r)
if aflBackupMig_r <= r.T_err:
comparison.append(sumMigCost_r)
else:
# 不需要迁移则成本为0
comparison.append(0)
# 添加一个统计满足率(有多少请求满足用户时延需求)
if aflBackupMig_r <= r.T_err:
satisfied_num += 1
#print("该请求迁移成本为:", sumMigCost_r)
aflBackupMig_all += aflBackupMig_r
else:
comparison.append(0)
sumMigCost_all += sumMigCost_r
# 把每个用户请求的具体迁移成本记录到文件中,用于比较不同的算法下的成本差距
save_name = "array_" + str(case) + ".json"
# 保存到文件
with open(save_name, 'w') as f:
json.dump(comparison, f)
print("\n")
print("总平均故障恢复时延:", aflBackupMig_all / len(R))
print("总请求迁移成本为:", sumMigCost_all)
print("满足率为:", 100 * satisfied_num / len(R), "%")