def test_coverage(self,sourcelist,h,infectG,singleregionList): print('查看真实源点的覆盖率以及真实h,看看我们的算法是不是那么智能。找到好的覆盖率') mins= 10 h = 0 for h_temp in range(2,11,1): sim=commons.getSimilir1(sourcelist,h_temp,singleregionList,infectG) if sim< mins: mins =sim h =h_temp print('最好的覆盖率以及h',str(sim)+' '+str(h))
def cal_BFS_monte_Carlo(self): tempGraph = nx.Graph() tempGraph = self.tempGraph print('这个传播子图的节点个数,也是我们用来做u的备选集合的' + str(len(set(tempGraph.nodes)))) print('这个感染区域的传播图节点个数') dfs_result_dict = commons.test_BFS_node( tempGraph, source_node=self.singe_source_result) sort_dfs_result_dict = sorted(dfs_result_dict.items(), key=lambda x: x[0]) print('sort_dfs_result_dict', sort_dfs_result_dict) ''' 这里我们只知道中心点的BFS点,还不能确定H。我们可以以传播子图的半径为最大h。进行 ''' singleRegionList = self.singleRegionList #计算半径。 # radius_graph= nx.radius(tempGraph) # radius_graph = 40 tempGraph = self.infectG #采用不同的感染图 radius_graph = self.radius print('图半径为', radius_graph) best_h = 0 best_h_node = [] min_cover = 100 # 某一层的覆盖率,肯定会比这个小。 for h in range(radius_graph // 2, radius_graph, 1): for k, node_list in sort_dfs_result_dict: print('how to that') # print(eccentric, node_list) # M_dis = max_eccentric - eccentric # 最好的bFS树半径。 # 随机挑选k个点固定次数。 temp_all_cover = 0 temp_cover = 0 temp_ave_cover = 0 if len(node_list ) > self.fix_number_source * 2: # 这一层只有大于3个点才可以。 if len(node_list) > 20: itemNumber = int(len(node_list) / 10) # 层数越大,节点越多,应该采样越多才能逼近近似值。 else: itemNumber = 2 #这是树的情况,每一层节点太少了 for frequency in range( itemNumber ): # 抽取10次,这里有问题,有些层数目多,怎么抽取会好点?按照层数抽取相应的次数会比较好点,公平。 slice = random.sample(node_list, self.fix_number_source) temp_cover = commons.getSimilir1( slice, h, singleRegionList, tempGraph) temp_all_cover += temp_cover if temp_all_cover != 0: temp_ave_cover = temp_all_cover / itemNumber # 求出平均覆盖率。 print('temp_ave_cover', temp_ave_cover) else: temp_ave_cover = 0.1 if temp_ave_cover <= min_cover: # 这一层表现优异,记下h,以及这一层的所有节点。 print('每次平均的覆盖率是' + str(min_cover)) print('temp_ave_cover', temp_ave_cover) min_cover = temp_ave_cover best_h_node = node_list best_h = h print('输出表现优异同学,看看' + str(best_h_node), str(best_h)) # 得到最优层数解,再大量进行选择,使用jaya算法。构建大量样本。在固定h下的寻找最合适的节点。 ''' 1 构建种群样本下 2 在固定h下更新 ''' self.single_best_result = commons.jaya(tempGraph, best_h_node, self.fix_number_source, best_h, singleRegionList)
def cal_BFS_monte_Carlo(self): tempGraph = nx.Graph() tempGraph = self.tempGraph print('这个传播子图的节点个数,也是我们用来做u的备选集合的' + str(len(set(tempGraph.nodes)))) print('这个感染区域的传播图节点个数') dfs_result_dict = self.test_BFS_node( tempGraph, source_node=self.singe_source_result) sort_dfs_result_dict = sorted(dfs_result_dict.items(), key=lambda x: x[0]) print('sort_dfs_result_dict', sort_dfs_result_dict) ''' 这里我们只知道中心点的BFS点,还不能确定H。我们可以以传播子图的半径为最大h。进行 ''' singleRegionList = self.singleRegionList #计算半径。 # radius_graph= nx.radius(tempGraph) # radius_graph = 40 tempGraph = self.infectG #采用不同的感染图 radius_graph = self.radius print('图半径为', radius_graph) best_h = 0 best_h_node = [] min_cover = 100 # 某一层的覆盖率,肯定会比这个小。 for h in range(radius_graph // 2, radius_graph, 1): for k, node_list in sort_dfs_result_dict: print('how to that') # print(eccentric, node_list) # M_dis = max_eccentric - eccentric # 最好的bFS树半径。 # 随机挑选k个点固定次数。 temp_all_cover = 0 temp_cover = 0 temp_ave_cover = 0 if len(node_list ) > self.fix_number_source * 2: # 这一层只有大于3个点才可以。 if len(node_list) > 20: itemNumber = int(len(node_list) / 2) # 层数越大,节点越多,应该采样越多才能逼近近似值。 else: itemNumber = 2 #这是树的情况,每一层节点太少了 for frequency in range( itemNumber ): # 抽取10次,这里有问题,有些层数目多,怎么抽取会好点?按照层数抽取相应的次数会比较好点,公平。 slice = random.sample(node_list, self.fix_number_source) temp_cover = commons.getSimilir1( slice, h, singleRegionList, tempGraph) temp_all_cover += temp_cover if temp_all_cover != 0: temp_ave_cover = temp_all_cover / itemNumber # 求出平均覆盖率。 print('temp_ave_cover', temp_ave_cover) else: temp_ave_cover = 0.1 if temp_ave_cover <= min_cover: # 这一层表现优异,记下h,以及这一层的所有节点。 print('每次平均的覆盖率是' + str(min_cover)) print('temp_ave_cover', temp_ave_cover) min_cover = temp_ave_cover best_h_node = node_list best_h = h print('输出表现优异同学,看看' + str(best_h_node), str(best_h)) # 得到最优层数解,再大量进行选择,使用jaya算法。构建大量样本。在固定h下的寻找最合适的节点。 ''' 1 构建种群样本下 2 在固定h下更新 ''' fix_number_sourcetemp = self.fix_number_source Sampleset = [] for i in range(50): Sampleset.append(random.sample(best_h_node, self.fix_number_source)) infectG = self.infectG min_cover = 1 min = 1 mincover = None bestsourceNews = None minCoverlist = [] for iter_number in range(5): for sample_index in range(len(Sampleset)): mincover = commons.getSimilir1(Sampleset[sample_index], best_h, singleRegionList, tempGraph) # 随机更换,看如何让变好 for j in range(1, 4, 1): # 随机变4次,只要能变好 # lateelement = [random.choice(best_h_node), random.choice(best_h_node), # random.choice(best_h_node)] # lateelement = [ random.choice(best_h_node) for i in range(self.fix_number_source) ] # print('当前输入的后面list' + str(lateelement)) latemincover = commons.getSimilir1(lateelement, best_h, singleRegionList, tempGraph) if mincover > latemincover: mincover = latemincover # 有更好地就要替换 # print("要进行替换了" + str(Sampleset[sample_index]) + '被替换成lateelement') Sampleset[sample_index] = lateelement # 替换 # print(Sampleset[sample_index]) # print('经过5次迭代之后的sample的list为多少呢?' + str(Sampleset)) # 计算样本集的similir,找出最好的。 for sources in Sampleset: mincover = commons.getSimilir1(sources, best_h, singleRegionList, tempGraph) if mincover < min: min = mincover # 这一次最好的覆盖误差率 bestsourceNews = sources # 最好的覆盖误差率对应的最好的那个解。 print('得到多源点情况最小的覆盖率为' + str(min)) minCoverlist.append([bestsourceNews, best_h, min]) print(minCoverlist) result = sorted(minCoverlist, key=lambda x: (x[2])) self.single_best_result = result[0]
def cal_ecctity(self): # 构建传播子图, singleRegionList = [] for node_index in list(self.infectG.nodes()): if self.infectG.node[node_index]['SI'] == 2: singleRegionList.append(node_index) tempGraph = nx.Graph() tempGraphNodelist = [] for edge in self.infectG.edges: # if infectG.adj[edge[0]][edge[1]]['Infection']==2: #作为保留项。 if edge[0] in singleRegionList and edge[1] in singleRegionList: tempGraph.add_edges_from([edge], weight=1) tempGraphNodelist.append(edge[0]) tempGraphNodelist.append(edge[1]) self.tempGraph = tempGraph # 临时图生成 print('这个传播子图的节点个数,也是我们用来做u的备选集合的' + str(len(set(tempGraphNodelist)))) print('这个感染区域的传播图节点个数') eccentricity_dict = nx.eccentricity(tempGraph) # print(list(eccentricity_dict.items())) # eccentricity_list= sorted(list(eccentricity_dict.items()), key= lambda x:x[1]) # print(eccentricity_list) eccentri_dict = defaultdict(list) for node_id, eccentric in eccentricity_dict.items(): eccentri_dict[eccentric].append(node_id) print(eccentri_dict) # 从偏心率大的考虑,先保存最大偏心度。 sort_eccentricity_dict = sorted(eccentri_dict.items(), key=lambda x: x[0], reverse=True) max_eccentric = sort_eccentricity_dict[0][0] print('输出最大的就是那个偏心率' + str(max_eccentric)) from random import sample best_h = 0 M_dis = 0 best_h_node = [] min_cover = 100 # 某一层的覆盖率,肯定会比这个小。 tempGraph = self.infectG # 采用不同的感染图 for eccentric, node_list in sort_eccentricity_dict: print('how to that') print(eccentric, node_list) M_dis = max_eccentric - eccentric # 最好的bFS树半径。 # 随机挑选k个点固定次数。 temp_all_cover = 0 temp_cover = 0 temp_ave_cover = 0 if len(node_list) > self.fix_number_source * 2: # 这一层只有大于3个点才可以。 itemNumber = int(len(node_list) / 10) # 层数越大,节点越多,应该采样越多才能逼近近似值。 for frequency in range(itemNumber): # 抽取10次,这里有问题,有些层数目多,怎么抽取会好点?按照层数抽取相应的次数会比较好点,公平。 slice = random.sample(node_list, self.fix_number_source) temp_cover = commons.getSimilir1(slice, M_dis, singleRegionList, tempGraph) temp_all_cover += temp_cover if temp_all_cover != 0: temp_ave_cover = temp_all_cover / itemNumber # 求出平均覆盖率。 print('temp_ave_cover', temp_ave_cover) else: temp_ave_cover = 0.1 if temp_ave_cover <= min_cover: # 这一层表现优异,记下h,以及这一层的所有节点。 print('每次平均的覆盖率是' + str(min_cover)) print('temp_ave_cover', temp_ave_cover) min_cover = temp_ave_cover best_h_node = node_list best_h = M_dis print('输出表现优异同学,看看' + str(best_h_node), str(best_h)) # 得到最优层数解,再大量进行选择,使用jaya算法。构建大量样本。在固定h下的寻找最合适的节点。 ''' 1 构建种群样本下 2 在固定h下更新 ''' fix_number_sourcetemp = self.fix_number_source Sampleset = [] for i in range(50): Sampleset.append(random.sample(best_h_node, self.fix_number_source)) infectG = self.infectG min_cover = 1 min = 1 mincover = None bestsourceNews = None minCoverlist = [] for iter_number in range(4): for sample_index in range(len(Sampleset)): mincover = commons.getSimilir1(Sampleset[sample_index], best_h, singleRegionList, tempGraph) # 随机更换,看如何让变好 for j in range(1, 4, 1): # 随机变4次,只要能变好 # lateelement = [random.choice(best_h_node), random.choice(best_h_node), # random.choice(best_h_node),random.choice(best_h_node)] lateelement = [random.choice(best_h_node) for i in range(self.fix_number_source)] # print('当前输入的后面list' + str(lateelement)) latemincover = commons.getSimilir1(lateelement, best_h, singleRegionList, tempGraph) if mincover > latemincover: mincover = latemincover # 有更好地就要替换 # print("要进行替换了" + str(Sampleset[sample_index]) + '被替换成lateelement') Sampleset[sample_index] = lateelement # 替换 # print(Sampleset[sample_index]) # print('经过5次迭代之后的sample的list为多少呢?' + str(Sampleset)) # 计算样本集的similir,找出最好的。 for sources in Sampleset: mincover = commons.getSimilir1(sources, best_h, singleRegionList, tempGraph) if mincover < min: min = mincover # 这一次最好的覆盖误差率 bestsourceNews = sources # 最好的覆盖误差率对应的最好的那个解。 print('得到多源点情况最小的覆盖率为' + str(bestsourceNews) + str(min)) minCoverlist.append([bestsourceNews, best_h, min]) print(minCoverlist) result = sorted(minCoverlist, key=lambda x: (x[2])) self.single_best_result = result[0]
def cal_BFS_monte_Carlo(self, dir): # 构建传播子图, singleRegionList = [] for node_index in list(self.infectG.nodes()): if self.infectG.node[node_index]['SI'] == 2: singleRegionList.append(node_index) tempGraph = nx.Graph() tempGraphNodelist = [] for edge in self.infectG.edges: # if infectG.adj[edge[0]][edge[1]]['Infection']==2: #作为保留项。 if edge[0] in singleRegionList and edge[1] in singleRegionList: tempGraph.add_edges_from([edge], weight=1) tempGraphNodelist.append(edge[0]) tempGraphNodelist.append(edge[1]) self.tempGraph = tempGraph # 临时图生成 #真实的改进代码部分。 self.get_center(tempGraph) center = self.center print('传播图源点', center) # tempGraph = nx.Graph() # tempGraph = self.tempGraph print('这个传播子图的节点个数,也是我们用来做u的备选集合的' + str(len(set(tempGraph.nodes)))) print('这个感染区域的传播图节点个数') dfs_result_dict = self.test_BFS_node(tempGraph, source_node=center) sort_dfs_result_dict = sorted(dfs_result_dict.items(), key=lambda x: x[0]) print('sort_dfs_result_dict', sort_dfs_result_dict) ''' 这里我们只知道中心点的BFS点,还不能确定H。我们可以以传播子图的半径为最大h。进行 ''' self.singleRegionList = singleRegionList # 计算半径。 # radius_graph= nx.radius(tempGraph) # radius_graph = 40 # tempGraph =self.infectG #采用不同的感染图 radius_graph = self.radius print('图半径为', radius_graph) best_h = 0 best_h_node = [] min_cover = 100 # 某一层的覆盖率,肯定会比这个小。 for h in range(radius_graph // 2, radius_graph, 1): for k, node_list in sort_dfs_result_dict: print('how to that') # print(eccentric, node_list) # M_dis = max_eccentric - eccentric # 最好的bFS树半径。 # 随机挑选k个点固定次数。 temp_all_cover = 0 temp_cover = 0 temp_ave_cover = 0 if len(node_list ) > self.fix_number_source * 2: # 这一层只有大于3个点才可以。 if len(node_list) > 20: itemNumber = int(len(node_list) / 10) # 层数越大,节点越多,应该采样越多才能逼近近似值。 else: itemNumber = 2 # 这是树的情况,每一层节点太少了 for frequency in range( itemNumber ): # 抽取10次,这里有问题,有些层数目多,怎么抽取会好点?按照层数抽取相应的次数会比较好点,公平。 slice = random.sample(node_list, self.fix_number_source) # temp_cover = self.getSimilir1(slice, h, singleRegionList, tempGraph) temp_cover = commons.getSimilir1( slice, h, singleRegionList, tempGraph) temp_all_cover += temp_cover if temp_all_cover != 0: temp_ave_cover = temp_all_cover / itemNumber # 求出平均覆盖率。 print('temp_ave_cover', temp_ave_cover) else: temp_ave_cover = 0.1 if temp_ave_cover <= min_cover: # 这一层表现优异,记下h,以及这一层的所有节点。 print('每次平均的覆盖率是' + str(min_cover)) print('temp_ave_cover', temp_ave_cover) min_cover = temp_ave_cover best_h_node = node_list best_h = h print('输出表现优异同学,看看' + str(best_h_node), str(best_h)) # 得到最优层数解,再大量进行选择,使用jaya算法。构建大量样本。在固定h下的寻找最合适的节点。 ''' 1 构建种群样本下 2 在固定h下更新 ''' self.single_best_result = commons.jaya(tempGraph, best_h_node, self.fix_number_source, best_h, singleRegionList)
def cal_ecctity(self,source_list): #构建传播子图, singleRegionList = [] for node_index in list(self.infectG.nodes()): if self.infectG.node[node_index]['SI'] == 2: singleRegionList.append(node_index) tempGraph = nx.Graph() tempGraphNodelist = [] for edge in self.infectG.edges: # if infectG.adj[edge[0]][edge[1]]['Infection']==2: #作为保留项。 if edge[0] in singleRegionList and edge[1] in singleRegionList: tempGraph.add_edges_from([edge], weight=1) tempGraphNodelist.append(edge[0]) tempGraphNodelist.append(edge[1]) self.tempGraph = tempGraph # 临时图生成 print('这个传播子图的节点个数,也是我们用来做u的备选集合的' + str(len(set(tempGraphNodelist)))) print('这个感染区域的传播图节点个数') eccentricity_dict = nx.eccentricity(tempGraph) # print(list(eccentricity_dict.items())) # eccentricity_list= sorted(list(eccentricity_dict.items()), key= lambda x:x[1]) # print(eccentricity_list) eccentri_dict = defaultdict(list) for node_id, eccentric in eccentricity_dict.items(): eccentri_dict[eccentric].append(node_id) print(eccentri_dict) #从偏心率大的考虑,先保存最大偏心度。 sort_eccentricity_dict = sorted(eccentri_dict.items(),key= lambda x:x[0],reverse=True) max_eccentric = sort_eccentricity_dict[0][0] min_eccentric = sort_eccentricity_dict[-1][0] print('输出最大的就是那个偏心率'+str(max_eccentric)) from random import sample best_h = 0 M_dis = 0 best_h_node = [] min_cover = 100 # 某一层的覆盖率,肯定会比这个小。 tempGraph = self.infectG self.test_coverage(source_list,6,tempGraph,singleRegionList) for node_list_index in range(len(sort_eccentricity_dict)-1): for h in range(self.radius_graph // 2, self.radius_graph, 1): # print('how to that') # print(sort_eccentricity_dict[node_list_index][1]) # print(sort_eccentricity_dict[node_list_index][0]) sort_eccentricity_dict[node_list_index][1].extend(sort_eccentricity_dict[node_list_index + 1][1]) # print(sort_eccentricity_dict[node_list_index][1]) M_dis = max_eccentric - sort_eccentricity_dict[node_list_index][0] # 最好的bFS树半径。 # 随机挑选k个点固定次数。 temp_all_cover = 0 temp_cover = 0 temp_ave_cover = 0 if len(sort_eccentricity_dict[node_list_index][1]) > self.fix_number_source * 2: # 这一层只有大于3个点才可以。 itemNumber = int(len(sort_eccentricity_dict[node_list_index][1]) / 20) # 层数越大,节点越多,应该采样越多才能逼近近似值。 for frequency in range(itemNumber): # 抽取10次,这里有问题,有些层数目多,怎么抽取会好点?按照层数抽取相应的次数会比较好点,公平。 slice = random.sample(sort_eccentricity_dict[node_list_index][1], self.fix_number_source) temp_cover = commons.getSimilir1(slice, h, singleRegionList, tempGraph) temp_all_cover += temp_cover if temp_all_cover != 0: temp_ave_cover = temp_all_cover / itemNumber # 求出平均覆盖率。 print('temp_ave_cover', temp_ave_cover) else: temp_ave_cover = 0.1 if temp_ave_cover <= min_cover: # 这一层表现优异,记下h,以及这一层的所有节点。 print('每次平均的覆盖率是' + str(min_cover)) print('temp_ave_cover', temp_ave_cover) min_cover = temp_ave_cover best_h_node = sort_eccentricity_dict[node_list_index][1] best_h = h print('输出表现优异同学,看看' + str(best_h_node), str(best_h)) #得到最优层数解,再大量进行选择,使用jaya算法。构建大量样本。在固定h下的寻找最合适的节点。 ''' 1 构建种群样本下 2 在固定h下更新 ''' self.single_best_result = commons.jaya(tempGraph, best_h_node, self.fix_number_source, best_h, singleRegionList) return best_h,singleRegionList,tempGraph