很像以前,一个新的人口被创造出来,人口的成员将会世代交配,而他们的后代可能携带突变。一个人的表现越好,就越有可能交配。随着时间的推移,算法收敛到最好的答案,或者至少是一个相当不错的答案。
那么当它运行时,它返回了什么呢?
Best: x: 3.072833 y: -6.994695
不坏!由于人口规模只有5、20代,而且输入的范围被限制在[0 100],这一搜索就钉在了顶点上。
现在,您可能想知道为什么我定义了所有的接口方法来返回“接口{}”。这就像Go和generics一样。没有对象,因此没有对象类型返回,但是没有描述的大小的数据仍然可以在堆栈上传递。这本质上也是这个返回类型的含义:它传递一些已知的和类似的类型的对象。有了这个“泛型”,我就可以将GA移动到它自己的包中,并将相同的代码移到多个不同类型的数据上。
我们有两个输入的3D二次方程,而不是一个二维二次方程的单个输入。接口方法只需要很小的改变:
type Quad3D struct {
x, y float64
}
func makeNewQuadEntry(newX, newY float64) Quad3D {
return Quad3D{
x: newX,
y: newY,
}
}
func calculate3D(entry Quad3D) float64 {
return math.Pow(entry.x, 2)- 6 * entry.x + math.Pow(entry.y, 2)- 6 * entry.y + 2
}
type Quadratic3dGA struct {
}
func (l Quadratic3dGA) GenerateInitialPopulation(populationSize int)[]interface{}{
initialPopulation := make([]interface{}, 0, populationSize)
for i:= 0; i < populationSize; i++ { initialPopulation = append(initialPopulation, makeNewQuadEntry(makeNewEntry(), makeNewEntry())) } return initialPopulation } func (l Quadratic3dGA) PerformCrossover(result1, result2 interface{}, mutationRate int) interface{}{ r1Entry, r2Entry := result1.(Quad3D), result2.(Quad3D) return makeNewQuadEntry((r1Entry.x + r2Entry.x) / 2, (r1Entry.y + r2Entry.y) / 2,) } func (l Quadratic3dGA) PerformMutation(_ interface{}) interface{}{ return makeNewQuadEntry(makeNewEntry(), makeNewEntry()) } func (l Quadratic3dGA) Sort(population []interface{}){ sort.Slice(population, func(i, j int) bool { return calculate3D(population[i].(Quad3D)) > calculate3D(population[j].(Quad3D))
})
}
func quadratic3dMain(){
settings := ga.GeneticAlgorithmSettings{
PopulationSize: 25,
MutationRate: 10,
CrossoverRate: 100,
NumGenerations: 20,
KeepBestAcrossPopulation: true,
}
best, err := ga.Run(Quadratic3dGA{}, settings)
entry := best.(Quad3D)
if err != nil {
println(err)
}else{
fmt.Printf("Best: x: %f y: %f z: %fn", entry.x, entry.y, calculate3D(entry))
}
}
而不是到处都是float64s,任何地方都可以通过Quad3D的条目;每一个都有一个X和一个Y值。对于创建的每个条目,都使用contructor makeNewQuadEntry创建。Run()方法中的代码都没有更改。
当它运行时,我们得到这个输出:
Best: x: 3.891671 y: 4.554884 z: -12.787259










