在经典的贪心算法的基础上,Wei Chen等人提出了改进算法NewGreedy。每条边uv在影响力传播过程中对全局的影响力的传播有且仅有一次,无论是从u到v,还是从v到u,因此,我们可以首先对社交网络中的边预处理一下,去掉一些关系不大的边得到一个新的更小的网络,在之后计算影响力期望值时,便只在优化后的小网络上进行影响力传播。具体的操作过程为:针对网络图G,每次随机删除固定的边数,为了减少算法的随机性,该过程重复R次最终会得到一个趋于稳定的小型网络。之所以采用这样的策略是因为被删除的那些边对整个网络的影响力很小,基本上可以忽略不计。NewGreedy算法的代码如下:
class NGIC:
def __init__(self):
pass
def preprocess(self, G, propProbability):
directedGraph = nx.DiGraph()
for u in G.nodes():
for v in G.neighbors(u):
if (u != v):
directedGraph.add_edge(u, v, pp=propProbability)
return directedGraph
def findSeed(self, G, R, K, propProbability):
seedNode = []
for _ in range(K): # (Line 2)
nodeValues = {} # Initialize Sv (Line 3)
for node in G.nodes():
nodeValues[node] = 0
for _ in range(R):
# CREATING SUBGRAPH G' (Line 5)
start = time.time()
removedEdge = [] # Initialize for removal of edge (Line 5)
setOfReachables = set()
for edge in G.edges():
if (not (self.flipCoin(propProbability))):
removedEdge.append(edge)
subgraph = G.copy()
for edge in removedEdge:
subgraph.remove_edge(edge[0], edge[1])
end = time.time()
total = end - start
print("Subgraph creation time : " + str(total))
start = time.time()
# Compute RG'(S) (Line 6)
for node in seedNode:
setOfReachables.update(nx.dfs_preorder_nodes(subgraph, node))
# Starting at (Line 8), Compute Line 7 if in condition
for node in subgraph.nodes():
if (node not in seedNode and node not in setOfReachables):
nodeValues[node] += len(list(nx.dfs_preorder_nodes(subgraph, node)))
end = time.time()
total = end - start
print("Calculation time : " + str(total))
# Find Mean of all nodeValues (Line 14)
nodeValues = {k: v / R for k, v in nodeValues.items()}
# Node that has the max value (Line 15)
maxNode = max(nodeValues, key=nodeValues.get)
seedNode.append(maxNode)
return seedNode
def simulate(self, G, seedNode, propProbability):
newActive = True
currentActiveNodes = copy.deepcopy(seedNode)
newActiveNodes = set()
activatedNodes = copy.deepcopy(seedNode) # Biar ga keaktivasi 2 kali
influenceSpread = len(seedNode)
while (newActive):
for node in currentActiveNodes:
for neighbor in G.neighbors(
node): # Harus dicek udah aktif apa belom, jangan sampe ngaktifin yang udah aktif
if (neighbor not in activatedNodes):
if (self.flipCoin(propProbability)):
newActiveNodes.add(neighbor)
activatedNodes.append(neighbor)
influenceSpread += len(newActiveNodes)
if newActiveNodes:
currentActiveNodes = list(newActiveNodes)
newActiveNodes = set()
else:
newActive = False
return influenceSpread
def flipCoin(self, probability):
return random.random() < probability