обнаружение цикла в неориентированном графе с использованием непересекающихся множеств?

Я реализую код для обнаружения цикла в неориентированном графе, используя методы поиска/объединения непересекающихся множеств.

Вот реализация:

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;
}

а вот и isConnected из disjoinset

public boolean isConnected(int i, int j){
    return find(i)==find(j);
}

если два узла имеют один и тот же корень (возвращенный find), это указывает на наличие цикла. Для такого графика, в котором нет циклов (1,2),(2,3),(3,4), мой метод возвращает 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;
}

я получаю node:java.util.NoSuchElementException


person brain storm    schedule 02.12.2013    source источник


Ответы (1)


Вы повторяете каждое ребро дважды, по одному разу с каждой стороны. Вам нужно рассмотреть любое ребро только один раз.

person user2357112 supports Monica    schedule 02.12.2013
comment
будет ли это иметь какое-либо значение для обнаружения цикла? - person brain storm; 03.12.2013
comment
@ user1988876: Да. Если вы повторяете каждое ребро дважды, вы в основном смотрите на граф так, как если бы все ребра были двумя ребрами. В удвоенном графе любое ребро и его двойник образуют цикл. - person user2357112 supports Monica; 03.12.2013
comment
Я рассматриваю для каждой вершины ее соседей... Должен ли я отмечать посещенные узлы? насколько я понимаю, непересекающийся подход не должен отслеживать посещенные узлы. но могу ошибаться.. - person brain storm; 03.12.2013
comment
@ user1988876: Нет. Отметка посещенных узлов не поможет. Этот алгоритм основан на ребрах, а не на вершинах. Если ваше представление графа не позволяет легко перебирать ребра, вы можете попробовать отслеживать, какие ребра вы посетили, и игнорировать любое ребро при втором посещении. - person user2357112 supports Monica; 03.12.2013
comment
Теперь я включил поле для отслеживания посещенных ребер, код обновлен в приведенном выше редактировании, но теперь я получаю node:java.util.NoSuchElementException - person brain storm; 03.12.2013
comment
@ user1988876: Вы звоните e.next() дважды. Просто для каждого по краям вместо использования явного итератора. Кроме того, похоже, что вы используете отдельные граничные объекты для представления края с каждой стороны, поэтому маркировка краев, посещенных полем в краевом объекте, вероятно, не будет работать. - person user2357112 supports Monica; 03.12.2013
comment
давайте продолжим это обсуждение в чате - person brain storm; 03.12.2013