Algorithm 烫伤:如何减少列表中的内存计算?

Algorithm 烫伤:如何减少列表中的内存计算?,algorithm,scala,hadoop,scalding,Algorithm,Scala,Hadoop,Scalding,我用滚烫法试图找到相似字符串对之间的编辑距离。总之,我在一个CSV文件中有10000个字符串。为了减少计算量,我使用以下算法: 使用前三个字符作为键将所有字符串分组 在每个组中生成两个字符串的组合 查找每组中每对字符串的编辑距离请参见下面的代码 当我在HDFS上运行这个算法时,它可以处理1000000个字符串。有10000个字符串,节点管理器抱怨我的“映射”作业试图分配比节点更多的物理内存。我知道当在.groupBy'key{{uu.mapList…}代码中创建大量组合时,就会出现这种情况。当然

我用滚烫法试图找到相似字符串对之间的编辑距离。总之,我在一个CSV文件中有10000个字符串。为了减少计算量,我使用以下算法:

使用前三个字符作为键将所有字符串分组 在每个组中生成两个字符串的组合 查找每组中每对字符串的编辑距离请参见下面的代码 当我在HDFS上运行这个算法时,它可以处理1000000个字符串。有10000个字符串,节点管理器抱怨我的“映射”作业试图分配比节点更多的物理内存。我知道当在.groupBy'key{{uu.mapList…}代码中创建大量组合时,就会出现这种情况。当然,这个算法并不能真正扩展

请建议减少此任务计算的其他方法

import cascading.tuple.Fields
import com.twitter.scalding._

class Proto1(args: Args) extends Job(args) {
  val outputStr = "tmp/out.txt"
  val output = TextLine(outputStr)

  val wordsList = List(
    ("aaaa"),
    ("aaaa"),
    ("aaaad"),
    ("aaaab"),
    ("aaabb"),
    ("aabbcc"),
    ("aaabccdd"),
    ("aaabbccdde"),
    ("aaabbddd"),
    ("bbbb"),
    ("bbbb"),
    ("bbbaaa"),
    ("bbaaabb"),
    ("bbbcccc"),
    ("bbbddde"),
    ("bbbdddd"),
    ("bbbdddf"),
    ("bbbdddd"),
    ("ccccc"),
    ("cccaaa"),
    ("ccccaabbb"),
    ("ccbbbddd"),
    ("cdddeee"),
    ("ddd"),
    ("ddd")
    )

  val orderedPipe =
    IterableSource[(String)](wordsList, ('word))
      .map('word -> 'key) { word: String => word.take(3) }
      .debug
      //.groupBy('key) { _.toList[String]('word -> 'list) }
      //.debug
      .groupBy('key) { _.mapList[String, List[(String, String, Int)]]('word -> 'list)(editDistances) }
      .filterNot('key, 'list) { fields: (String, List[(String, String, Int)]) =>
        val (key, list) = fields
        list.isEmpty
      }
      .flatMapTo('list -> ('str1, 'str2, 'dist)) {list:List[(String, String, Int)] => list  }
      .debug
      //.write(output)
      .write(Csv(outputStr))

  def editDistances(list: List[String]): List[(String, String, Int)] = {

    val resultList = list.combinations(2).toList.map(x => (x(0), x(1), editDistance(x(0), x(1))))
        //println(resultList+"\n")
    val result = resultList.filter(x => x._3 <= 1)
    result
  }

  def editDistance(a: String, b: String): Int = {

    import scala.math.min

    def min3(x: Int, y: Int, z: Int) = min(min(x, y), z)

    val (m, n) = (a.length, b.length)

    val matrix = Array.fill(m + 1, n + 1)(0)

    for (i <- 0 to m; j <- 0 to n) {

      matrix(i)(j) = if (i == 0) j
      else if (j == 0) i
      else if (a(i - 1) == b(j - 1)) matrix(i - 1)(j - 1)
      else min3(
        matrix(i - 1)(j) + 1,
        matrix(i)(j - 1) + 1,
        matrix(i - 1)(j - 1) + 1)
    }

    matrix(m)(n)
  }

}

有什么想法吗?

你必须提供更多的背景,说明你到底想要什么。也就是说,您是否将进入阈值以获取editDistance小于某个数量的所有对??正如您所介绍的,问题是当您为一个大的组调用.combinations2时。您可以尝试两件事:使用惰性集合,因此使用迭代器而不是列表-这意味着在调用flatMapTo之前不会计算组合。另一件事就是把3个字符改成4个:是的,我也做了过滤,以获取距离小于某个阈值的对。我还用了一把4个字符的钥匙。这些都不能解决问题。你能举一个在烫伤中使用迭代器的例子吗?谢谢