影响力传播的线性阈值模型:
网络中连接任意两个节点u,v之间的边都有权重,任意一个节点它的各个邻居节点的边的权重之和为1,即
![](https://i-blog.csdnimg.cn/blog_migrate/b71fe58eab609fd03182f6b88cb8633c.png)
N(v):neighbors of v.
网络中的节点分为已激活节点和未激活节点,每个节点都有一个自己的激活阈值Θ(每个节点的激活阈值可以不同,且现实情况下社交网络的各个用户的激活阈值一般不相同,有的用户活跃,阈值低,容易受人影响,而有的用户较沉默,阈值高)。未被激活的节点v受所有与之相邻且已被激活的节点u的影响。当未激活节点v与所有已被激活的邻居节点的边的权重之和达到或超过激活阈值Θ时,节点v就会被激活。
即当满足条件:
![](https://i-blog.csdnimg.cn/blog_migrate/b64881350285a1ce21dd9ccc3751354f.png)
Na(v):active neighbors of v.
v被激活之后,它也会以同样的方式影响它自己的未被激活的邻居节点。这样会有越来越多的,满足激活条件的节点被激活,直到最后再也没有新的节点被激活了,激活过程才会停止。
上述过程被称为影响力传播的线性阈值模型(Linear Threshold Model),传播过程停止时最终被激活的节点的数量被称为影响力的传播范围(Influence Spread)。
无向无权图的线性阈值模型的Java实现:
public int beginDiffusionProcess(ArrayList<Node> graph,ArrayList<Integer> activeNodeIds,int lastInfSpread)
{
//Mark the active neighbors of each node.
for(Node nd:graph)
{
for(Node n:nd.neighbors)
{
if(activeNodeIds.contains(n.nodeId))
{
n.setActive(true);
}
}
}
//Determine whether each node is activated or not.
for(Node nd:graph)
{
int activeNeighbor_Num=0;
for(Node n:nd.neighbors)
{
if(n.isActive())
{
activeNeighbor_Num++;
}
}
if (activeNeighbor_Num/(nd.neighbors.size()*1.0)>=nd.getThreshold())//如果是带权图,这里要修改
{
nd.setActive(true);
activeNodeIds.add(nd.nodeId);
}
}
//Get the influence spread of the current step.
int infSpread=0;
for(Node n:graph)
{
if(n.isActive())
{
infSpread++;
}
}
//If it converges,stop the diffusion process,else continue the next step.
if(lastInfSpread==infSpread)
return infSpread;
else
return beginDiffusionProcess(graph,activeNodeIds,infSpread);
}
下面的代码调用上述方法,获取最终的Influence Spread:
public int GetInfSpread(ArrayList<Node> graph)
{
ArrayList<Integer> activeNodeIds=new ArrayList<Integer>();
//this.dimensions是已经被激活的种子节点,是某一个类的静态属性,类型为ArrayList<Node>,这些节点会尝试激活它们的邻居节点。
for(Node n:this.dimensions)
{
activeNodeIds.add(n.nodeId);
}
int lastInfSpread=0;
return beginDiffusionProcess(graph, activeNodeIds,lastInfSpread);
}
其他相关的代码:
Node.java
import java.util.ArrayList;
public class Node implements Comparable<Node>
{
public int nodeId;
public ArrayList<Node> neighbors = new ArrayList<Node>();
private boolean b_isActive = false;
private double threshold = 0.0;
public Node(int nodeId, double threshold)
{
this.nodeId = nodeId;
this.threshold = threshold;
}
public int neighbors_num()
{
return this.neighbors.size();
}
public void setActive(boolean isActive)
{
this.b_isActive = isActive;
}
public boolean isActive(){
return this.b_isActive;
}
public double getThreshold(){
return this.threshold;
}
// Sort nodes by (out)degree
public int compareTo(Node anotherNode)
{
if (this.neighbors != null && anotherNode.neighbors != null)
{
// reverse order
return anotherNode.neighbors_num() - this.neighbors_num();
// positive order
// return this.neighbors_num()-anotherNode.neighbors_num();
}
return 0;
}
}