当前位置: 代码迷 >> java >> Java中的Dijkstra算法耗尽堆空间?
  详细解决方案

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

热度:87   发布时间:2023-07-31 11:28:57.0

我正在尝试使用25,000个顶点在Java中执行Dijkstra算法。 当我做了1000个顶点时,该程序起作用了,但是我又尝试了一次,但是失败了。

我首先要做的是制作一个二维数组来表示从每个节点到每个节点的路径,并且存储在此double数组中的是权重。

但是内存不足说Java堆空间内存在第39行用完了。

输入就像一样,除了现在有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
    }
}

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

您正在使用邻接矩阵来存储边。 该矩阵甚至包含不存在的边的条目。

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

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

但是,真正的解决方案是对边缘表示使用 ,因为您的图形明显稀疏 (即, 仅为0.00018)

  相关解决方案