我正在研究这个简单的项目,我想制作一个遗传算法来找到某个适应度函数的近似最优值。简而言之,它看起来像这样:
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] {
...
}
}
这样我就可以专门为某个类型GeneticAlgorithm
创建T
的实现。我现在正在忙于创建一些选择,交叉和变异策略的实现。
当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而不是任何序列之外,它编译得很好。我使用存在类型的原因是我不关心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]]
。
除了可以解决的其他一些问题外,解决这个问题的正确方法是什么?我怀疑它必须做一些覆盖面,但还不确定。一直在忙着学习斯卡拉的方式......; - )
答案 0 :(得分: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
答案 1 :(得分:0)
这实际上可能是这些情况之一,使用下划线作为存在类型的简写实际上并没有产生明显的结果。
Individual[Vector[_]]
被翻译为
Individual[Vector[T]] forSome {type T}
与
不同Individual[Vector[T] forSome {type T}]
这可能是你的想法。
我认为如果你改变方法的签名,那么错误就会消失。