Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在没有内存溢出的情况下检出图形中的所有周期?_Java_Scala_Graph - Fatal编程技术网

Java 如何在没有内存溢出的情况下检出图形中的所有周期?

Java 如何在没有内存溢出的情况下检出图形中的所有周期?,java,scala,graph,Java,Scala,Graph,相邻列表中的图形示例: > (K01196,List(K00700, K01178, K01187, K00688)) > (K00844,List(K01835, K01810)) > (K00700,List(K00688)) > (K01178,List(K01196, K01187)) > (K00706,List(K00693, K01210, K00963, K00697, K16055)) > (K01810,List(K00844, K0183

相邻列表中的图形示例:

> (K01196,List(K00700, K01178, K01187, K00688))
> (K00844,List(K01835, K01810))
> (K00700,List(K00688))
> (K01178,List(K01196, K01187))
> (K00706,List(K00693, K01210, K00963, K00697, K16055))
> (K01810,List(K00844, K01835))
> (K01193,List(K00844, K01210, K01187))
> (K00693,List(K01196, K00688, K00700))
> (K16055,List(K01194, K00693))
> (K01835,List(K00844, K00688, K01810, K00963))
> (K00963,List(K00688, K16055, K00693, K01835, K00697))
> (K00697,List(K16055, K00693))
> (K01187,List(K01178, K01210, K00844))
第二个例子(容易出现问题):

相邻列表是使用默认值list()生成的。可以使用以下函数加载边,它将返回相邻列表

 def reader_AdjacentList(edgefile: String): Map[String, List[String]] = {
    val sourcefile = Source.fromFile(edgefile)
    val pat = """([A-Z]\w+),([A-Z]\w+)""".r
    sourcefile.getLines.:\(Map[String, List[String]]().withDefaultValue(List()))((line, maps) =>
      pat.findFirstMatchIn(line) match {
        case Some(pat(from, to)) => if (maps.contains(from)) maps.updated(from, maps(from).+:(to).distinct)
        else maps.+((from, List(to)))
        case None => maps
      })
  }
下面的功能是检查给定开始节点和图形的所有循环:

def checkCycles(start: String, maps: Map[String, List[String]]): List[List[String]] = {
  def explore(node: String, visits: List[String]): List[List[String]] = {
    if (visits.contains(node)) List(visits.+:(node))
    else {
      if (maps(node).isEmpty) List()
      else {
        maps(node).flatMap(x => explore(x, visits.+:(node)))
      }
    }
  }
  explore(start, List())
}
为检出所有循环路径而运行的程序如下所示(
adList
是开头相邻列表表示的图形):

此程序适用于其他一些图形示例,例如上面给出的第一个示例,但不适用于第二个示例,它给出了以下错误,尽管eclipse中的堆大小已设置为4G

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

有人知道这个程序出了什么问题,以及如何改进它吗?

在我的计算机上运行完全正常,无需更改堆空间的任何设置。
循环的长度为818。我所做的唯一改变是,现在所有节点都是符号(因为我只是将您的员工复制到我的IDE中,这是使事情正常运行的最快方法),这一点都不重要

更新 由于第二个示例不容易复制和粘贴,我正在生成我自己的更大比例的示例,这是一个随机图,每个节点都有
n
个节点和
k
个边(删除自循环和重复边)


对于
n=50
k=4
,有124693个“周期”(如您所定义)。我还尝试了
n=100
k=10
,似乎要计算的路径太多了,因此程序不会在几分钟内终止,但不会引发内存异常。

在示例映射中,某些节点(如K00688)没有键。。。因此,您可能需要添加
映射。包含(节点)
检查。修复后,代码在我的计算机上完全正常工作,无需更改堆空间的任何设置。它将由默认值列表()处理。我刚刚编辑了这篇文章以包含这些信息。相邻列表是使用默认值生成的。它给出了
java.util.NoSuchElementException:key not found:'K00688
在我的计算机上,而不是在缺少密钥时返回一个空集,这并不奇怪。。。您确定这就是您正在运行的代码吗?相邻的列表是通过折叠并以Map[String,list[String]]()开始创建的。withDefaultValue(list())。您所说的“所有周期”是什么意思?假设我们有一个由10个元素组成的完全连通的网络;那你就有大约10个!循环,这是相当多的。在你可以探索它们之前,很容易创造出足够的周期,不仅超过机器的内存容量,而且超过宇宙的年龄。@QiQi当然,但更好的是,我可以复制和粘贴,让事情顺利进行,而无需做任何其他事情……只需在这个程序上独立运行,与其他部分分离。第一个例子运行良好,@Kane,你是对的。但我将发布另一个容易出现问题的示例。您可以将边缘保存到一个文件中,然后使用我刚刚发布的函数将文件加载到相邻列表的映射中。我很感激你的努力,凯恩,你不必在这上面花太多时间。谢谢。我的计算机运行第二个示例时花了两分钟多的时间,出现了错误。@QiQi您的第二个示例正在运行。。。没有内存异常,但它只是不终止。我添加了一个计数器来动态打印到目前为止找到的路径数,它在几秒钟内增长到数百万条——这只是表明事情正在正常工作。
val cycles = adList.toList.flatMap(pair => checkCycles(pair._1, adList))

cycles.foreach(println)
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
val rand = new java.util.Random
val n = 50
val k = 4
val map = 0 until n map (i => {
  i -> ((0 until k) map (_ => rand.nextInt(n)) filter (_ != i) groupBy(identity) map (_._1) toList)
}) toMap