Example #1
0
func (d Classic) decode(g neat.Genome) (net neat.Network, err error) {

	// Identify the genes
	nodes, conns := g.GenesByPosition()

	// Create the neurons
	nmap := make(map[int]int)
	neurons := make([]network.Neuron, len(nodes))
	for i, ng := range nodes {
		nmap[ng.Innovation] = i
		neurons[i] = network.Neuron{NeuronType: ng.NeuronType, ActivationType: ng.ActivationType, X: ng.X, Y: ng.Y}
	}

	// Create the synapses
	//forward := true // Keep track of conenctions to determine if this is a feed-forward only network
	synapses := make([]network.Synapse, 0, len(conns))
	for _, cg := range conns {
		if cg.Enabled {
			//src, tgt := nodes[nmap[cg.Source]], nodes[nmap[cg.Target]]
			//forward = forward && src.Y < tgt.Y
			synapses = append(synapses, network.Synapse{
				Source: nmap[cg.Source],
				Target: nmap[cg.Target],
				Weight: cg.Weight,
			})
		}
	}

	net, err = network.New(neurons, synapses)
	return
}
Example #2
0
File: web.go Project: NioTeX/neat
func updateComplexity(v *Web, pop neat.Population) {
	// Build complexity slice
	x := make([]float64, len(pop.Genomes))
	for i, g := range pop.Genomes {
		x[i] = float64(g.Complexity())
	}

	var b neat.Genome
	max := -1.0
	for _, g := range pop.Genomes {
		if g.Fitness > max {
			b = g
			max = g.Fitness
		}
	}

	// Append the record
	min, _ := stats.Min(x)
	max, _ = stats.Max(x)
	mean, _ := stats.Mean(x)

	v.complexity = append(v.complexity, [4]float64{
		min,
		mean,
		max,
		float64(b.Complexity()),
	})
}
Example #3
0
// Compares two genomes and returns their compatibility distance
//
// The number of excess and disjoint genes between a pair of genomes is a natural measure of their
// compatibility distance. The more disjoint two genomes are, the less evolutionary history they
// share, and thus the less compatible they are. Therefore, we can measure the compatibility distance δ
// of different structures in NEAT as a simple linear combination of the number of excess E and
// disjoint D genes, as well as the average weight differences of matching genes W, including disabled genes:
//     see formula in paper
// The coefficients c1, c2,and c3 allow us to adjust the importance of the three factors, and thefactor N,
// the number of genes in the larger genome, normalizes for genome size (N can be set to 1 if both genomes
// are small, i.e., consist of fewer than 20 genes (Stanley, 110)
func (c Classic) Compare(g1, g2 neat.Genome) (float64, error) {

	// Determine N
	n := 1.0
	if len(g1.Conns) > len(g2.Conns) && len(g1.Conns) >= 20 {
		n = float64(len(g1.Conns))
	} else if len(g2.Conns) >= 20 {
		n = float64(len(g2.Conns))
	}

	// Ensure connections are sorted
	_, conns1 := g1.GenesByInnovation()
	_, conns2 := g2.GenesByInnovation()

	// Calculate the components. This assumes both genomes' connections are sorted by their
	// innovation number (which is true if the NEAT library created them)
	var d, e, w, x float64
	i := 0
	j := 0
	for i < len(conns1) || j < len(conns2) {
		switch {
		case i == len(conns1):
			e += 1
			j += 1
		case j == len(conns2):
			e += 1
			i += 1
		default:
			c1 := conns1[i]
			c2 := conns2[j]
			switch {
			case c1.Innovation < c2.Innovation:
				d += 1
				i += 1
			case c1.Innovation > c2.Innovation:
				d += 1
				j += 1
			default: // Same innovation number
				w += math.Abs(c1.Weight - c2.Weight)
				x += 1
				i += 1
				j += 1
			}
		}
	}

	// Return the compatibility distance
	n = 1 // NOTE: The variable N mentioned in the paper does not seem to be used in any implemenation
	δ := c.ExcessCoefficient()*e/n + c.DisjointCoefficient()*d/n
	if x > 0 {
		δ += c.WeightCoefficient() * w / x
	}
	return δ, nil
}
Example #4
0
func (c Classic) Mutate(g *neat.Genome) error {
	old := g.Complexity()
	if err := c.Complexify.Mutate(g); err != nil {
		return err
	}
	if g.Complexity() == old {
		if err := c.Weight.Mutate(g); err != nil {
			return err
		}
		if err := c.Trait.Mutate(g); err != nil {
			return err
		}
	}
	return nil
}
Example #5
0
func (c Complete) Mutate(g *neat.Genome) error {
	old := g.Complexity()
	if err := c.Phased.Mutate(g); err != nil {
		return err
	}
	if g.Complexity() == old {
		if err := c.Weight.Mutate(g); err != nil {
			return err
		}
		if err := c.Trait.Mutate(g); err != nil {
			return err
		}
		if err := c.Activation.Mutate(g); err != nil {
			return err
		}
	}
	return nil
}
Example #6
0
func createOffspring(ctx neat.Context, cfg ClassicSettings, cross bool, rng *rand.Rand, pool map[int]Improvements, cnts map[int]int, next *neat.Population) (err error) {
	var child neat.Genome
	for idx, cnt := range cnts {
		l := pool[idx]
		for i := 0; i < cnt; i++ {
			p1, p2 := pickParents(cfg, cross, rng, l, pool)
			if p1.ID == p2.ID {
				child = neat.CopyGenome(p1)
			} else {
				child, err = ctx.Crosser().Cross(p1, p2)
				if err != nil {
					return
				}
			}
			child.ID = ctx.NextID()
			child.Birth = next.Generation
			err = ctx.Mutator().Mutate(&child)
			next.Genomes = append(next.Genomes, child)
		}
	}
	return
}