回答
在有向圖,假設你是從u增加一個邊緣到v:
你必須檢查是否V和U已經連接。您可以使用BFS或DFS來做到這一點。
如果您確定存在從v到u的連接,則從u到v添加邊將導致一個循環。
對於演示,我已經從互聯網上實現了一個圖形,並添加了路徑是否存在從v到u的邏輯。以下代碼中的邏輯功能爲doesPathExistBetween(V from, V to)
。
package java8new;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
public class Digraph<V> {
public static class Edge<V> {
private V vertex;
private int cost;
public Edge(V v, int c) {
vertex = v;
cost = c;
}
public V getVertex() {
return vertex;
}
public int getCost() {
return cost;
}
@Override
public String toString() {
return "Edge [vertex=" + vertex + ", cost=" + cost + "]";
}
}
/**
* A Map is used to map each vertex to its list of adjacent vertices.
*/
private Map<V, List<Edge<V>>> neighbors = new HashMap<V, List<Edge<V>>>();
/**
* String representation of graph.
*/
public String toString() {
StringBuffer s = new StringBuffer();
for (V v : neighbors.keySet())
s.append("\n " + v + " -> " + neighbors.get(v));
return s.toString();
}
/**
* Add a vertex to the graph. Nothing happens if vertex is already in graph.
*/
public void add(V vertex) {
if (neighbors.containsKey(vertex))
return;
neighbors.put(vertex, new ArrayList<Edge<V>>());
}
/**
* Add an edge to the graph; if either vertex does not exist, it's added.
* This implementation allows the creation of multi-edges and self-loops.
*/
public void add(V from, V to, int cost) {
this.add(from);
this.add(to);
neighbors.get(from).add(new Edge<V>(to, cost));
}
public List<V> outboundNeighbors(V vertex) {
List<V> list = new ArrayList<V>();
for (Edge<V> e : neighbors.get(vertex))
list.add(e.vertex);
return list;
}
public void bfs(V root) {
// Since queue is a interface
Queue<V> queue = new LinkedList<V>();
Map<V, Boolean> visited = new HashMap<V, Boolean>();
if (root == null)
return;
visited.put(root, Boolean.TRUE);
// Adds to end of queue
queue.add(root);
while (!queue.isEmpty()) {
// removes from front of queue
V r = queue.remove();
System.out.println(r.toString());
// Visit child first before grandchild
for (V n : outboundNeighbors(r)) {
if (!visited.containsKey(n)) {
queue.add(n);
visited.put(n, Boolean.TRUE);
}
}
}
}
public Boolean doesPathExistBetween(V from, V to) {
Queue<V> queue = new LinkedList<V>();
Map<V, Boolean> visited = new HashMap<V, Boolean>();
visited.put(from, Boolean.TRUE);
// Adds to end of queue
queue.add(from);
while (!queue.isEmpty()) {
// removes from front of queue
V r = queue.remove();
// Visit child first before grandchild
for (V n : outboundNeighbors(r)) {
if (!visited.containsKey(n)) {
if (n.equals(to))
return Boolean.TRUE;
queue.add(n);
visited.put(n, Boolean.TRUE);
}
}
}
return Boolean.FALSE;
}
public static void main(String[] args) throws IOException {
Digraph<Integer> graph = new Digraph<Integer>();
// Adding vertices
graph.add(0);
graph.add(1);
graph.add(2);
graph.add(3);
// Adding Edges with weights
graph.add(0, 1, 1);
graph.add(1, 2, 2);
graph.add(3, 0, 2);
System.out.println("Path betwen 0 to 2 exists : " + graph.doesPathExistBetween(0, 2));
System.out.println("Path betwen 1 to 3 exists : " + graph.doesPathExistBetween(1, 3));
graph.bfs(0);
graph.bfs(1);
}
}
如果連接指的是同一個組件,那麼假設圖是1-> 2-> 3,2-> 4,那麼按照您的算法添加4-> 3將導致循環,這是不正確的。 –
不,您會檢查是否存在4到2之間的路徑。如果沒有,那麼您將繼續並添加2-> 4。 –
查找是否有從4到2的路徑的邏輯可以使用BFS或DFS –
的簡單算法,然後會像:
- 遍歷圖形(BFS將做的工作)
- 在探索的節點,標誌着它像「好吧,我去過那裏」。你可以使用一些HashSet來做到這一點。
- 如果節點已經在一個集合中,那麼你第二次來到它,所以有一個循環 - 你可以安全地返回'這個圖形有一個循環'的答案。
現在給出一個狀態爲X(當前狀態)的圖沒有循環,它們在頂點A→B之間添加一個新的邊時可以創建一個新的循環。但在這種情況下,A將永遠是這種循環的一部分。因此重新開始A遍歷是有意義的。根據圖的大小和性質,您可以更快地找到它。
希望這有助於
算法對於這個問題仍是一個研究課題,但對於許多實際情況下,它有很大幫助你添加邊維持支配樹的圖(https://en.wikipedia.org/wiki/Dominator_(graph_theory))。
維護統治者樹可以完成每個添加操作的分期O(log(V + E))時間,或者可能更好一點。
當你添加一條邊時,你仍然需要做一個DFS或BFS,但是由於一個循環中的所有頂點都經過了同一個直接控制器,所以你只需要搜索那些將是同一個父代子代的頂點,父母本身,在支配樹中檢測該週期。
如果在構建圖形時不允許循環,則可能會有很多支配點,並且您必須搜索每個邊緣插入的節點數量很小。
- 1. 檢測圖像中的U形邊緣
- 2. 如何增加canny filtrer檢測到的邊緣的連續性
- 3. 檢測邊緣是否是在一個週期內最重的邊緣
- 4. MATLAB中的輪廓線邊緣檢測
- 5. 邊緣檢測後的形狀識別
- 6. 如何測量邊緣檢測圖像邊緣的長度?
- 7. OpenCV中的邊緣檢測
- 8. C#中的邊緣檢測
- 9. C++中的圖像邊緣檢測
- 10. 檢測圖像中的邊緣
- 11. 檢測圖中的相互邊緣
- 12. 圖像處理中的邊緣檢測
- 13. 圖像邊緣檢測
- 14. 檢測彩色圖像中的水平圓形邊緣
- 15. 圖像邊緣/形狀檢測在OpenCV中
- 16. 使用Python檢測圖像中激光/光線的邊緣
- 17. 如何在d3圖形中添加圖像到邊緣?
- 18. 在圖中檢測週期的條件
- 19. Canny邊緣檢測器檢測到所述圖像的邊界
- 20. 用於檢測不連續圖中的週期的最佳並行算法
- 21. 檢測週期在圖
- 22. 在iPhoneSDK中檢測文檔的邊緣
- 23. SQLITE邊緣檢測
- 24. VHDL邊緣檢測
- 25. Canny邊緣檢測
- 26. qTip2邊緣檢測
- 27. 從邊緣檢測中分割圖像
- 28. 線條和邊緣檢測器,opencv
- 29. 檢測邊緣(連接的邊緣)並查找邊緣長度和連接的組件回轉半徑
- 30. 執行Canny邊緣檢測兩次 - >更好的線檢測?
圖是否定向/無向? –
是足以檢測到圖形有一個循環(布爾答案)或包含循環的邊緣也應該找到(如A→B→C→A)? –
你需要什麼?您的具體問題很可能比這個一般的問題更容易。 –