【问题标题】:Parallelizing recursive branching computations in scala using futures使用期货并行化scala中的递归分支计算
【发布时间】:2016-10-20 14:11:48
【问题描述】:

我正在尝试使用 Futures 在 Scala 中并行化 SAT 求解器。

解决 SAT 问题的算法大致类似于(伪代码):

def has_solution(x):
    if x is a solution:
        return true
    else if x is not a solution:
        return false
    else:
        x1 = left_branch(x)
        x2 = right_branch(x)
        return has_solution(x1) or has_solution(x2)

因此,每当我对问题进行分支时,我都会看到并行计算的机会。

如何使用 Futures 做到这一点?我需要等待 has_solution(x1) 和 has_solution(x2) 的结果,并且:

  1. 只要任一分支返回 true,就返回 true
  2. 如果两个分支都返回 false,则返回 false

我目前的做法如下:

object DPLL {
  def apply(formula: Formula): Future[Boolean] = {
    var tmp = formula

    if (tmp.isEmpty) {
      Future { true }
    } else if (tmp.hasEmptyClause) {
      Future { false }
    } else {

      for (unitClause <- tmp.unitClauses) tmp = tmp.propagateUnit(unitClause);
      for (pureLiteral <- tmp.pureLiterals) tmp = tmp.assign(pureLiteral);

      if (tmp.isEmpty())
        Future { true }
      else if (tmp.hasEmptyClause)
        Future { false }
      else {
        val nextLiteral = tmp.chooseLiteral

这里是发生分支的地方,也是我想等待上述计算的地方:

        for (f1 <- DPLL(tmp.assign(nextLiteral)); 
             f2 <- DPLL(tmp.assign(-nextLiteral)))
          yield (f1 || f2)
      }
    }
  }
}

当我运行它时,这看起来是错误的,因为我永远无法充分利用我的核心 (8)。

我有一种直觉,我不应该使用期货来进行这种计算。也许期货只适合异步计算。我应该为此尝试一些较低级别的线程或基于参与者的方法吗?谢谢。

【问题讨论】:

    标签: multithreading scala concurrency


    【解决方案1】:

    由于 for 块,此代码按顺序工作! f2 的计算在 f1 的计算完成后开始。

    for {
      f1 <- DPLL(tmp.assign(nextLiteral))
      f2 <- DPLL(tmp.assign(-nextLiteral))
    } yield f1 || f2
    

    上面的块转换为遵循flatMap/map 序列,flatMap/map 所做的是在值存在后运行函数。

    DPLL(tmp.assign(nextLiteral)).flatMap(f1 =>
      DPLL(tmp.assign(-nextLiteral)).map(f2 =>
        f1 || f2)
    

    并行开始计算的一个简单技巧是将它们分配给一个值并访问该值以进行理解

    val comp1 = DPLL(tmp.assign(nextLiteral))
    val comp2 = DPLL(tmp.assign(-nextLiteral))
    for {
      f1 <- comp1
      f2 <- comp1
    } yield f1 || f2
    

    【讨论】:

      猜你喜欢
      • 2013-08-02
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 2021-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多