邻接列表创建,内存错误

时间:2010-04-19 03:49:24

标签: java heap data-structures adjacency-list

我正在尝试创建一个邻接列表来存储图形。实现在存储100,000条记录时工作正常。但是,当我试图存储大约100万条记录时 我遇到了OutofMemory错误:

线程“main”中的异常java.lang.OutOfMemoryError:Java堆空间         at java.util.Arrays.copyOfRange(Arrays.java:3209)         在java.lang.String。(String.java:215)         在java.io.BufferedReader.readLine(BufferedReader.java:331)         在java.io.BufferedReader.readLine(BufferedReader.java:362)         在liarliar.main(liarliar.java:39)

以下是我的实施

HashMap<String,ArrayList<String>> adj = new HashMap<String,ArrayList<String>>(num);


        while ((str = in.readLine()) != null)
        {

            StringTokenizer Tok = new StringTokenizer(str);
            name = (String) Tok.nextElement();
            cnt = Integer.valueOf(Tok.nextToken());
            ArrayList<String> templist = new ArrayList<String>(cnt);

            while(cnt>0)
             {
                    templist.add(in.readLine());
                    cnt--;
             }
            adj.put(name,templist);

        } //done creating a adjacency list

我想知道,如果有更好的方法来实现邻接列表。此外,我知道开始时的节点数量,并且在将来我访问节点时将列表展平。有什么建议吗?

由于

2 个答案:

答案 0 :(得分:1)

我似乎在这里有不公平的优势,因为我认识到问题的名称(liarliar)和输入的确切性质。

我可以告诉你,这个OutOfMemoryError是设计的。您需要找到一个更好的算法,它不会将图形的整个邻接信息存储在内存中。

我将避免提供过多的算法洞察力,但我可以告诉你,你需要坐下来思考,而不是在这个阶段进行编程。也许读一本关于算法和数据结构的好书。


您现在正在做的是,您实际上将输入文件中的字符串存储在HashMap<String,ArrayList<String>>中。考虑到问题的本质,这是非常低效的。

如果您使用java.util.Scanner,则更容易,效率更高。 <{1}}和new Scanner(new File(inputFilename))以及next()就是您所需要的一切。

为每个名称指定一个唯一的nextInt()(提示:int),然后存储更小的Map<String, Integer>

答案 1 :(得分:0)

感谢您回答我的问题。是的,你猜对了,代码是关于什么的。

我想是的,使用字符串到整数的映射会为邻居列表节省一些空间请求。从这个意义上讲,可以消除上述错误。

但是,我使用了java -jar -Xmx1024M。这提供了一种使用更多堆内存来运行程序的方法,并且因为它允许在给定的prolem中使用它,所以这不是我提交失败的原因。

虽然我不确定,性能可能是机器人失败的原因之一。

关于您的解决方案,

如果我创建一个Map,然后将数字存储在adjacencey列表中,它将为我节省一些空间,但每次我需要在bfs / dfs遍历期间访问节点时,它还会添加额外的查找。这困扰我。你是说我不应该创建邻接列表吗?我明白你要说的正确吗?

感谢。