我正在尝试使用25,000个顶点在Java中进行Dijkstra算法。当我做了1000个顶点时程序工作但是我再次尝试它并且它失败了。
我首先制作了一个二维数组来表示从每个节点到每个节点的路径,这个双数组中存储的是权重。
但内存不足则表示java堆空间内存已在第39行耗尽。
输入就像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
}
}
答案 0 :(得分:0)
基于邻接矩阵的图表表示需要大量内存(如此处wiki所述)。你能尝试图表的邻接列表表示吗?如果你有很好的RAM容量,矩阵表示也应该有效。您可以尝试增加启动VM参数。
答案 1 :(得分:0)
您正在使用邻接矩阵来存储边缘。即使对于不存在的边,该矩阵也包含一个条目。
如果您有25.000
个顶点,则邻接矩阵有25.000^2 = 625.000.000
个条目。假设Java非常有效地存储这些,这至少需要2.500.000.000
,即Java堆空间的~ 2.32 GibiBytes
。
您可以尝试使用java -Xmx3g
运行JVM以使其具有更大的堆大小。当然,这仅适用于64位Java。
然而,真正的解决方案是使用more space efficient implementation进行边缘表示,因为您的图形显然是稀疏(即density只有0.00018)