轉載請注明出處:http://www.cnblogs.com/bethansy/p/6953625.html
LPA算法的思路:
首先每個節點有一個自己特有的標簽,節點會選擇自己鄰居中出現次數最多的標簽,如果每個標簽出現次數一樣多,那么就隨機選擇一個標簽替換自己原始的標簽,如此往復,直到每個節點標簽不再發生變化,那么持有相同標簽的節點就歸為一個社區。
算法優點:思路簡單,時間復雜度低,適合大型復雜網絡。
算法缺點:眾所周知,划分結果不穩定,隨機性強是這個算法致命的缺點。
體現在:(1)更新順序。節點標簽更新順序隨機,但是很明顯,越重要的節點越早更新會加速收斂過程
(2)隨機選擇。如果一個節點的出現次數最大的鄰居標簽不止一個時,隨機選擇一個標簽作為自己標簽。很明顯,在標簽重復次數相同的情況下,與本節點相似度更高或對本節點影響力越大的鄰居節點的標簽有更大的概率被節點選中
但是這些缺點並沒有妨礙LPA經常作為論文的benchmark對比算法,而且這個思路可以用在機器學習領域
此處應該有一個小案例支撐,先看一個別人有的
這也是篇好文章,偏機器學習 http://blog.csdn.net/u013378306/article/details/52550805
代碼實現:
第一步:先給每個節點分配對應標簽,即節點1對應標簽1,節點i對應標簽i;(有的話直接用,沒有就生成)
第二步:遍歷N個節點(for i=1:N),找到對應節點鄰居,獲取此節點鄰居標簽,找到出現次數最大標簽,若出現次數最多標簽不止一個,則隨機選擇一個標簽替換成此節點標簽;
第三步:若節點標簽不再變化,則迭代停止,否則重復第二步
最下面是做了一個收斂條件,由於存在二部網絡震盪收斂(具體參見上文別人博客介紹),所以本次標簽和上一次標簽有可能永遠不收斂,於是需要再引入一個上上次標簽;
Labelnew是每次更新后的每個節點對應標簽,Label1存儲Labelnew上一次標簽記錄,Label2存儲上上次的標簽記錄。當其中有一對相同的時候,收斂停止
function [ Labelnew ] = LPA( adjacent_matrix,label ) if nargin<2 label = 1:size(adjacent_matrix,2); end N = size(adjacent_matrix,2); Label1 = label; Label2 = Label1; Labelnew = Label1; flag=1; while(1) for i=1:N nb_lables = Labelnew(adjacent_matrix(i,:)==1);%找到鄰居下標對應的標簽 if size(nb_lables,2)>0 x = tabulate(nb_lables); max_nb_labels = x(x(:,2)==max(x(:,2)),1); Labelnew(i) = max_nb_labels(randi(length(max_nb_labels))); end end % 收斂條件,預防跳躍 if all(Labelnew==Label1)||all(Labelnew==Label2) break; else if flag==1 Label1 = Labelnew; flag=0; else Label2 = Labelnew; flag=1; end end end end