Skip to content

Golang implementation of a binary genetic algorithm with random binary crossover & mutation

License

Notifications You must be signed in to change notification settings

kelindar/evolve

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Genetic Algorithm

GitHub go.mod Go version PkgGoDev Go Report Card License Coverage Status

This repository contains a simple implementation of a genetic algorithm for evolving arbitrary types. There's a double-buffering in place to prevent unnecessary allocations and a relatively simple API around it.

It also provides a binary package for evolving []byte genomes. Under the hood, it uses a simple random binary crossover and mutation to do the trick.

Usage

In order to use this, we first need to create a "phenotype" representation which contains the dna. In this example we're using the binary package in order to evolve a string. It should implement the Evolver interface which contains Genome() and Evolve() methods, in the example here we are creating a simple text which contains the binary representation of the text itself.

// Text represents a text with a dna (text itself in this case)
type text struct {
	dna evolve.Genome
}

// Genome returns the genome
func (t *text) Genome() []byte {
	return t.dna
}

// Evolve updates the genome
func (t *text) Evolve(v []byte) {
	t.dna = v
}

Next, we'll need a fitness function to evaluate how good a genome is. In this example we're creating a fitness function for an abritrary string which simply returns a func(Evolver) float32

// fitnessFor returns a fitness function for a string
func fitnessFor(text string) evolve.Fitness {
	target := []byte(text)
	return func(v evolve.Evolver) float32 {
		var score float32
		genome := v.Genome().(*binary.Genome)
		for i, v := range *genome {
			if v == target[i] {
				score++
			}
		}
		return score / float32(len(target))
	}
}

Finally, we can wire everything together by using New() function to create a population, and evolve it by repeatedly calling Evolve() method as shown below.

func main() {
	const target = "Hello World"
	const n = 200

	// Create a fitness function
	fit := fitnessFor(target)

	// Create a population
	population := make([]evolve.Evolver, 0, n)
	for i := 0; i < n; i++ {
		population = append(population, new(text))
	}
    
	// Create a population
	pop := evolve.New(population, fit, len(target))

	// Evolve over many generations
	for i := 0 ; i < 100000; i++ {
		pop.Evolve()
	}

	// Get the fittest member of the population
	fittest := pop.Fittest()
}

License

Tile is licensed under the MIT License.

About

Golang implementation of a binary genetic algorithm with random binary crossover & mutation

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published