[英]Find all cycles in undirected graph
我正在使用算法第4版来稍微改进我的图论。 这些书附带了大量的图形处理代码。
目前,我遇到了以下问题:如何在无向图中找到所有周期? 我想修改现有的循环检测代码来做到这一点。
这是重要的部分:
private void dfs(Graph G, int u, int v) {
marked[v] = true;
for (int w : G.adj(v)) {
// short circuit if cycle already found
if (cycle != null) return;
if (!marked[w]) {
edgeTo[w] = v;
dfs(G, v, w);
}
// check for cycle (but disregard reverse of edge leading to v)
else if (w != u) {
cycle = new Stack<Integer>();
for (int x = v; x != w; x = edgeTo[x]) {
cycle.push(x);
}
cycle.push(w);
cycle.push(v);
}
}
}
现在,如果我要找到所有循环,我应该删除在找到循环时返回的行,并且每次创建一个循环时我都会存储它。 我无法弄清楚的部分是:算法什么时候停止? 我怎么能确定我找到了所有周期?
以上代码甚至可以通过某种方式修改,以便我找到所有循环?
/**
* In this program we create a list of edges which is an ordered pair of two
* integers representing two vertices.
*
* We iterate through each edge and apply Union Find algorithm to detect
* cycle.
*
* This is a tested code and gives correct result for all inputs.
*/
package com.divyanshu.ds.disjointSet;
import java.util.HashMap;
/**
* @author Divyanshu
* DisjointSet is a data structure with three operations :
* makeSet, union and findSet
*
* Algorithms Used : Union by rank and path compression for detecting cycles
* in an undirected graph.
*/
public class DisjontSet {
HashMap<Long, Node> map = new HashMap<>();
class Node {
long data;
Node parent;
int rank;
}
public void makeSet(long data) {
Node node = new Node();
node.data = data;
node.parent = node;
node.rank = 0;
map.put(data, node);
}
public void union(long firstSet,
long secondSet) {
Node firstNode = map.get(firstSet);
Node secondNode = map.get(secondSet);
Node firstParent = findSet(firstNode);
Node secondParent = findSet(secondNode);
if (firstParent.data == secondParent.data) {
return;
}
if (firstParent.rank >= secondParent.rank) {
firstParent.rank = (firstParent.rank == secondParent.rank) ? firstParent.rank + 1 : firstParent.rank;
secondParent.parent = firstParent;
} else {
firstParent.parent = secondParent;
}
}
public long findSet(long data) {
return findSet(map.get(data)).data;
}
private Node findSet(Node node) {
if (node.parent == node) {
return node;
}
node.parent = findSet(node.parent);
return node.parent;
}
}
=============================================================================
package com.divyanshu.ds.client;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import com.divyanshu.ds.disjointSet.DisjontSet;
import com.divyanshu.ds.disjointSet.Edge;
public class DisjointSetClient {
public static void main(String[] args) {
int edgeCount = 4;
int vertexCount = 12;
List<Edge> graph = generateGraph(edgeCount, vertexCount);
System.out.println("Generated Graph : ");
System.out.println(graph);
DisjontSet disjontSet = getDisjointSet(graph);
Boolean isGraphCyclic = isGraphCyclic(graph, disjontSet);
System.out.println("Graph contains cycle : " + isGraphCyclic);
}
private static Boolean isGraphCyclic(List<Edge> graph,
DisjontSet disjontSet) {
Boolean isGraphCyclic = false;
for (Edge edge : graph) {
if (edge.getFirstVertex() != edge.getSecondVertex()) {
Long first = disjontSet.findSet(edge.getFirstVertex());
Long second = disjontSet.findSet(edge.getSecondVertex());
if (first.equals(second)) {
isGraphCyclic = true;
break;
} else {
disjontSet.union(first, second);
}
}
}
return isGraphCyclic;
}
private static DisjontSet getDisjointSet(List<Edge> graph) {
DisjontSet disjontSet = new DisjontSet();
for (Edge edge : graph) {
disjontSet.makeSet(edge.getFirstVertex());
disjontSet.makeSet(edge.getSecondVertex());
}
return disjontSet;
}
private static List<Edge> generateGraph(int edgeCount,
int vertexCount) {
List<Edge> graph = new ArrayList<>();
HashSet<Edge> edgeSet = new HashSet<>();
Random random = new Random();
for (int j = 0; j < vertexCount; j++) {
int first = random.nextInt(edgeCount);
int second = random.nextInt(edgeCount);
if (first != second) {
edgeSet.add(new Edge(first, second));
} else {
j--;
}
}
for (Edge edge : edgeSet) {
graph.add(edge);
}
return graph;
}
}
===================================================================
/**
*
*/
package com.divyanshu.ds.disjointSet;
/**
* @author Divyanshu
*
*/
public class Edge {
private long firstVertex;
private long secondVertex;
public Edge(long firstVertex,
long secondVertex) {
this.firstVertex = firstVertex;
this.secondVertex = secondVertex;
}
public long getFirstVertex() {
return firstVertex;
}
public void setFirstVertex(long firstVertex) {
this.firstVertex = firstVertex;
}
public long getSecondVertex() {
return secondVertex;
}
public void setSecondVertex(long secondVertex) {
this.secondVertex = secondVertex;
}
@Override
public String toString() {
return "(" + firstVertex + "," + secondVertex + ")";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (firstVertex ^ (firstVertex >>> 32));
result = prime * result + (int) (secondVertex ^ (secondVertex >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Edge other = (Edge) obj;
if (firstVertex != other.firstVertex)
return false;
if (secondVertex != other.secondVertex)
return false;
return true;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.