在我的具體情況下,圖表表示爲鄰接列表,並且是無向和稀疏的,n可以是數百萬,d是3.計算A^d(其中A是鄰接矩陣)並挑選出非零的條目,但我希望不涉及矩陣乘法的東西。在每個頂點上進行廣度優先搜索也是一種選擇,但速度很慢。對於圖中的每個頂點,找出距離內的所有頂點d
回答
假設我們有一個函數verticesWithin(d,x)
,它可以找到頂點x
的距離d
內的所有頂點。
對於像這樣的問題,揭示緩存/記憶機會的一個好策略是提出這樣一個問題:這個問題的子問題如何相互關聯?
在這種情況下,我們可以看到,如果verticesWithin(d,x)
是d >= 1
的vertices(d-1,y[i])
的聯盟範圍內的所有i
,其中y=verticesWithin(1,x)
。如果d == 0
那麼它只是{x}
。 (我假設一個頂點被認爲距離它自己的距離爲0)。
實際上,你會想看看案例d == 1
的鄰接列表,而不是使用該關係來避免無限循環。您還需要避免考慮將x
本身作爲y
的成員。
此外,如果的verticesWithin(d,x)
返回類型是從簡單的列表改變或設置,以代表從x
的距離增加d
集的列表,然後
verticesWithin(d,x) = init(verticesWithin(d+1,x))
其中init
是函數,產率列表中除最後一個之外的所有元素。顯然這是一個非終止遞歸關係,如果字面轉換成代碼,所以你必須對你如何實現它有點聰明。
配備了這些子問題之間的關係,我們現在可以緩存verticesWithin
的結果,並使用這些緩存的結果來避免執行冗餘遍歷(儘管需要執行一些設置操作的代價 - 我不完全確定這是一場勝利)。我將把它作爲練習來填寫實現細節。
您已經提到計算A^d
的選項,但這比您需要的多得多(正如您已經說過的)。
然而,使用這個想法有一個更便宜的方法。假設你有一個(列)矢量v
零和1,表示一組頂點。現在,矢量w := A v
在每個節點上都有一個節點,可以在一個步驟中從起始節點到達該節點。迭代,u := A w
有一個爲每個節點可以從起始節點正好有兩個步驟達到,等等
對於d=3
,你可以做以下(MATLAB僞代碼):
v = j'th unit vector
w = v
for i = (1:d)
v = A*v
w = w + v
end
的矢量w
現在對於每個節點具有肯定條目,可以從最多d
步驟中的j
節點訪問該節點。
我不明白這比矩陣乘法更便宜(時間方面),因爲此過程必須是對於一個單獨的起始頂點,廣度優先搜索是一個更好的選擇,也不需要你的向量'w'。'A^d * v'(反覆計算或其他)零元素作爲'w' – 2011-04-19 22:48:57
你說得對,我以爲你想從一個頂點開始,但是,請不要在這種方法中沒有矩陣矩陣產品,只有矩陣向量產品(它比計算)。 – Martijn 2011-04-20 06:16:49
在這種情況下,從給定頂點開始的寬度第一次搜索是最佳解決方案。你會發現距離d內的所有頂點,而且你甚至不會訪問距離> = d + 2的任何頂點。
這裏是遞歸代碼,儘管如果需要的話,遞歸可以很容易地完成一個隊列。
// Returns a Set
Set<Node> getNodesWithinDist(Node x, int d)
{
Set<Node> s = new HashSet<Node>(); // our return value
if (d == 0) {
s.add(x);
} else {
for (Node y: adjList(x)) {
s.addAll(getNodesWithinDist(y,d-1);
}
}
return s;
}
這是1個起始頂點的最佳解決方案,但問題在於爲每個頂點執行此操作。 – 2011-04-19 20:14:53
@ Robert D.是的,你是對的。我錯過了 - 我的不好! – Josh 2011-04-19 21:28:58
def find_d(graph, start, st, d=0):
if d == 0:
st.add(start)
else:
st.add(start)
for edge in graph[start]:
find_d(graph, edge, st, d-1)
return st
graph = { 1 : [2, 3],
2 : [1, 4, 5, 6],
3 : [1, 4],
4 : [2, 3, 5],
5 : [2, 4, 6],
6 : [2, 5]
}
print find_d(graph, 1, set(), 2)
- 1. 在頂點x的較小或相等距離d內找到頂點數
- 2. 圖 - 找到從所有其他頂點可到達的頂點
- 3. 考慮圖G.頂點8距頂點的距離是多少?7
- 4. 查找哪些點位於每個點的給定距離內
- 5. 算法根據距離源的距離對圖中的頂點進行排序
- 6. 使用igraph查找連接到頂點的所有頂點?
- 7. Gremlin-Traversing查找與特定頂點無關的所有頂點
- 8. U-SQL頂點圖不會顯示每個頂點的ROW_COUNT
- 9. 在圖中找到一組頂點,使每個頂點可以到達其他k個頂點
- 10. 統計圖中的所有頂點
- 11. 在有向圖中找出一個循環中的所有頂點
- 12. 從頂部獲取點擊div距離
- 13. 每個頂點的概率
- 14. OrientDB:查找所有沒有給定類的直接鄰居頂點的頂點
- 15. 從多個頂點的最大距離內提取子圖的高效算法
- 16. 如何使用頂點的測地距離來平滑骨骼頂點權重?
- 17. 查找兩個頂點(節點)之間的所有路徑
- 18. 如何找到最大度數的圖中的所有頂點?
- 19. 的igraph:爲每個頂點中心性措施CSV文件,爲每個頂點
- 20. 在另一個點的距離內查找所有點的算法
- 21. 有向圖中的頂點,使得存在從這個頂點到另一個頂點的路徑
- 22. 刪除頂點和頂點本身的所有邊
- 23. 在時間O(| E | + | V |)中查找從有向圖的頂點可到達的所有頂點
- 24. 使用每個頂點
- 25. 有向圖中從一個頂點到另一個頂點的最短路徑
- 26. 查找圖中的代表頂點
- 27. 查找屬於簡單循環一部分的所有頂點
- 28. 我如何在ThreeJS中每個頂點和每個頂點照明發光?
- 29. 如何在有向圖中找到最小的一組頂點,以便可以達到所有其他頂點
- 30. Neo4j中所有頂點的索引
在圖表執導? – 2011-04-16 08:50:13
閱讀第一句 – 2011-04-16 10:20:35
由於圖表表示爲鄰接表,因此深度優先搜索(最多d = 3)應該可以工作,您不需要在每個頂點上工作,而只需要頂點可訪問 – Wei 2011-04-16 14:14:55