簡介
對於影響力最大化問題,我以前寫過兩個blog
影響力最大化 IC模型+貪心算法
影響力最大化 模擬爆發(粗糙筆記)
但是,對於這兩個方法都不是最優的:
- 對於IC模型
模型使用了貪心算法,然後遍歷激活結點,每一次遍歷將可能被激活的結點按照概率激活。然後選擇影響力最大的組合。
對於我測試使用的鄰接矩陣的大小是200*200的,也就是200個點的圖,選出影響力最大的五個點的時間是13s左右。準確率比較高。
- 對於模擬爆發
模擬爆發只要設置足夠多的模擬爆發次數就幾乎可以得到最準確的影響力最大的五個點,但是缺點就是性能太差了,在實際的應用中根本不可能使用。
表現:
這個時間根本沒法看。
廢話不多說,IMRank絕對是我見過的影響力最大問題的最好方法,當然如果有更好的大家一定留言發我。這是我看到的一篇論文,本身沒有代碼,所以就自己實現了。可以說比 IC加貪心這個方法快了幾百倍。
IMRank (邊緣爆破)
IMRank,我乾脆起箇中文名字,叫邊緣爆破,但是我還真不知道專業的怎麼叫。我也沒考證,管他呢,就這麼叫了,什麼是邊緣爆破呢。
算法思路
這裏我只說我自己的理解,借用論文中的一副圖:
上圖中的下角標是代表的當前的根據M的排名順序,這個順序是在不斷地迭代中優化的。
實線表示存在傳播概率,或者說傳播概率不爲零。
首先,總述一下算法,大致就是說,會爲整個圖的每一個結點得到一個M(邊際影響力),然後根據邊際影響力對所有點進行排序。通過不斷優化這個排序,最終得到的排序順序就是影響力最大的點的順序,那麼在我們一開始的要求下就只需要去除前五個點就可以了。
那麼計算M其實是一個倒敘的方法,也就是從後往前推導,上圖中的虛線表示掃描節點時傳遞影響分數的邊緣。我們可以看到首先只有存在傳播概率的(也就是圖中存在實現的)才能存在邊際影響力傳遞。但是v2和v3之間沒有是因爲2<3,所以不能傳遞。
定義M的計算公式:
優化迭代:
r表示根據M的排序,後面的實現中我用list存儲。
效率分析
我們想一下爲什麼他這麼快:
- 最重要的,只需要遍歷一遍,這是我認爲時間短的最重要的原因。
- 然後我覺得使用了動態規劃的思想,每個結點存儲的M是可以存儲非鄰居節點傳過來的影響力的,這樣大大減少了運算。
- 充分利用節點的等級與其基於等級的邊際影響力擴散之間的相互作用,該框架有效地將任何初始等級調整爲迭代式的自洽等級
- 論文評價:其可擴展性優於最新的啓發式算法,同時其準確性可與貪婪算法相媲美
代碼實現
import operator
import numpy as np
import copy
import time
data = np.loadtxt('graph.txt')
data = list(data)
def LFA(matrix):
n = len(matrix)
Mr = [1 for i in range(n)]
for i_ in range(1, n):
i = n - i_
for j in range(0, i + 1):
Mr[j] = Mr[j] + matrix[j][i] * Mr[i]
Mr[i] = (1 - matrix[j][i]) * Mr[i]
return Mr
def IMRank(matrix):
start = time.clock()
t = 0
r0 = [i for i in range(len(matrix))]
r = [0 for i in range(len(matrix))]
while(True):
t = t + 1
r = LFA(matrix)
r = np.argsort(-np.array(r))
if operator.eq(list(r0), list(r)):
break
r0 = copy.copy(r)
print('運行時間 : {}'.format(time.clock() - start))
print(r)
IMRank(data)
結果
可見,速度、正確性沒得說。
大家共勉~~