简介
对于影响力最大化问题,我以前写过几个blog
影响力最大化 IC模型+贪心算法
影响力最大化 模拟爆发(粗糙笔记)
影响力最大化 IC 蒙特卡洛模拟 贪心算法
影响力最大化 IMRank 我心中的最优算法
影响力最大化 CELF 成本效益延迟转发算法
这篇文章采用CELF的算法来解决影响力最大化问题。
CELF——Cost Effective Lazy Forward Algorithm
这个算法是在2007年提出的,论文地址如下:
Leskovec et al. (2007)
主要是对于基于IC模型的贪心算法的一种改进,IC模型我以前的文章中说过,有兴趣的可以从前面的简介中跳转去看一看。
我们知道,IC模型和贪心算法的结合对于解决影响力最大化问题存在效率低的问题,因为需要遍历每一个未激活节点的IC模型影响力,才能找到一个最大的影响力的节点加入seed set。这样的算法虽然能够保证正确率,但是时间上的消耗算力上的消耗面对真正应用中的复杂网络就是不能使用的。
成千上万个节点求一个最大影响力集合用贪心+IC估计得跑个好几天了。这是不行的。
所以CELF算法对于时间方面做了很好的提升。
算法原理
CELF利用扩展函数的子模属性,这意味着在Greedy算法的一次迭代中给定节点的边际扩展不能大于其在先前迭代中的边际扩展。这有助于我们以更复杂的方式选择要为其评估扩散函数的节点,而不是简单地评估所有节点的扩散。
更具体地说,在第一轮中,我们计算所有节点的蔓延(我们仍然选择greedy算法),并将它们存储在列表中,然后进行排序。顶部节点在第一次迭代中被添加到种子集中,然后从列表中删除。在下一次迭代中,仅计算顶部节点的影响力差值。
如果在排序后该节点仍位于列表的顶部,则它必须具有所有节点中最高的边际增益。之所以得到这个结论,因为我们知道,如果我们计算所有其他节点的边际增益,它们将低于列表中当前的值,因此“顶部节点”将保持在顶部。此过程继续进行,在计算完边际扩展后找到保留在顶部的节点,然后将其添加到种子集中。通过避免计算许多节点的扩展,CELF的结果比贪婪的要快得多。
我知道上面有很多术语让大家有点蒙,没关系后面的代码很简单,看到后面就明白了。
算法实现
celf算法主要有两个部分组成:
- 利用Greedy算法,遍历图中节点,根据影响力进行排序。
然后选择排名最高的,也就是影响力最大的节点进入seed set。
2. 查找剩余k-1个种子节点
在每次迭代中,该算法将评估列表Q中顶部节点的边际扩展,并将其替换为列表中的Q。如果在计算排序后,顶部节点保留在原位,则将该节点选作下一个种子节点。如果不是,则评估Q中新的顶部节点的边际扩展,依此类推。
其中我们利用LOOKUPS来记录每一次种子集新添加的节点执行的边际差次数。
代码实现
实例测试
首先引入库函数
%matplotlib inline
import matplotlib.pyplot as plt
from random import uniform, seed
import numpy as np
import pandas as pd
import time
from igraph import *
import random
然后构建一个简单地测试图
source = [0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,3,4,5]
target = [2,3,4,5,6,7,8,9,2,3,4,5,6,7,8,9,6,7,8,9]
g = Graph(directed=True)
g.add_vertices(range(10))
g.add_edges(zip(source,target))
plot(g)
一个很简单的图。
结果:
大家共勉~~