影響力傳播的線性閾值模型:
網絡中連接任意兩個節點u,v之間的邊都有權重,任意一個節點它的各個鄰居節點的邊的權重之和為1,即

N(v):neighbors of v.
網絡中的節點分為已激活節點和未激活節點,每個節點都有一個自己的激活閾值Θ(每個節點的激活閾值可以不同,且現實情況下社交網絡的各個用戶的激活閾值一般不相同,有的用戶活躍,閾值低,容易受人影響,而有的用戶較沉默,閾值高)。未被激活的節點v受所有與之相鄰且已被激活的節點u的影響。當未激活節點v與所有已被激活的鄰居節點的邊的權重之和達到或超過激活閾值Θ時,節點v就會被激活。
即當滿足條件:

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; } }
