【alg4-有向圖】單點可達性和多點可達性
阿新 • • 發佈:2020-12-21
有向圖的可達性
單點可達性:給定一幅有向圖和一個起點s,回答“是否存在一條從s到達給定頂點v的有向路徑?”等類似問題。
多點可達性:給定一幅有向圖和頂點集合,回答“是否存在一條從集合中的任意頂點到達給定頂點v的有向路徑?”等類似問題。
我們可以使用深度優先搜尋來解決這類問題。
有向圖可達性API
API | 功能 |
---|---|
DirectedDFS(Digraph G, int s) | 在G中找到從s可達的所有頂點 |
DirectedDFS(Digraph G, Iterable<Integer> sources) | 在G中找到從sources中的所有頂點可達的所有頂點 |
boolean marked(int v) | v是可達的嗎 |
在有向圖中,深度優先搜尋標記由一個集合的頂點可達的所有頂點所需的時間與被標記的所有頂點的出度之和成正比。
程式碼
其中有向圖實現為Digraph。
package section4_2;
import section1_3.Bag;
public class DirectedDFS {
private boolean[] marked;
public DirectedDFS(Digraph G, int s) {
marked = new boolean[G.V()];
dfs(G,s);
}
public DirectedDFS(Digraph G, Iterable<Integer> sources) {
marked = new boolean[G.V()];
for (int s : sources) {
if (!marked[s]) dfs(G,s);
}
}
private void dfs(Digraph G, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
if (! marked[w]) dfs(G,w);
}
}
public boolean marked(int v) {
return marked[v];
}
public static void main(String[] args) {
int[][] data = {
{4,2},
{2,3},
{3,2},
{6,0},
{0,1},
{2,0},
{11,12},
{12,9},
{9,10},
{9,11},
{8,9},
{10,12},
{11,4},
{4,3},
{3,5},
{7,8},
{8,7},
{5,4},
{0,5},
{6,4},
{6,9},
{7,6}
};
int vn = 13;
int en = 22;
Digraph digraph = new Digraph(vn,en,data);
//test case1
Bag<Integer> sources1 = new Bag<>();
sources1.add(1);
DirectedDFS reachable1 = new DirectedDFS(digraph,sources1);
for (int v = 0;v < digraph.V();v++) {
if (reachable1.marked(v)) {
System.out.print(v + " ");
}
}
System.out.println();
//test case2
Bag<Integer> sources2 = new Bag<>();
sources2.add(2);
DirectedDFS reachable2 = new DirectedDFS(digraph,sources2);
for (int v = 0;v < digraph.V();v++) {
if (reachable2.marked(v)) {
System.out.print(v + " ");
}
}
System.out.println();
//test case3
Bag<Integer> sources3 = new Bag<>();
sources3.add(1);
sources3.add(2);
sources3.add(6);
DirectedDFS reachable3 = new DirectedDFS(digraph,sources3);
for (int v = 0;v < digraph.V();v++) {
if (reachable3.marked(v)) {
System.out.print(v + " ");
}
}
System.out.println();
}
}
輸出:
實際應用
標記-清除的垃圾收集
多點可達性的一個重要的實際應用是在典型的記憶體管理系統中。在一幅有向圖中,一個頂點表示一個物件,一條邊則表示一個物件對另一個物件的引用。這個模型很好地表現了執行中地Java程式的記憶體使用狀況。在程式執行的任何時候都有某些物件是可以被直接訪問的,而不能通過這些物件訪問到的所有物件都應該被回收以便釋放記憶體。標記-清除的垃圾回收策略會為每個物件保留一個位做垃圾收集使用。它會週期性地執行一個有向圖可達性演算法來標記所有可以被訪問到的物件,然後清理所有物件,回收沒有被標記的物件,以騰出記憶體供新的物件使用。