Java 使用不相交集的无向图的圈检测?

Java 使用不相交集的无向图的圈检测?,java,algorithm,graph,cycle,disjoint-sets,Java,Algorithm,Graph,Cycle,Disjoint Sets,我正在使用不相交集的find/union方法实现无向图中循环检测的代码 以下是实施方案: public boolean isCyclicundirected(){ int k; ArrayDisjointSet set = new ArrayDisjointSet(5); //Set<Vertex> parents = new HashSet<Vertex>(); System.out.println(vertexMap); Set

我正在使用不相交集的find/union方法实现无向图中循环检测的代码

以下是实施方案:

public boolean isCyclicundirected(){
    int k;
    ArrayDisjointSet set = new ArrayDisjointSet(5);
    //Set<Vertex> parents = new HashSet<Vertex>();
    System.out.println(vertexMap);
    Set<String> allVertices = vertexMap.keySet();
    for (String v : allVertices){
        Iterator<Edge> e = vertexMap.get(v).adj.iterator();
        while (e.hasNext()){
            int i = Integer.parseInt(vertexMap.get(v).name);
            int j = Integer.parseInt(e.next().target.name);
            if (set.isConnected(i, j))
                return true;
            else
                   k = set.join(i, j);
            System.out.println(set);
    }
    }
    return false;
}
如果两个节点具有相同的根(由
find
返回),则表示存在循环。 对于这样一个没有圈的图,我的方法返回true。 我不明白出了什么问题

编辑最新版本:在以下建议之后:

public boolean isCyclicundirected() {
    int k;
    HashSet<HashSet<Vertex>> vertexpairs = new HashSet<HashSet<Vertex>>();
    ArrayDisjointSet set = new ArrayDisjointSet(100);
    Set<String> allVertices = vertexMap.keySet();
    for (String v : allVertices) {
        Vertex current = vertexMap.get(v);
        for (Edge e : current.adj){
            Vertex nextVertex = e.target;
            HashSet<Vertex> temp = new HashSet<Vertex>();
            temp.add(nextVertex);
            temp.add(current);

            if (!vertexpairs.contains(temp)) {
                vertexpairs.add(temp);
                int i = Integer.parseInt(current.name);
                int j = Integer.parseInt(nextVertex.name);
                if (set.isConnected(i, j))
                    return true;
                else
                    k = set.join(i, j);
                System.out.println(set);
            }
        }
    }
    return false;
}
public boolean isCyclicundirected(){
int k;
HashSet vertexpairs=新HashSet();
ArrayDisjointSet=新的ArrayDisjointSet(100);
设置AllVertexts=vertexMap.keySet();
对于(字符串v:所有顶点){
顶点当前=顶点映射。获取(v);
用于(边e:当前调整){
顶点nextVertex=e.目标;
HashSet temp=新HashSet();
温度添加(下一个特级);
温度添加(当前);
如果(!vertexpairs.contains(temp)){
垂直扩展添加(温度);
int i=Integer.parseInt(current.name);
int j=Integer.parseInt(nextVertex.name);
如果(设置断开连接(i,j))
返回true;
其他的
k=集合连接(i,j);
系统输出打印项次(套);
}
}
}
返回false;
}

我得到
节点:java.util.NoSuchElementException

您在每条边上迭代两次,每边迭代一次。你只需要考虑任何一次边缘。

这对循环检测有什么影响吗?@如果你在每一条边上迭代两次,你基本上是在看图,好像所有的边都是两条边。在双图中,任何边和它的双圈形成一个循环。我考虑每个顶点,它的邻居。我必须标记访问的节点吗?据我所知,disjointset方法不必跟踪访问的节点。但是我可能完全错了。@user1988876:不。标记已访问的节点不会有帮助。该算法基本上是关于边的,而不是顶点。如果您的图形表示不便于在边上进行迭代,您可以尝试跟踪您访问过的边,并在第二次访问时忽略任何边。我现在包括了一个字段来跟踪访问过的边,代码在上面的编辑中更新,但现在我得到了
节点:java.util.NoSuchElementException
public boolean isCyclicundirected() {
    int k;
    HashSet<HashSet<Vertex>> vertexpairs = new HashSet<HashSet<Vertex>>();
    ArrayDisjointSet set = new ArrayDisjointSet(100);
    Set<String> allVertices = vertexMap.keySet();
    for (String v : allVertices) {
        Vertex current = vertexMap.get(v);
        for (Edge e : current.adj){
            Vertex nextVertex = e.target;
            HashSet<Vertex> temp = new HashSet<Vertex>();
            temp.add(nextVertex);
            temp.add(current);

            if (!vertexpairs.contains(temp)) {
                vertexpairs.add(temp);
                int i = Integer.parseInt(current.name);
                int j = Integer.parseInt(nextVertex.name);
                if (set.isConnected(i, j))
                    return true;
                else
                    k = set.join(i, j);
                System.out.println(set);
            }
        }
    }
    return false;
}