Алгоритм Каргера

Я пытаюсь реализовать алгоритм минимального разреза Каргера на Java. Для этого я создал класс Graph, в котором хранится SortedMap с целочисленным индексом в качестве ключа и объектом Vertex в качестве значения, а также ArrayList объектов Edge. Edges хранит индекс своих инцидентных вершин. Затем я объединяю вершины некоторого случайного ребра, пока количество вершин не достигнет 2. Я повторяю эти шаги безопасное количество раз. Любопытно, что в моем выводе я получаю в 2 раза больше пересекающихся ребер. Я имею в виду, что если правильный ответ равен 10, после выполнения алгоритма n раз (для n достаточно больших) минимальный результат выполнения равен 20, что заставляет меня поверить, что реализация почти правильная. Это соответствующая часть кода:

    void mergeVertex(int iV, int iW) {

    for (int i = 0; i < edges.size(); i++) {
        Edge e = edges.get(i);
        if (e.contains(iW)) {
            if (e.contains(iV)) {
                edges.remove(i);
                i--;
            } else {
                e.replace(iW, iV);
            }
        }
    }

    vertices.remove(iW);
}

public int kargerContraction(){

    Graph copy = new Graph(this);
    Random r = new Random();
    while(copy.getVertices().size() > 2){
        int i = r.nextInt(copy.getEdges().size());
        Edge e = copy.getEdges().get(i);
        copy.mergeVertex(e.getVertices()[0], e.getVertices()[1]);
    }

    return copy.getEdges().size()/2;
}

person Giovanni Oliveira    schedule 08.08.2015    source источник
comment
Ваш код выглядит нормально, за исключением необъяснимого деления на 2. Имейте в виду, что алгоритм Каргера имеет низкую вероятность успеха, поэтому вам придется вызывать его несколько раз, чтобы быть уверенным в нахождении минимального количества порезы.   -  person r3mainer    schedule 09.08.2015
comment
Это то, что я пытаюсь выяснить. Без этого деления возвращаемое значение в 2 раза больше правильного ответа и, что любопытно, всегда четно. Я выполняю метод большое количество раз в зависимости от количества вершин, и я совершенно уверен, что алгоритм выполнялся достаточное количество раз, чтобы найти minCut.   -  person Giovanni Oliveira    schedule 10.08.2015
comment
Возможно, используемый вами объект Graph предназначен для ориентированных графов? Попробуйте запустить свой код с более простыми тестовыми данными. Например, дерево, у которого minCut должен быть равен 1.   -  person r3mainer    schedule 10.08.2015
comment
Получил ошибку. Спасибо за твою заботу.   -  person Giovanni Oliveira    schedule 11.08.2015


Ответы (1)


На самом деле проблема оказалась намного проще, чем я думал. При чтении .txt, который содержит данные графика, я дважды считал каждое ребро, поэтому логически возвращаемый minCut был в 2 раза больше правильного minCut.

person Giovanni Oliveira    schedule 11.08.2015