2016-05-06 5 views
0

私は遺伝的アルゴリズムを使って、特定のフィットネス機能に最適な値を見つけるためのこの単純なプロジェクトを進めています。シーケンスの一般的な操作

class Individual[T](val underlying: T, val fitnessFunc: T => Double) { 
    lazy val fitness: Double = fitnessFunc(underlying) 
    def update(x: T): Individual[T] = new Individual[T](x, fitnessFunc) 
} 

class Population[T](individuals: Seq[Individual[T]]) { 
    def best: Individual[T] = individuals.tail.foldLeft(individuals.head)((b, a) => if(b.fitness > a.fitness) b else a) // not sure if this is the best way btw 
} 

trait GeneticAlgorithm[T] { 
    def select(p: Population[T]): Individual[T] 
    def crossover(i1: Individual[T], i2: Individual[T]): (Individual[T], Individual[T]) 
    def mutate(i: Individual[T]): Individual[T] 
    def evolve(p: Population[T]): Population[T] { 
     ... 
    } 
} 

私は特定のタイプTのために特別にGeneticAlgorithmの実装を作成することができますこの方法:一言で言えば、それは次のようになります。私は現在、選択、交叉、突然変異の戦略のいくつかの実装を作成しています。

しかし、私はTがシーケンスであるときに問題に遭遇しています。私は、例えば、ある変異戦略を持っているしたいこのタイプ、特定のチャンスとばかりにランダムシャッフルについて:

object Mutation { 
    def shuffleVector(p: Double): Individual[Vector[_]] => Individual[Vector[_] = (i: Individual[Vector[_]) => { 
     if (math.random < p) i.update(scala.util.Random.shuffle(i.underlying)) else i 
    } 
} 

別にそれは、任意の配列のベクターに特異的ではないという事実から、それがコンパイルちょうど良い。私が実在型を使用した理由は、Vectorがどんな型であるか気にしないということです。

しかし私はそれを使いたいときに問題にぶつかります。私はエラーを取得する

val ga = new GeneticAlgorithm[Vector[Int]] { 
    ... 
    override def mutate(i: Individual[Vector[Int]]): Individual[Vector[Int]] = Mutation.shuffleVector(0.5)(i) 
    ... 
} 

Expression of type Individual[Vector[_]] doesn't conform to expected type Individual[Vector[Int]]をたとえば、私はint型のベクトルを最適化したい場合。

これ以外にも解決できること以外に、これを解決する適切な方法は何ですか?私はそれが覆い隠しで何かをしなければならないと思うが、まだ確かではない。 ... Scalaの方法を学ぶ... ;-)すべての

答えて

2

まず、あなたが求めていないこと忙しかったが、

individuals.tail.foldLeft(individuals.head)((b, a) => if(b.fitness > a.fitness) b else a) 

something.tail.foldLeft(something.head)(f)something.reduce(f)と同等です。

はまた、あなたのスニペットは、あなたの質問に答えるために、今すぐindividuals.maxBy(_.fitness)

に実際に相当し、解決策は簡単です:ちょうどあなたのシャッフル機能は、汎用ます

def maybeShuffle[T](p: Double, xs: Seq[T]): Seq[T] = 
    if(math.random < p) scala.util.Random.shuffle(xs) else xs 
+0

はい、実際には最も明白な解決策です。ありがとう。 – avanwieringen

0

これは、実際にこれらのいずれかであるかもしれません実際のタイプの省略形としてアンダースコアを使用すると、実際には明らかな結果が得られない場合があります。

Individual[Vector[_]] 

はあなたの心に持っているものはおそらくです

Individual[Vector[T] forSome {type T}] 

異なる

Individual[Vector[T]] forSome {type T} 

に変換されます。

エラーが消えるメソッドのシグネチャを変更すると思う。

関連する問題