golang遗传算法与粒子群优化智能计算插件库evoli的使用
Golang遗传算法与粒子群优化智能计算插件库evoli的使用
简介
evoli是一个用Go语言实现的遗传算法和粒子群优化算法库,用于解决各种优化问题。
示例问题
给定函数:f(x,y) = cos(x^2 * y^2) * 1/(x^2 * y^2 + 1)
寻找使f(x,y)
达到最大值的(x,y)
点,正确答案是f(0,0) = 1
。
粒子群优化(PSO)示例
package main
import (
"fmt"
"math"
"math/rand"
"github.com/khezen/evoli"
)
// 3d cosine that gets smaller as you move away from 0,0
func f(x, y float64) float64 {
d := x*x + y*y
return math.Cos(d) * (1 / (d/10 + 1))
}
type FIndividual struct {
v []float64
x []float64
fitness float64
}
func (i *FIndividual) Equal(other evoli.Individual) bool {
return i == other
}
func (i *FIndividual) Fitness() float64 {
return i.fitness
}
func (i *FIndividual) SetFitness(newFitness float64) {
i.fitness = newFitness
}
type FPositioner struct {
}
func (p *FPositioner) Position(indiv, pBest, gBest evoli.Individual, c1, c2 float64) (evoli.Individual, error) {
fIndiv, ok1 := indiv.(*FIndividual)
fPBest, ok2 := pBest.(*FIndividual)
fGBest, ok3 := gBest.(*FIndividual)
if !ok1 || !ok2 || !ok3 {
return nil, fmt.Errorf("invalid individual type")
}
newIndiv := FIndividual{
v: make([]float64, len(fIndiv.v)),
x: make([]float64, len(fIndiv.v)),
}
w := 0.9
for d := range fIndiv.v {
rp := rand.Float64()
rg := rand.Float64()
newIndiv.v[d] = w*fIndiv.v[d] +
c1*rp*(fPBest.x[d]-fIndiv.x[d]) +
c2*rg*(fGBest.x[d]-fIndiv.x[d])
newIndiv.x[d] = fIndiv.x[d] + newIndiv.v[d]
}
return &newIndiv, nil
}
type FEvaluater struct {
}
func (e *FEvaluater) Evaluate(indiv evoli.Individual) (Fitness float64, err error) {
fIndiv, ok := indiv.(*FIndividual)
if !ok {
return 0, fmt.Errorf("invalid individual type")
}
return f(fIndiv.x[0], fIndiv.x[1]), nil
}
func main() {
pop := evoli.NewPopulation(50)
for i := 0; i < pop.Cap(); i++ {
x := rand.Float64()*20 - 10
y := rand.Float64()*20 - 10
vx := rand.Float64()*20 - 10
vy := rand.Float64()*20 - 10
pop.Add(&FIndividual{
x: []float64{x, y},
v: []float64{vx, vy},
})
}
positioner := &FPositioner{}
evaluator := &FEvaluater{}
sw := evoli.NewSwarm(pop, positioner, .2, .2, evaluator)
for i := 0; i < 100; i++ {
err := sw.Next()
if err != nil {
panic(err)
}
}
// evaluate the latest population
for _, v := range sw.Population().Slice() {
f, err := evaluator.Evaluate(v)
if err != nil {
panic(err)
}
v.SetFitness(f)
}
fmt.Printf("Max Value: %.2f\n", sw.Alpha().Fitness())
}
输出结果:
Max Value: 1.00
遗传算法(GA)示例
package main
import (
"fmt"
"math"
"math/rand"
"github.com/khezen/evoli"
)
// 3d cosine that gets smaller as you move away from 0,0
func h(x, y float64) float64 {
d := x*x + y*y
return math.Cos(d) * (1 / (d/10 + 1))
}
type HIndividual struct {
v []float64
x []float64
fitness float64
}
func (i *HIndividual) Equal(other evoli.Individual) bool {
return i == other
}
func (i *HIndividual) Fitness() float64 {
return i.fitness
}
func (i *HIndividual) SetFitness(newFitness float64) {
i.fitness = newFitness
}
type HMutater struct {
}
func (m *HMutater) Mutate(indiv evoli.Individual, mutationProbability float64) (evoli.Individual, error) {
hIndiv1, ok := indiv.(*HIndividual)
if !ok {
return nil, fmt.Errorf("invalid individual type")
}
x := hIndiv1.x[0]
y := hIndiv1.x[1]
vx := hIndiv1.v[0]
vy := hIndiv1.v[1]
if mutationProbability > rand.Float64() {
x = rand.Float64()*20 - 10
}
if mutationProbability > rand.Float64() {
y = rand.Float64()*20 - 10
}
if mutationProbability > rand.Float64() {
vx = rand.Float64()*20 - 10
}
if mutationProbability > rand.Float64() {
vy = rand.Float64()*20 - 10
}
return &HIndividual{
x: []float64{x, y},
v: []float64{vx, vy},
}, nil
}
type HCrosser struct {
}
func (h *HCrosser) Cross(indiv1, indiv2 evoli.Individual) (evoli.Individual, evoli.Individual, error) {
hIndiv1, ok1 := indiv1.(*HIndividual)
hIndiv2, ok2 := indiv2.(*HIndividual)
if !ok1 || !ok2 {
return nil, nil, fmt.Errorf("invalid individual type")
}
return &HIndividual{
x: []float64{hIndiv1.x[0], hIndiv2.x[1]},
v: []float64{hIndiv1.v[0], hIndiv2.v[1]},
}, &HIndividual{
x: []float64{hIndiv2.x[0], hIndiv1.x[1]},
v: []float64{hIndiv2.v[0], hIndiv1.v[1]},
}, nil
}
type HEvaluater struct {
}
func (e *HEvaluater) Evaluate(indiv evoli.Individual) (Fitness float64, err error) {
fIndiv, ok := indiv.(*HIndividual)
if !ok {
return 0, fmt.Errorf("invalid individual type")
}
return h(fIndiv.x[0], fIndiv.x[1]), nil
}
func main() {
pop := evoli.NewPopulation(50)
for i := 0; i < pop.Cap(); i++ {
x := rand.Float64()*20 - 10
y := rand.Float64()*20 - 10
vx := rand.Float64()*20 - 10
vy := rand.Float64()*20 - 10
pop.Add(&HIndividual{
x: []float64{x, y},
v: []float64{vx, vy},
})
}
crosser := &HCrosser{}
mutater := &HMutater{}
evaluator := &HEvaluater{}
mutationProbability := .20
selecter := evoli.NewTruncationSelecter()
survivorSize := 30
ga := evoli.NewGenetic(pop, selecter, survivorSize, crosser, mutater, mutationProbability, evaluator)
for i := 0; i < 100; i++ {
err := ga.Next()
if err != nil {
panic(err)
}
}
// evaluate the latest population
for _, v := range ga.Population().Slice() {
f, err := evaluator.Evaluate(v)
if err != nil {
panic(err)
}
v.SetFitness(f)
}
fmt.Printf("Max Value: %.2f\n", ga.Alpha().Fitness())
}
输出结果:
Max Value: 1.00
贡献
欢迎任何形式的贡献!无论是改进文档、优化代码还是修复问题。如果您有任何问题或建议,请通过GitHub issue提出。
更多关于golang遗传算法与粒子群优化智能计算插件库evoli的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang遗传算法与粒子群优化智能计算插件库evoli的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang遗传算法与粒子群优化:evoli库使用指南
evoli是一个用于Golang的智能计算插件库,提供了遗传算法(GA)和粒子群优化(PSO)等进化算法的实现。下面我将详细介绍如何使用这个库。
安装
首先安装evoli库:
go get github.com/kraken-hpc/evoli
遗传算法(GA)使用示例
遗传算法是一种模拟自然选择过程的优化算法。以下是使用evoli实现遗传算法的完整示例:
package main
import (
"fmt"
"math/rand"
"time"
"github.com/kraken-hpc/evoli"
)
// 定义个体类型
type MyIndividual struct {
Gene []float64
Fitness float64
Age int
Dead bool
Evaluated bool
}
// 实现Individual接口
func (i *MyIndividual) Clone() evoli.Individual {
return &MyIndividual{
Gene: append([]float64{}, i.Gene...),
Fitness: i.Fitness,
Age: i.Age,
Dead: i.Dead,
Evaluated: i.Evaluated,
}
}
// 评估函数 - 这里使用简单的平方和作为示例
func evaluate(indiv evoli.Individual) float64 {
i := indiv.(*MyIndividual)
sum := 0.0
for _, v := range i.Gene {
sum += v * v
}
return -sum // 取负值因为我们要最小化这个函数
}
func main() {
rand.Seed(time.Now().UnixNano())
// 创建种群
popSize := 50
geneSize := 5
population := evoli.NewPopulation(popSize)
// 初始化种群
for i := 0; i < popSize; i++ {
gene := make([]float64, geneSize)
for j := range gene {
gene[j] = rand.Float64()*20 - 10 // -10到10之间的随机数
}
population.Add(&MyIndividual{
Gene: gene,
})
}
// 创建遗传算法
ga := evoli.NewGenetic(
evoli.NewTruncationSelection(0.5), // 选择算子
evoli.NewTwoPointsCrossover(), // 交叉算子
evoli.NewUniformMutation(0.1), // 变异算子
0.7, // 交叉概率
)
// 创建模拟环境
env := evoli.NewEnvironment(ga)
env.SetEvaluator(evaluate)
// 运行遗传算法
for gen := 0; gen < 100; gen++ {
env.Next()
best := env.Alpha()
fmt.Printf("Generation %d: Best fitness = %.4f, Gene = %.2v\n",
gen, best.Fitness(), best.(*MyIndividual).Gene)
}
}
粒子群优化(PSO)使用示例
粒子群优化是一种模拟鸟群觅食行为的优化算法:
package main
import (
"fmt"
"math/rand"
"time"
"github.com/kraken-hpc/evoli"
)
// 定义粒子类型
type MyParticle struct {
Position []float64
Velocity []float64
Fitness float64
BestPos []float64
BestFit float64
}
// 实现Particle接口
func (p *MyParticle) UpdatePosition(pos []float64) {
p.Position = pos
}
func (p *MyParticle) UpdateVelocity(vel []float64) {
p.Velocity = vel
}
func (p *MyParticle) PositionSlice() []float64 {
return p.Position
}
func (p *MyParticle) VelocitySlice() []float64 {
return p.Velocity
}
func (p *MyParticle) BestPositionSlice() []float64 {
return p.BestPos
}
func (p *MyParticle) SetBestPosition(pos []float64) {
p.BestPos = pos
}
func (p *MyParticle) FitnessValue() float64 {
return p.Fitness
}
func (p *MyParticle) BestFitnessValue() float64 {
return p.BestFit
}
func (p *MyParticle) SetBestFitness(fit float64) {
p.BestFit = fit
}
// 评估函数 - 同样使用平方和
func evaluate(p evoli.Particle) float64 {
particle := p.(*MyParticle)
sum := 0.0
for _, v := range particle.Position {
sum += v * v
}
return -sum // 取负值因为我们要最小化这个函数
}
func main() {
rand.Seed(time.Now().UnixNano())
// 创建粒子群
swarmSize := 30
dim := 5
swarm := evoli.NewSwarm(swarmSize)
// 初始化粒子群
for i := 0; i < swarmSize; i++ {
pos := make([]float64, dim)
vel := make([]float64, dim)
for j := range pos {
pos[j] = rand.Float64()*20 - 10 // -10到10之间的随机位置
vel[j] = rand.Float64()*2 - 1 // -1到1之间的随机速度
}
particle := &MyParticle{
Position: pos,
Velocity: vel,
BestPos: append([]float64{}, pos...),
}
swarm.Add(particle)
}
// 创建PSO算法
pso := evoli.NewPSO(
0.7, // 惯性权重
1.5, // 认知系数
1.5, // 社会系数
0.1, // 最大速度比例
)
// 创建模拟环境
env := evoli.NewEnvironment(pso)
env.SetEvaluator(evaluate)
// 运行PSO算法
for iter := 0; iter < 100; iter++ {
env.Next()
best := env.Alpha()
fmt.Printf("Iteration %d: Best fitness = %.4f, Position = %.2v\n",
iter, best.Fitness(), best.(*MyParticle).Position)
}
}
关键概念说明
-
遗传算法组件:
- 选择算子(Selection): 决定哪些个体可以繁殖
- 交叉算子(Crossover): 组合两个个体的基因
- 变异算子(Mutation): 随机改变个体基因
-
粒子群优化参数:
- 惯性权重: 控制粒子保持原速度的倾向
- 认知系数: 控制粒子向自身最佳位置移动的倾向
- 社会系数: 控制粒子向群体最佳位置移动的倾向
-
评估函数:
- 需要根据具体问题实现
- 通常返回一个数值表示解的优劣
实际应用建议
- 对于离散问题,遗传算法通常更合适
- 对于连续优化问题,粒子群优化通常收敛更快
- 可以尝试调整种群大小、迭代次数和算法参数以获得更好结果
- 对于复杂问题,可能需要定制交叉、变异或评估函数
evoli库提供了灵活的接口,可以方便地扩展和定制各种进化算法组件,适用于各种优化问题场景。