Code optimization (Kruskal algorithm)

Task-implementation of the Kruskal algorithm for calculating the minimum total length of tracks in an amusement park. The time limit is 5 seconds.

When testing for 3900 rides, the program takes more than 5 seconds, the whole point, as I understand it, is in the implementation of finding the length of the track (the usual algorithm for finding the distance from point to point). If so, how to optimize the program? There are no other ways, it seems. If this is not the case, then why?

Input - the number of attractions and their coordinates. Output - the minimum total length of roads between them.

Example:

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

Conclusion:

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

    }
}
Author: Kromster, 2018-07-05

2 answers

You have in this part of the program:

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

No less than 7,603,050 edges are created for 3,900 nodes. You are building a fully connected topology.

The task is to find an algorithm for how to discard failed edges in advance. Without specifying the original edges on the graph, this turns out to be a problem of finding the optimal path, as I understand

 0
Author: Serhii Dikobrazko, 2019-10-21 11:51:55

The minimum length of the track network is the Euclidean minimum spanning tree (EMOD). EMOD is a subgraph of the Delaunay triangulation.

The problem is solved as follows: the Delaunay triangulation is constructed, and the EMOD is extracted from it by the Kruskal algorithm. The working time is NlogN. The implementation is difficult for both parts, if you make them really fast.

 0
Author: Stanislav Volodarskiy, 2020-12-02 20:24:40