2015-10-16 50 views
1

由于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(0)应该使用mates.head,这表明这可以用更优雅的方式实现。

提前致谢!

回答

0

您可以transposemates,比map在它与一个Seq提取:

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

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

+0

谢谢!太棒了,我希望有这样的事情。只是一个简单的问题,为什么我们允许使用'Seq'来模式匹配'Stream'? – Wilco

+0

@Wilco如果Seq'提取器的参数是'Seq'的任何子类,'Stream'就是'Seq'提取器。提取器归结为'def unapplySeq [A](x:Seq [A]):Option [Seq [A]] = Some(x)',所以它接受任何子类,然后'unapplySeq'完成作业提取并检查元素。 – Kolmar