【问题标题】:Scala: How to create a new list from the weighted difference of two lists added to a thirdScala:如何从添加到第三个列表的两个列表的加权差中创建一个新列表
【发布时间】:2016-01-15 06:12:09
【问题描述】:

作为Differential Evolution 算法实现的一部分,我需要实现“突变”步骤:

  1. 从总体中随机选择三个成员,他们必须彼此不同,也必须与给定成员不同
  2. 通过将两个向量的加权差与第三个向量相加来计算捐赠者成员

This 是我想出的:

// Algorithm types
type Member = List[Double]
type Generation = Vector[Member]

def mutate(index: Int, generation: Generation): Member = {
  // Create a random number stream with distinct values
  val selector = Stream.continually(Random.nextInt(N)).distinct

  // Select 3 mates from the generation
  val mates = selector.filter(_ != index).take(3).map(generation(_))

  // Calculate the donor member
  (mates(0), mates(1), mates(2)).zipped map {
    case (e1, e2, e3) => e1 + F * (e2 - e3)
  }
}

(我按照here的解释实现了算法)

现在我的问题;有没有更好的方法来实现这一步?我一直在尝试找到一种更好的方法来从向量中选择 3 个列表并将它们压缩在一起,但是除了手动将所选列表放入元组之外,我找不到任何其他方法。 scala 编译器发出警告,应该使用mates.head 而不是mates(0),这表明这可以以更优雅的方式实现。

提前致谢!

【问题讨论】:

    标签: algorithm list scala random


    【解决方案1】:

    你可以transpose你的mates,然后mapSeq提取器覆盖它:

    mates.transpose map {
      case Seq(e1, e2, e3) => e1 + F * (e2 - e3)
    }
    

    这将是一个Stream[Double],所以要获得一个Member,你必须调用toList,或者使用mates.toList.transpose ...

    【讨论】:

    • 谢谢!太棒了,我希望有这样的东西。只是一个简单的问题,为什么我们可以使用Seq 来匹配Stream
    • @Wilco Seq 提取器在其参数是Seq 的任何子类(Stream 是)的情况下工作。提取器归结为def unapplySeq[A](x: Seq[A]): Option[Seq[A]] = Some(x),因此它接受任何子类,然后unapplySeq 完成提取和检查元素的工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多