Я пытаюсь написать программу, которая найдет MST данного неориентированного взвешенного графа с помощью алгоритмов Крускала и Прима.Я успешно реализовал алгоритм Крускала в программе, но у меня проблемы с Примом.Чтобы быть более точным, я не могу понять, как на самом деле построить функцию Prim, чтобы она перебирала все вершины графа.Я получаю некоторые ошибки IndexOutOfBoundsException во время выполнения программы.Я не уверен, сколько информации нужно, чтобы другие поняли, что я уже сделал, но, надеюсь, не будет слишком много бесполезной информации.
Это то, что я имею до сих пор:
У меня есть класс Graph
, Edge
и Vertex
.
Класс вершин в основном просто хранилище информации, которое содержит имя (число)вершина.
Класс Edge может создать новый Edge с параметрами (Vertex start, Vertex end, int edgeWeight)
.У класса есть методы для возврата обычной информации, такой как начальная вершина, конечная вершина и вес.
Класс Graph считывает данные из текстового файла и добавляет новые Edges в ArrayList.Текстовый файл также сообщает нам, сколько вертеков в графике, и это тоже сохраняется.
В классе Graph
у меня есть метод Prim (), который должен вычислятьMST:
public ArrayList<Edge> Prim(Graph G) {
ArrayList<Edge> edges = G.graph; // Copies the ArrayList with all edges in it.
ArrayList<Edge> MST = new ArrayList<Edge>();
Random rnd = new Random();
Vertex startingVertex = edges.get(rnd.nextInt(G.returnVertexCount())).returnStartingVertex(); // This is just to randomize the starting vertex.
// This is supposed to be the main loop to find the MST, but this is probably horribly wrong..
while (MST.size() < returnVertexCount()) {
Edge e = findClosestNeighbour(startingVertex);
MST.add(e);
visited.add(e.returnStartingVertex());
visited.add(e.returnEndingVertex());
edges.remove(e);
}
return MST;
}
Метод findClosesNeighbour () выглядит следующим образом:
public Edge findClosestNeighbour(Vertex v) {
ArrayList<Edge> neighbours = new ArrayList<Edge>();
ArrayList<Edge> edges = graph;
for (int i = 0; i < edges.size() -1; ++i) {
if (edges.get(i).endPoint() == s.returnVertexID() && !visited(edges.get(i).returnEndingVertex())) {
neighbours.add(edges.get(i));
}
}
return neighbours.get(0); // This is the minimum weight edge in the list.
}
ArrayList<Vertex> visited
и ArrayList<Edges> graph
создаются при создании нового графа.
Visited () -метод - это просто логическая проверка, чтобы увидеть, содержит ли посещаемый ArrayList вершина, в которую мы думаем перейти.Я тестировал findClosestNeighbour()
независимо и он, похоже, работал, но если кто-то обнаружит, что с ним что-то не так, обратная связь также приветствуется.
В основном, как я уже говорил, моя проблема заключается в создании основного цикла вPrim () -метод, и если понадобится какая-либо дополнительная информация, я с радостью ее предоставлю.
Спасибо.
Редактировать: Чтобы уточнить, что мой ход мыслей с Prim ()метод есть.Что я хочу сделать, это сначала рандомизировать начальную точку на графике.После этого я найду ближайшего соседа к этой отправной точке.Затем мы добавим ребро, соединяющее эти две точки с MST, а также добавим вершины в список посещений для последующей проверки, чтобы не образовывать никаких петель на графике.
Вот ошибкакоторое выдается:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at Graph.findClosestNeighbour(graph.java:203)
at Graph.Prim(graph.java:179)
at MST.main(MST.java:49)
Строка 203: return neighbour.get(0);
в findClosestNeighbour ()
Строка 179: Edge e = findClosestNeighbour(startingVertex);
в Prim ()