controller.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. import networkx as nx
  2. from networkx.algorithms import community # for community structure later
  3. import collections
  4. from matplotlib import pyplot as plt
  5. from networkx.algorithms import approximation as app
  6. import operator
  7. # from networkx.generators.community import LFR_benchmark_graph
  8. import math
  9. import time
  10. from itertools import repeat
  11. import copy
  12. import pickle
  13. import random
  14. import numpy as np
  15. import pandas as pd
  16. from functools import reduce
  17. from scipy.special import comb, perm
  18. from itertools import repeat
  19. import copy
  20. import time
  21. import os
  22. import csv
  23. import json
  24. import requests
  25. import traceback
  26. from itertools import combinations
  27. from collections import defaultdict
  28. from collections import deque
  29. from optparse import OptionParser
  30. ######################################
  31. # STEP 0: Initial graph ##
  32. ######################################
  33. # file = open('./generate/Graph_gpickleSCS.gpickle', 'rb')
  34. # Graph=pickle.load(file)
  35. ''' 准备数据 '''
  36. SCHEDULER_BASE_URL = os.getenv("SCHEDULER_BASE_URL")
  37. BACKEND_BASE_URL = os.getenv("BACKEND_BASE_URL")
  38. missionId = os.getenv("missionId")
  39. planId = os.getenv("planId")
  40. headers = {
  41. "Content-Type": "application/json", # 明确声明数据格式
  42. "Accept": "application/json" # 声明期望的响应格式
  43. }
  44. params = {
  45. "missionId": missionId,
  46. "planId": planId,
  47. }
  48. print("[output]", json.dumps({'msg': 'started'}), flush=True)
  49. response = requests.get(SCHEDULER_BASE_URL + '/fetchData', params=params, headers=headers)
  50. fetchedData = response.json()
  51. if not fetchedData:
  52. # 此处应当放置错误报告
  53. quit()
  54. # fetchedData: {'nodes': [] , 'edges': []}
  55. '''准备数据(完毕)'''
  56. # 更改为从flask获取数据
  57. input_nodes = []
  58. for line in fetchedData['nodes']:
  59. # 清空原有meta
  60. line['meta'] = []
  61. input_nodes.append([int(line['id']), str(line['type']).upper()])
  62. input_edges = []
  63. for line in fetchedData['edges']:
  64. # 清空原有meta
  65. line['meta'] = []
  66. input_edges.append([int(line['from']), int(line['to'])])
  67. # 检测节点编号,本程序要求从0起
  68. flag = True
  69. for node in input_nodes:
  70. if int(node[0]) == 0:
  71. flag = False
  72. if flag:
  73. # 原始数据不从0开始,则所有节点的id均减一,同时边的节点id也减一
  74. for node in input_nodes:
  75. node[0] = int(node[0]) - 1
  76. # 同时修改原始输入数据
  77. for node in fetchedData['nodes']:
  78. node['id'] = int(node['id']) - 1
  79. for edge in input_edges:
  80. edge[0] = int(edge[0]) - 1
  81. edge[1] = int(edge[1]) - 1
  82. for edge in fetchedData['edges']:
  83. edge['from'] = int(edge['from']) - 1
  84. edge['to'] = int(edge['to']) - 1
  85. # print("测试输出节点和边")
  86. # print(input_nodes)
  87. # print(input_edges)
  88. # file = open('nodes.csv', 'r')
  89. # idx = 0
  90. # for line in file:
  91. # input_nodes.append([idx, line.replace('\n', '')])
  92. # idx += 1
  93. # file.close()
  94. # file = open('edges.csv', 'r')
  95. # csvfile = csv.reader(file)
  96. # idx = 0
  97. # for line in csvfile:
  98. # input_edges.append([int(line[0]), int(line[1])])
  99. Graph = nx.Graph()
  100. for i in input_nodes:
  101. Graph.add_nodes_from([i[0]],type=i[1])
  102. for i in input_edges:
  103. #G.add_weighted_edges_from([(i,j,random.random())])
  104. Graph.add_edges_from([(i[0], i[1])])
  105. ###### 手动输入图结构 ###########
  106. '''
  107. Graph = nx.DiGraph()
  108. nodesfile = open('./nodes', 'r')
  109. for line in nodesfile:
  110. nodeline = line.replace('\n','').split(',')
  111. Graph.add_node(int(nodeline[0]), type = nodeline[1])
  112. edgefile = open('./edges', 'r')
  113. for line in edgefile:
  114. edgeline = line.replace('\n', '').split(',')
  115. Graph.add_edges_from([(int(edgeline[0]), int(edgeline[1]))])
  116. '''
  117. ###############################
  118. G = Graph.to_undirected() # 无向图
  119. graphname = 'ori' + str(random.randint(10000, 99999))
  120. ## remove self loops & degree = 0
  121. # G.remove_edges_from(G.selfloop_edges(G, data=True)) #ckb change
  122. isola = [k for k in nx.isolates(G)]
  123. G.remove_nodes_from(isola)
  124. Dict_Centrality = nx.degree_centrality(G)
  125. Centrality = list(Dict_Centrality.values()) # degree centerality
  126. Name = list(Dict_Centrality.keys())
  127. A = nx.adjacency_matrix(G) # A = matix
  128. #code for search SDI
  129. nodes=Graph.nodes
  130. li = np.array(nx.adjacency_matrix(Graph).todense())# 转换为numpy矩阵是因为原始的格式不支持A[i][j]形式的索引
  131. class GrfAllEdge():
  132. # 定义方法,重点是items列表用作栈
  133. def __init__(self, total):
  134. self.total = total
  135. self.li = li # 使用局部邻接矩阵
  136. self.SDIi = []
  137. def bfs_paths(self,start,goal,max_depth=5):
  138. if start == goal:
  139. return
  140. queue = deque([(start,[start])])
  141. while queue:
  142. current,path = queue.popleft()
  143. if len(path) > max_depth:
  144. continue
  145. # 获取栈顶的类型,防止D到S的路径
  146. tp_current = Graph._node[path[-1]]['type']
  147. for next_node in range(self.total):
  148. if self.li[current][next_node] == 1 and next_node not in path:
  149. if len(path) >= max_depth:
  150. continue
  151. tp_next = Graph._node[next_node]['type']
  152. if tp_current == 'D' and tp_next == 'S':
  153. continue
  154. new_path = list(path) # 复制当前路径
  155. new_path.append(next_node) # 添加新节点到路径
  156. if next_node == goal: # 如果下一个节点是目标节点
  157. self.SDIi.append(new_path) # 添加到解决方案路径列表
  158. else:
  159. queue.append((next_node, new_path)) # 将新路径添加到队列
  160. def get_oc(node):
  161. #get SDI nodes
  162. SensSet, DeciSet, InfluSet = [], [], []
  163. for index in range(len(node)):
  164. tps = Graph._node[index]['type']
  165. if tps == 'S':
  166. SensSet.append(index)
  167. elif tps == 'D':
  168. DeciSet.append(index)
  169. elif tps == 'I':
  170. InfluSet.append(index)
  171. #get OC by DFS
  172. OC_ALL = []
  173. for orig in SensSet: #sensor nodes
  174. for goal in InfluSet: #influencer nodes
  175. edge = GrfAllEdge(len(node))
  176. edge.bfs_paths(orig,goal)
  177. OC_ALL.extend(edge.SDIi)
  178. return OC_ALL
  179. # 提取社团中的节点编号
  180. def get_community_nodes(community):
  181. return [node[0] for node in community]
  182. def get_communities_oc(communities):
  183. communities_oc = {}
  184. for community_name, community_nodes in communities.items():
  185. community_nodes_ids = get_community_nodes(community_nodes)
  186. communities_oc[community_name] = get_oc(community_nodes_ids)
  187. return communities_oc
  188. #转换作战链数为相对作战链矩阵
  189. def transform_matrix(matrix):
  190. # 获取矩阵形状和扁平化的矩阵
  191. rows, cols = matrix.shape
  192. flat_matrix = matrix.flatten()
  193. # 获取非零元素及其索引
  194. non_zero_indices = np.where(flat_matrix != 0)[0]
  195. non_zero_elements = flat_matrix[non_zero_indices]
  196. # 获取唯一值及其反向索引,用于构建排名
  197. unique_values, inverse_indices = np.unique(-non_zero_elements, return_inverse=True)
  198. # 对唯一值排名,这里使用负数是因为我们希望降序排列
  199. ranks = np.zeros_like(non_zero_elements, dtype=int)
  200. for i in range(len(unique_values)):
  201. ranks[inverse_indices == i] = i + 1
  202. # 将排名映射回原始矩阵位置
  203. ranked_non_zero_elements = np.zeros_like(flat_matrix, dtype=int)
  204. ranked_non_zero_elements[non_zero_indices] = ranks
  205. # 调整矩阵,将零元素的排名设置为最大排名加一
  206. max_rank = np.max(ranks)
  207. ranked_non_zero_elements[ranked_non_zero_elements == 0] = max_rank + 1
  208. # 重新形成原始矩阵的形状
  209. ranked_matrix = ranked_non_zero_elements.reshape(rows, cols)
  210. for i in range(len(ranked_matrix)):
  211. for j in range(len(ranked_matrix)):
  212. if i == j:
  213. ranked_matrix[i][j] = 0
  214. return ranked_matrix
  215. #缩小作战链矩阵的算法
  216. def Matrix_shrink_oc(oc_temp,ii,jj):
  217. k1 = oc_temp[:,ii]
  218. k2 = oc_temp[:,jj]
  219. dd = np.delete(oc_temp,[ii,jj],1)
  220. dd = np.delete(dd,[ii,jj],0)
  221. kk = np.maximum(k1,k2)
  222. kk = np.delete(kk,[ii,jj],0)
  223. m1 = np.vstack([dd,kk])
  224. m2 = np.append(kk,0)
  225. shrank = np.vstack([m1.T,m2])
  226. return shrank
  227. def main_function():
  228. ######################################
  229. # STEP 1: Identification of sources ##
  230. ######################################
  231. # print('##### STEP 1 #####')
  232. # print('--------------------')
  233. start_s1 = time.perf_counter()
  234. source = []
  235. sink = []
  236. iso = []
  237. leaf = []
  238. nodetemp = list(G.nodes)
  239. count_s1 = 0 # count nodes
  240. for i in nodetemp:
  241. count_s1 += 1
  242. # if count_s1 % 1000 == 0: # calculate time per 1000 nodes
  243. # print('Time Elapsed--- ' + str((time.perf_counter() - start_s1)) + ' Node:' + str(count_s1) + '/' + str(
  244. # len(G)) + '\n')
  245. nei = list(G.neighbors(i))
  246. iso_count = 0
  247. source_count = 0
  248. sink_count = 0
  249. if len(nei) == 1: # leaf
  250. leaf.append(i)
  251. continue
  252. for ii in nei: # counter
  253. '''
  254. node > neibour:source++
  255. node == neibour:isolate++
  256. '''
  257. if Dict_Centrality.get(i) > Dict_Centrality.get(ii):
  258. source_count += 1
  259. elif Dict_Centrality.get(i) == Dict_Centrality.get(ii):
  260. iso_count += 1
  261. source_count += 1 # ?
  262. else:
  263. sink_count += 1
  264. continue
  265. if iso_count == G.degree(i): # all the
  266. if all(Centrality[Name.index(p)] == Centrality[Name.index(i)] for p in list(G.neighbors(i))): # clique
  267. if not any(w in source for w in list(G.neighbors(i))): # 顺序的问题?
  268. source.append(i) # get one as hub, the other are inner members
  269. Centrality[Name.index(i)] += 0.5 # additive value to this hub
  270. else:
  271. iso.append(i) # non-clique
  272. if source_count == G.degree(i):
  273. if i not in iso and i not in source: # source: greater than at least one neighbor in centrality score
  274. source.append(i)
  275. if sink_count == G.degree(i) & G.degree(i) > 1:
  276. sink.append(i)
  277. # 完成第一步,进度20%
  278. print("[output]", json.dumps({'msg': 'progress', 'data': 20}), flush=True)
  279. r_source = len(source) / len(G) # proportion of source
  280. r_sink = len(sink) / len(G) # proportion of sink
  281. inner = len(G) - len(source) - len(sink) - len(iso) - len(leaf)
  282. #############################################################
  283. # STEP 2: Propagation and Formulation of Local Communities ##
  284. #############################################################
  285. # print('##### STEP 2 #####')
  286. # print('--------------------')
  287. start_s2 = time.perf_counter()
  288. History = [[] for i in repeat(None, len(nx.nodes(G)))] # H = (history,time)
  289. community = [[] for i in repeat(None, len(source))] # X = (source_node,time)
  290. t = 0
  291. tmax = 100
  292. time_record = []
  293. for i in range(len(source)):
  294. community[i].append((source[i], t)) # first label , first contagion time
  295. History[Name.index(source[i])] = [(source[i], 0)]
  296. while t < tmax:
  297. if t % 10 == 0 and t > 0:
  298. print("[output]", json.dumps({'msg': 'progress', 'data': int(20 + t / tmax * 30)}), flush=True)
  299. old_community = copy.deepcopy(community)
  300. old_history = copy.deepcopy(History)
  301. t = t + 1
  302. for i in range(len(source)): # all propagation happens at the same time
  303. # if (i + 1) % 100 == 0:
  304. # print('Iteration:' + str(t) + '/' + str(tmax) + '---' + 'Source:' + str(i + 1) + '/' + str(
  305. # len(source)) + '---Time Elapsed---' + str(
  306. # (time.perf_counter() - start_s2)) + '---CommunitySize---' + str(len(community[i])))
  307. for j in community[i]:
  308. if j[1] == t - 1: # newly join the community from last round propagation
  309. for s in G.neighbors(j[0]):
  310. if Centrality[Name.index(s)] < Centrality[Name.index(j[0])]:
  311. if s not in [k[0] for k in community[i]]:
  312. community[i].append((s, t))
  313. History[Name.index(s)].append((source[i], t))
  314. time_record.append((time.perf_counter() - start_s2))
  315. if old_community == community or old_history == History: # no change in History or community membership
  316. break
  317. # check History and community are consistent #
  318. if sum(len(History[i]) for i in range(len(History))) != sum(len(community[i]) for i in range(len(community))):
  319. print('WRONG! COMMUNITY AND HISTORY DONT MATCH!')
  320. ave_membership = sum(len(History[i]) for i in range(len(History))) / len(History) # mh
  321. ave_size = sum(len(community[i]) for i in range(len(community))) / len(community) # mx
  322. # mh = len(S)/N * mx ?
  323. elapsed = (time.perf_counter() - start_s2)
  324. # plot local communities #
  325. from matplotlib import colors as mcolors
  326. colors = dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS)
  327. old_co = list(community)
  328. old_his = list(History)
  329. len_hist = [len(hh) for hh in History]
  330. r_crossover = len(len_hist) - len_hist.count(1)
  331. ###############################################
  332. # STEP 3&4: Aggregation of Small Communities ##
  333. ###############################################
  334. # print('##### STEP 3&4 #####')
  335. # print('--------------------')
  336. start_s3 = time.perf_counter()
  337. #save chain
  338. # import os
  339. # current_path = os.path.dirname(os.path.abspath(__file__))
  340. # file_path = os.path.join(current_path, "oc.txt")
  341. #write
  342. # OC_ALL = get_oc(nodes)
  343. # with open(file_path,"w") as file:
  344. # for path in OC_ALL:
  345. # if path:
  346. # file.write(",".join(map(str,path)) + "\n")
  347. #read chain
  348. # with open(file_path, "r") as file:
  349. # OC_ALL = [list(map(int, line.strip().split(','))) for line in file]
  350. #get operation chain in any community
  351. community_dict = {}
  352. for comm in community:
  353. community_name = comm[0][0]
  354. community_dict[community_name] = comm
  355. # print(community_dict)
  356. # 注意community_dict中即保存了功能体结构
  357. # 取消将community_dict保存至文件,改为将其直接传递至flask
  358. # community_file = open('community.csv', 'w', newline='')
  359. # community_csv = csv.writer(community_file)
  360. # for community_source_node in community_dict:
  361. # for member_node in community_dict[community_source_node]:
  362. # community_csv.writerow([member_node[0], member_node[1], community_source_node])
  363. # community_file.close()
  364. # print("SOURCE", source)
  365. print("[output]", json.dumps({'msg': 'progress', 'data': 80}), flush=True)
  366. try:
  367. source_oc = get_communities_oc(community_dict)
  368. #get shared chain matrix
  369. OC_source = np.zeros((len(source),len(source)))
  370. for i,community_id_1 in enumerate(source):
  371. for j,community_id_2 in enumerate(source[i+1:],i+1):#只遍历上三角
  372. chains_1 = set(map(tuple, source_oc[community_id_1]))
  373. chains_2 = set(map(tuple, source_oc[community_id_2]))
  374. shared_chains = chains_1.intersection(chains_2)
  375. # if i == 3 and j ==4:
  376. # print(shared_chains)
  377. shared_count = len(shared_chains)
  378. OC_source[i][j] += shared_count
  379. OC_source[j][i] += shared_count # 利用对称性将值赋给矩阵的另一半
  380. except Exception as error:
  381. print(error, flush=True)
  382. # print(OC_source)
  383. # for i in range(len(source)):
  384. # for j in range(len(source)):
  385. # if i == j:
  386. # continue
  387. # else:
  388. # shared_oc = set(source_oc[i]).intersection(source_oc[j])
  389. # OC_source[i][j] += len(shared_oc)
  390. # print(OC_source)
  391. # OC_source_new = transform_matrix(OC_source).astype(int)
  392. # # print(OC_source_new)
  393. # #epsilon
  394. # epsilon_max = int(OC_source_new.max())
  395. # hierarchy_community = [list(source)]
  396. # epsilon_community_size = [(len(OC_source_new), 0)]
  397. # oc_temp = OC_source_new
  398. # oc_record = [list(oc_temp)]
  399. # phi_list = [] ## list of phi-epsilon
  400. # phi_ref_list = [] ## list of reference phi-epsilon
  401. # print("[output]", json.dumps({'msg': 'progress', 'data': 90}), flush=True)
  402. # for l in range(1,epsilon_max + 1):
  403. # # print('Epsilon:' + str(l) + '/' + str(epsilon_max) + '---' + 'Time Elapsed:' + str((time.perf_counter() - start_s3)))
  404. # temp = list(hierarchy_community[-1])
  405. # merging_count = 0 # count of num of merging (in each epsilon)
  406. # while True:
  407. # ij = np.argwhere(oc_temp == l) # Note: l starts from 1
  408. # # print("Ep = ",str(l),"ij = ",ij)
  409. # if len(ij) == 0: # no element == l
  410. # break
  411. # merging_count += 1
  412. # #change
  413. # rand_index = np.random.choice(len(ij))
  414. # ii, jj = ij[rand_index]
  415. # # ii = ij[0][0]
  416. # # jj = ij[0][1]
  417. # if type(temp[ii]) != list: # str to list
  418. # temp[ii] = [temp[ii]]
  419. # if type(temp[jj]) != list: # str to list
  420. # temp[jj] = [temp[jj]]
  421. # temp_com = temp[ii] + temp[jj] #merge community
  422. # tempp = [temp[ii],temp[jj]]
  423. # tempp_copy = list(tempp)
  424. # # print("--------------------")
  425. # # print("temp = ", temp, " Ep = ", str(l))
  426. # # print("temp[ii] = ",temp[ii]," temp[jj] = ",temp[jj]," temp_com = ",temp_com," tempp = ",tempp," temp_copy = ",tempp_copy)
  427. # # print("--------------------")
  428. # if len(temp[ii]) == 1:
  429. # tempp_copy[0] = temp[ii][0]
  430. # if len(temp[jj]) == 1:
  431. # tempp_copy[1] = temp[jj][0]
  432. # #merge community
  433. # temp.remove(tempp[0]) # remove old small community 1
  434. # temp.remove(tempp[1]) # remove old small community 2
  435. # temp.append(temp_com)
  436. # #shrink oc_matrix
  437. # oc_temp = Matrix_shrink_oc(oc_temp,ii,jj)
  438. # # print("oc_temp = ")
  439. # # print(oc_temp)
  440. # oc_record.append(oc_temp)
  441. # # jac_record.append(jac_temp)
  442. # hierarchy_community.append(temp)
  443. # epsilon_community_size.append((len(oc_temp),l+1))
  444. # print("hierarchy_community = ",hierarchy_community)
  445. # 注意hierarchy_community中保存了不同社团的层级关系,但是目前无法利用
  446. ## unconnected components ## i think oc_bad can merge
  447. # if len(np.argwhere(oc_temp == int(OC_source_new.max()))) == len(oc_temp)*(len(oc_temp)-1):#int(OC_source_new.max())is dummy
  448. # break
  449. # 准备汇报flask的数据
  450. result = {
  451. 'missionId': missionId,
  452. 'planId': planId,
  453. 'progress': 100,
  454. 'nodes': [],
  455. 'edges': [],
  456. }
  457. # 将节点和边直接放入nodes和edges
  458. result['nodes'] = fetchedData['nodes'].copy()
  459. # 删除可能存在的旧的group信息
  460. for n in result['nodes']:
  461. for meta_index in range(len(n['meta'])-1, -1, -1):
  462. if 'group' in n['meta'][meta_index]:
  463. del n['meta'][meta_index]
  464. result['edges'] = fetchedData['edges'].copy()
  465. # print(result['edges'])
  466. # print(result['nodes'])
  467. # 构建功能体核心节点与功能体编号的映射
  468. groups = {}
  469. group_index = 0
  470. for leader in community_dict:
  471. groups[group_index] = leader
  472. for group_node in community_dict[leader]:
  473. # 修改节点的meta,标注其所属的功能体
  474. node = [n for n in result['nodes'] if int(n['id']) == int(group_node[0])][0]
  475. for dicts in node['meta']:
  476. if type(dicts) != dict:
  477. print("ERROR, WRONG META", node['meta'])
  478. raise ValueError("ERROR, WRONG META")
  479. node['meta'].append({
  480. 'group': group_index,
  481. })
  482. group_index += 1
  483. print("[output]", json.dumps({'msg': 'result', 'data': result}), flush=True)
  484. ## refine hierarchy_community 0 ##
  485. # for i in range(len(hierarchy_community[0])):
  486. # hierarchy_community[0][i] = [(hierarchy_community[0][i])]
  487. #get hierarchy_nodes
  488. # com_node_dic = {}
  489. # for i in range(len(source)):
  490. # com_node_dic[source[i]] = community_nodes[i]
  491. # hierarchy_nodes = []
  492. # for hel_com in hierarchy_community:#对于层次的每一层
  493. # level_temp = []
  494. # for i in hel_com:#对于每层中的各个社团
  495. # if not isinstance(i,list):#不是小社团
  496. # nodes_all = set(com_node_dic[i]) if isinstance(com_node_dic[i], (list, set, tuple)) else set([com_node_dic[i]])
  497. # level_temp.append(nodes_all)
  498. # else:
  499. # nodes_all = set()
  500. # for j in i:
  501. # nodes_all.update(com_node_dic[j] if isinstance(com_node_dic[j], (list, set, tuple)) else [com_node_dic[j]])
  502. # level_temp.append(nodes_all)
  503. # hierarchy_nodes.append(level_temp)
  504. #
  505. # nodetemp = list(G.nodes)
  506. # sensors = 0 # 传感器
  507. # deciders = 0 # 决策者
  508. # influencer = 0 # 影响者
  509. # for i in range(len(nodetemp)):
  510. # tps = G._node[i]['type']
  511. # if tps == 'S':
  512. # sensors = sensors + 1
  513. # elif tps == 'D':
  514. # deciders = deciders + 1
  515. # else:
  516. # influencer = influencer + 1
  517. # print("Num of node S:" + str(sensors))
  518. # print("Num of node D:" + str(deciders))
  519. # print("Num of node I:" + str(influencer))
  520. # print('Num of nodes:'+ str(len(G.nodes)))
  521. # print('Num of edges:'+ str(len(G.edges)))
  522. # print('Num of operation chains:'+ str(len(OC_ALL)))
  523. # print('Num of sources:'+ str(len(source)))
  524. # print('Num of sinks:'+ str(len(sink)))
  525. # print('Num of isolated nodes:'+ str(len(iso)))
  526. # print('Num of leaf nodes:'+ str(len(leaf)))
  527. # print('Num of inner members:'+ str(inner))
  528. # print("hierarchy_community = ",hierarchy_community)
  529. # print("epsilon_community_size = ",epsilon_community_size)
  530. # print("epsilon_max = ",epsilon_max)
  531. # # save files
  532. # g = nx.read_gpickle("./generate/Graph_gpickleSCS.gpickle")
  533. # # #1.leaf sink hub
  534. # # 为列表中的每一个节点添加属性,同时检查节点是否存在
  535. # for node_list, node_type in zip([source, sink, iso, leaf], ["hub", "sink", "isolated", "leaf"]):
  536. # for node in node_list:
  537. # # 检查节点是否存在于图中
  538. # if node in g:
  539. # g._node[node]["detect_node"] = node_type
  540. # else:
  541. # # 如果节点不存在,输出一个错误消息
  542. # print(f"Node {node} not found in graph.")
  543. #2.small community
  544. # for community_index, nodes in enumerate(community_nodes):
  545. # for node in nodes:
  546. # if g.has_node(node):
  547. # g._node[node]["community"] = community_index
  548. #3.hierarchy_community
  549. # 遍历hierarchy_community和hierarchy_nodes来建立每个节点的属性
  550. # for level, (communities, nodes) in enumerate(zip(hierarchy_community, hierarchy_nodes)):
  551. # for community_id, community_nodes in zip(communities, nodes):
  552. # # 如果community_id是列表,那么社团需要合并
  553. # if isinstance(community_id, list):
  554. # for sub_community in community_id:
  555. # for node in community_nodes:
  556. # g._node[node] = {'community_id': sub_community, 'hierarchy_level': level}
  557. # else:
  558. # for node in community_nodes:
  559. # g._node[node] = {'community_id': community_id, 'hierarchy_level': level}
  560. # path = './generate/Graph_gml' + str(level)+'.gml'
  561. # nx.write_gml(g, path)
  562. # nx.write_gml(g, './generate/my_Graph_gml.gml')
  563. # nx.write_gpickle(g, "./generate/Graph_gpickleSCS.gpickle")
  564. if __name__ == '__main__':
  565. try:
  566. main_function()
  567. except Exception as error:
  568. print(str(error))
  569. print(traceback.format_exc())
  570. print("END ERROR")