简体   繁体   English

Java中的Dijkstra算法耗尽堆空间?

[英]The Dijkstra algorithm in java running out heap space?

I am trying to do Dijkstra algorithm in java using 25,000 vertices. 我正在尝试使用25,000个顶点在Java中执行Dijkstra算法。 The program worked when I did 1000 vertices but I am trying it again and it fails. 当我做了1000个顶点时,该程序起作用了,但是我又尝试了一次,但是失败了。

What I first was make a 2d array to represent the path from each node to each node and what is stored in this double array is the weight. 我首先要做的是制作一个二维数组来表示从每个节点到每个节点的路径,并且存储在此double数组中的是权重。

However out of memory it say java heap space memory ran out at line 39. 但是内存不足说Java堆空间内存在第39行用完了。

This is what the input is like http://pastebin.com/vwR6Wmrh except there now 25,000 vertices and 57604 edges. 输入就像http://pastebin.com/vwR6Wmrh一样,除了现在有25,000个顶点和57604个边。

The line with a single number is a vertice 具有单个数字的线是一个顶点

the line with two number is which vertice the edge is going to and the weight. 具有两个数字的线是边要到达的顶点和权重。

So weight from node 0 to node 25 is 244. 因此,从节点0到节点25的权重为244。

This is my code 这是我的代码

import java.io.*; //needed for the file class

import java.util.StringTokenizer;
import java.util.Scanner;

public class ShortestPath {

    public static void main(String[] args)
        throws IOException {
        String filename;
        Scanner keyboard = new Scanner(System.in);
        System.out.println("HELLO USER, ENTER THE NAME OF THE FILE YOU WANT TO INPUT");
        filename = keyboard.nextLine();
        FileReader freader = new FileReader(filename);
        BufferedReader inputFile = new BufferedReader(freader);
        String loco = inputFile.readLine();
        System.out.println(loco);
        StringTokenizer pedro = new StringTokenizer(loco, "= m n");
        int N = Integer.parseInt(pedro.nextToken()); //the number of nodes you have in the array
        int inf = 2100000;
        int[][] a = new int[N][N]; //this will hold all vertices going to all edges
        //int[] d = new int[N]; //distance
        //boolean[] kaki = new boolean[N];
        //int[] p = new int[N]; 
        //the sum of all the shortest paths
        int v = 0; //is for vertices
        int x = 0; //is for the edges
        int y = 0;
        //now we initialize the graph the source node is zero the rest of the paths are inf
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (i != j) {
                    a[i][j] = inf;
                } else {
                    a[i][j] = 0;
                }
            }
        }
        //read the first line
        //ok now we are reading the file
        //in the file the first line is the vertex
        //the second is where it is going and the weight of this edge
        //a is the array vertices and edges are stored
        while (loco != null) {
            loco = inputFile.readLine();
            if (loco == null) {
                break;
            }
            StringTokenizer str = new StringTokenizer(loco);
            if (str.countTokens() == 1) {
                x = Integer.parseInt(str.nextToken());
                v = x;
                //System.out.println(v);
            }
            if (str.countTokens() == 2) {
                x = Integer.parseInt(str.nextToken());
                y = Integer.parseInt(str.nextToken());
                //System.out.println( x + " " + y);
                a[v][x] = y;
                a[x][v] = y; //since the graph goes in multiple directions
            }
        }
        inputFile.close();
        System.out.println("-------------");
        //here I have constructed the graph yes
        //these be examples to make sure its working 
        //System.out.println(a[0][25]);
        //System.out.println(a[0][613]);
        //System.out.println(a[613][0]);
        //System.out.println(a[899][903]);
        //System.out.println(a[991][997]);
        inputFile.close();
        Dijaskra(0, a, N);
        //vertex zero is the shortest path
    }
}

Adjacency matrix based representation of graph takes lot of memory (as mentioned here wiki ). 图的基于邻接矩阵的表示占用大量内存(如此处wiki所述 )。 Can you try adjacency list representation of a graph? 您可以尝试图的邻接表表示吗? If you have good RAM capacity, matrix representation should also work. 如果您具有良好的RAM容量,矩阵表示法也应该起作用。 You can try increasing the startup VM arguments. 您可以尝试增加启动VM参数。

You are using an adjacency matrix to store the edges. 您正在使用邻接矩阵来存储边。 This matrix contains an entry even for non-existing edges. 该矩阵甚至包含不存在的边的条目。

If you have 25.000 vertices, the adjacency matrix has 25.000^2 = 625.000.000 entries. 如果您有25.000个顶点,则邻接矩阵具有25.000^2 = 625.000.000条目。 Assuming Java stores these very efficiently, this needs at least 2.500.000.000 , ie ~ 2.32 GibiBytes of Java heap space. 假设Java非常有效地存储它们,则至少需要2.500.000.000 ,即~ 2.32 GibiBytes的Java堆空间。

You might try running your JVM with java -Xmx3g to give it a larger heap size. 您可以尝试使用java -Xmx3g运行JVM,以使其具有更大的堆大小。 This only works on 64-bit Java, of course. 当然,这仅适用于64位Java。

The real solution is, however, to use a more space efficient implementation for edge representation since your graph is clearly sparse (ie has a density of only 0.00018) 但是,真正的解决方案是对边缘表示使用更节省空间的实现 ,因为您的图形明显稀疏 (即, 密度仅为0.00018)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM