先决条件: 社交网络介绍
在社交网络中,网络有2种类型-未签名网络和已签名网络。在未签名的网络中,任何节点之间都没有符号,而在签名的网络中,+或-的两个节点之间始终都存在一个符号。 “ +”号表示2个节点之间的友谊,“-”号表示2个节点之间的敌对状态。
我们的任务是使用Python语言在N个节点上创建一个签名网络。
方法:
- 创建图并向其添加节点。
- 添加所有可能的边并为其分配一个符号。
- 获取网络中所有可能的三角形的列表。
- 将所有三角形的符号详细信息存储在网络中。
- 计算网络中不稳定三角形的总数
- 现在从列表中选取一个不稳定的三角形并使它稳定。
- 再次计算多个不稳定三角形。
- 重复步骤6和7,直到没有不稳定的三角形。
- 现在形成一个联盟(联盟1中的朋友节点为红色,而其他联盟中的敌人节点为蓝色)并显示图形。
下面是实现。
Python3
import networkx as nx
import matplotlib.pyplot as plt
import random
import itertools
def get_signs_of_graph(g, tris_list):
# eg-['A-B','B-C','C-A']
all_signs = []
for i in range(len(tris_list)):
t = []
t.append(g[tris_list[i][0]][tris_list[i][1]]['sign'])
t.append(g[tris_list[i][1]][tris_list[i][2]]['sign'])
t.append(g[tris_list[i][2]][tris_list[i][0]]['sign'])
all_signs.append(t)
return all_signs
def unstablecount(all_signs):
stable = 0
unstable = 0
for i in range(len(all_signs)):
if (((all_signs[i]).count('+')) == 1 or ((all_signs[i]).count('+')) == 3):
stable += 1
unstable = len(all_signs) - stable
return unstable
def move_graph_to_stable(g, tris_list, all_signs):
found_unstable = False
ran = 0
while (found_unstable == False):
ran = random.randint(0, len(tris_list) - 1)
if (all_signs[ran].count('+') % 2 == 0):
found_unstable = True
else:
continue
r = random.randint(1, 3)
if (all_signs[ran].count('+') == 2):
if (r == 1):
if (g[tris_list[ran][0]][tris_list[ran][1]]['sign'] == '+'):
g[tris_list[ran][0]][tris_list[ran][1]]['sign'] = '-'
else:
g[tris_list[ran][0]][tris_list[ran][1]]['sign'] = '+'
elif (r == 2):
if (g[tris_list[ran][1]][tris_list[ran][2]]['sign'] == '+'):
g[tris_list[ran][1]][tris_list[ran][2]]['sign'] = '-'
else:
g[tris_list[ran][1]][tris_list[ran][2]]['sign'] = '+'
else:
if (g[tris_list[ran][0]][tris_list[ran][2]]['sign'] == '+'):
g[tris_list[ran][0]][tris_list[ran][2]]['sign'] = '-'
else:
g[tris_list[ran][0]][tris_list[ran][2]]['sign'] = '+'
else:
if (r == 1):
g[tris_list[ran][0]][tris_list[ran][1]]['sign'] = '+'
elif (r == 2):
g[tris_list[ran][1]][tris_list[ran][2]]['sign'] = '+'
else:
g[tris_list[ran][0]][tris_list[ran][2]]['sign'] = '+'
return g
def Coalition(g):
f = []
s = []
nodes = g.nodes()
r = random.choice(list(nodes))
f.append(r)
processed_nodes = []
to_be_processed = [r]
for each in to_be_processed:
if each not in processed_nodes:
neigh = list(g.neighbors(each))
for i in range(len(neigh)):
if (g[each][neigh[i]]['sign'] == '+'):
if (neigh[i] not in f):
f.append(neigh[i])
if (neigh[i] not in to_be_processed):
to_be_processed.append(neigh[i])
elif (g[each][neigh[i]]['sign'] == '-'):
if (neigh[i] not in s):
s.append(neigh[i])
processed_nodes.append(neigh[i])
processed_nodes.append(each)
return f, s
# 1.Create graph
g = nx.Graph()
n = 8
g.add_nodes_from(range(1, n + 1))
map = {1: "A", 2: "B", 3: "C", 4: "D", 5: "E",
6: "F", 7: "G", 8: "H", 9: "I", 10: "J"}
signs = ['+', '-']
g = nx.relabel_nodes(g, map)
# 2.Add every possible edge and assign sign
for i in g.nodes():
for j in g.nodes():
if (i != j):
g.add_edge(i, j, sign=random.choice(signs))
# 3.Display graph
edge_attributes = nx.get_edge_attributes(g, 'sign')
pos = nx.circular_layout(g)
nx.draw(g, pos, node_size=3000, with_labels=1)
nx.draw_networkx_edge_labels(
g, pos, edge_labels=edge_attributes, font_size=20, font_color='blue')
plt.show()
# 4.1.Get list of all the triangles in network
nodes = g.nodes()
tris_list = [list(x) for x in itertools.combinations(nodes, 3)]
# 4.2.Store the sign details of all the triangles
all_signs = get_signs_of_graph(g, tris_list)
# 4.3.Count total number of unstable triangle
# in the network
unstable = unstablecount(all_signs)
# 5 chose the triangle in the graph that is unstable
# and make the triangle stable
unstable_track = [unstable]
while (unstable != 0):
g = move_graph_to_stable(g, tris_list, all_signs)
all_signs = get_signs_of_graph(g, tris_list)
unstable = unstablecount(all_signs)
unstable_track.append(unstable)
# 6 Form the coalition
first, second = Coalition(g)
print(first)
print(second)
edge_labels = nx.get_edge_attributes(g, 'sign')
pos = nx.circular_layout(g)
nx.draw_networkx_nodes(g, pos, nodelist=first,
node_color='red', node_size=4000)
nx.draw_networkx_nodes(g, pos, nodelist=second,
node_color='blue', node_size=4000)
nx.draw_networkx_labels(g, pos)
nx.draw_networkx_edges(g, pos)
nx.draw_networkx_edge_labels(g, pos, edge_labels=edge_labels, font_color="red")
plt.show()
输出:
['G', 'B', 'C', 'H']
['A', 'D', 'E', 'F']