Оптимизация кода (алгоритм Крускала)

186
23 августа 2018, 04:50

Задание - реализация алгоритма Крускала для вычисления минимальной суммарной длины дорожек в парке аттракционов. Лимит времени - 5 секунд.

При тесте на 3900 аттракционов, программа занимает больше 5 секунд, дело все, как я понял, в реализации нахождения длины дорожки (обычный алгоритм нахождения расстояния от точки до точки). Если это так, то как оптимизировать программу? Других способов, вроде как, нет. Если же это не так, то из-за чего?

Ввод - количество аттракционов и их координаты. Вывод - минимальная суммарная длина дорог между ними.

Пример:

  • 5
  • 26 71
  • 15 89
  • 62 63
  • 78 19
  • 96 23

Вывод:

- 123.23

import java.util.*;
class Node {
    int x, y, z = 0;
    Node parent = this;
}
class Edge implements Comparable<Edge> {
    int first, second;
    double length;
    public int compareTo(Edge arr) {
        if (this.length > arr.length) {
            return 1;
        } else if (this.length == arr.length) {
            return 0;
        } else {
            return -1;
        }
    }
}
public class Kruskal {
    public static double MST(ArrayList<Node> arr, ArrayList<Edge> edges) {
        Collections.sort(edges);
        int i = 0;
        double result = 0;
        while (i <  edges.size()) {
            int x = edges.get(i).first;
            int y = edges.get(i).second;
            Node rX = find(arr.get(x));
            Node rY = find(arr.get(y));
            if (rX != rY) {
                result += edges.get(i).length;
                if (rX.z < rY.z) {
                    rX.parent = rY;
                } else {
                    rY.parent = rX;
                    if (rY.z == rX.z && rX != rY) {
                        rX.z++;
                    }
                }
            }
            i++;
        }
        return result;
    }
    public static Node find(Node x) {
        if (x.parent == x) {
            return x;
        } else {
            return x.parent = find(x.parent);
        }
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int i, j, count = 0;

        ArrayList<Node> result = new ArrayList<>();
        for (i = 0; i < n; i++) {
            result.add(new Node());
            result.get(i).x = in.nextInt();
            result.get(i).y = in.nextInt();
        }
        ArrayList<Edge> edges = new ArrayList<>();
        for (i = 0; i < n; i++) {
            for (j = i + 1; j < n; j++) {
                edges.add(new Edge());
                edges.get(count).first = i;
                edges.get(count).second = j;
                edges.get(count).length = Math.sqrt((result.get(j).x-result.get(i).x)*(result.get(j).x-result.get(i).x)+(result.get(j).y-result.get(i).y)*(result.get(j).y-result.get(i).y));
                count++;
            }
        }
        System.out.printf("%.2f", MST(result, edges));
    }
}
Answer 1

У вас в этой вот части программы

for (i = 0; i < n; i++) {
            for (j = i + 1; j < n; j++) {
                edges.add(new Edge());
                edges.get(count).first = i;
                edges.get(count).second = j;
                edges.get(count).length = Math.sqrt((result.get(j).x-result.get(i).x)*(result.get(j).x-result.get(i).x)+(result.get(j).y-result.get(i).y)*(result.get(j).y-result.get(i).y));
                count++;
            }
        }

Создается не много не мало, а 7 603 050 ребер для 3900 узлов. Вы строите полносвязную топологию. Задача найти алгоритм как отбросить заранее неудачные ребра. Без указания изначальных ребер на графе это получается задача о поиске оптимального пути, как я понимаю

READ ALSO
Регулярное выражение [a-z]+

Регулярное выражение [a-z]+

Почему регулярка [a-z]+ в Idea не ищет букву из диапазона a-z, в то время как на https://regexrru/ нормально находит?

158
Мой Box2D Body падает на немного при создании box2d libgdx

Мой Box2D Body падает на немного при создании box2d libgdx

Я создаю для практики игру арканоидУ меня есть родительский абстрактный класс GameObject для каждого спрайта в игре(Bat, Brick, Ball):

213
Сравнивание двух объектов

Сравнивание двух объектов

Имеется абсолютно рабочий класс с методом в котором сравниваются два объекта

218
Многопоточность в одном методе

Многопоточность в одном методе

Есть метод, который декомпресит файл, но этот процесс довольной долгий (а файлов 130+)Я решил реализовать это многопоточно

172