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)
	}
}

关键概念说明

  1. 遗传算法组件:

    • 选择算子(Selection): 决定哪些个体可以繁殖
    • 交叉算子(Crossover): 组合两个个体的基因
    • 变异算子(Mutation): 随机改变个体基因
  2. 粒子群优化参数:

    • 惯性权重: 控制粒子保持原速度的倾向
    • 认知系数: 控制粒子向自身最佳位置移动的倾向
    • 社会系数: 控制粒子向群体最佳位置移动的倾向
  3. 评估函数:

    • 需要根据具体问题实现
    • 通常返回一个数值表示解的优劣

实际应用建议

  1. 对于离散问题,遗传算法通常更合适
  2. 对于连续优化问题,粒子群优化通常收敛更快
  3. 可以尝试调整种群大小、迭代次数和算法参数以获得更好结果
  4. 对于复杂问题,可能需要定制交叉、变异或评估函数

evoli库提供了灵活的接口,可以方便地扩展和定制各种进化算法组件,适用于各种优化问题场景。

回到顶部