【问题标题】:The Dijkstra algorithm in java running out heap space?java中的Dijkstra算法耗尽堆空间?
【发布时间】:2015-07-18 05:33:41
【问题描述】:

我正在尝试使用 25,000 个顶点在 java 中执行 Dijkstra 算法。该程序在我做 1000 个顶点时运行,但我再次尝试它并失败了。

我首先是制作一个二维数组来表示从每个节点到每个节点的路径,这个双数组中存储的是权重。

但是在第 39 行它说 java 堆空间内存用完了。

这就是输入 http://pastebin.com/vwR6Wmrh 的样子,除了现在有 25,000 个顶点和 57604 条边。

只有一个数字的线是一个顶点

有两个数字的线是边要到达的顶点和权重。

所以从节点 0 到节点 25 的权重是 244。

这是我的代码

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

【问题讨论】:

  • 为什么会有两个inputFile.close();
  • 第 39 行是哪一行?
  • 您可以随时increase the heap space
  • 哦,是的,这是第 39 行 int[][] a =new int[N][N];
  • @rakeb.void 哦,对不起,我认为这是我犯的错误,我只打开了一个文件。

标签: java graph-algorithm


【解决方案1】:

您正在使用邻接矩阵来存储边。即使对于不存在的边,该矩阵也包含一个条目。

如果您有25.000 顶点,则邻接矩阵有25.000^2 = 625.000.000 条目。假设 Java 非常有效地存储这些,这至少需要2.500.000.000,即~ 2.32 GibiBytes 的 Java 堆空间。

您可以尝试使用java -Xmx3g 运行您的JVM,以使其拥有更大的堆大小。当然,这只适用于 64 位 Java。

然而,真正的解决方案是使用more space efficient implementation 进行边表示,因为您的图显然是稀疏(即density 只有0.00018)

【讨论】:

    【解决方案2】:

    基于邻接矩阵的图形表示会占用大量内存(如wiki 所述)。您可以尝试图形的邻接表表示吗?如果您有良好的 RAM 容量,矩阵表示也应该可以工作。您可以尝试增加启动 VM 参数。

    【讨论】:

      猜你喜欢
      • 2017-09-16
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      • 2011-05-28
      • 2021-09-21
      • 1970-01-01
      相关资源
      最近更新 更多