2015-10-16 49 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