Reputation: 151
I'm working on reproduce of Ripple Walk Sampler. This is an algorithm to extract subgraph from target graph.
Here we have to set s and r as parameters. s is the size of subgraph and r is an expansion ratio, which means the ration of nodes in neighbor set to be sampled in current step.
For subgraph Gk, it is initialized with a random node vs, then expands along the connections among nodes.
After multiple steps of expansion, the subgraph with a size of s will be returned. During each expansion, the neighbor set contains the potential nodes to be sampled.
Then r of the nodes in neighbor set will be added into the current subgraph.
Here is the original pseudo code and the example of Sampling process.
And here is my attempt:
import random
import networkx as nx
import numpy as np
m = np.matrix([
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0]])
G = nx.from_numpy_matrix(m) #target graph
r = 0.5 #expansion ratio
S = 4 #subgraph size
Gk = nx.DiGraph() #initialize subgraph
Vk = [] #initialize nodes
vs = random.randint(0, G.size()) #randomly select the initial node from G
Gk.add_node(vs) #add vs to Gk
while len(Vk) < S:
#get neighbor nodes set of Vk
NS = [n for n in G.neighbors(vs)]
print(NS)
#randomly select r of nodes in NS, add them into the Vk
for nodes in NS:
if random.random() < r:
Vk.append(nodes)
I'm struggling with the logic of line 4 in pseudo code, the part of getting neighbor set of Vk. I know this code is wrong but how should I implement this part?
Can someone help me to fix this? Any suggestions/advices would be appreciated.
Upvotes: 3
Views: 944
Reputation: 1515
Here you go:
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
def RPS(G, r=0.5, S=4):
# designed for undirected graph
#initialize subgraph
Gk = nx.Graph()
#initialize nodes
Vk = []
#randomly select the initial node from G
vs = np.random.randint(0, G.size())
print(vs)
#add vs to Gk
Gk.add_node(vs)
Vk.append(vs)
while len(Vk) < S:
#get neighbor nodes set of Vk (step 4) (Also appending j just for the purpose of adding edge)
NS = [(n, j) for j in Vk for n in G.neighbors(j) if n not in Vk]
# randomly select r of nodes in NS, add them into the Vk
for node, j in NS:
if np.random.uniform() < r:
Vk.append(node)
Gk.add_edge(j, node)
if len(Vk) == S:
break
return Gk
if __name__ == '__main__':
# "Undirected" graph adjacency matrix
m = np.matrix([
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 0, 1, 0, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 1, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0]])
# G = nx.from_numpy_matrix(m, create_using=nx.MultiDiGraph())
G = nx.from_numpy_matrix(m)
#expansion ratio
r = 0.5
#subgraph size
S = 4
Gk = RPS(G, r, S)
# VISUALIZATION
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos)
nx.draw_networkx_nodes(G, pos, nodelist=list(Gk.nodes()), node_color='r')
nx.draw_networkx_labels(G, pos)
nx.draw_networkx_edges(G, pos, edge_color='b', width=0.5)
nx.draw_networkx_edges(G, pos, edgelist=list(Gk.edges()), edge_color='g', width=1)
plt.axis('off')
plt.show()
(r = 0.5, S = 4, red - subgraph, blue - target graph)
Upvotes: 1