Beispiel #1
0
func (d *ESHyperNEAT) pruneAndExtract(cppn neat.Network, t int, a []float64, p *espoint, outgoing bool) (conns esconns, err error) {
	for _, c := range p.children {
		if variance(c) > d.VarianceThreshold() {
			var con2 esconns
			con2, err = d.pruneAndExtract(cppn, t, a, c, outgoing)
			if err != nil {
				return
			}
			conns = append(conns, con2...)
		} else {
			max := 0.0
			// Determine if point is in a band by checking neighbor CPPN values
			var outputs []float64
			for i := 0; i < d.dims; i++ {
				min := math.Inf(1)
				for j := 0; j < 2; j++ {
					x := c.position[i]
					if j == 0 {
						c.position[i] -= p.width
					} else {
						c.position[i] += p.width
					}
					if outgoing {
						outputs, err = cppn.Activate(append(a, append(c.position, 1.0)...))
					} else {
						outputs, err = cppn.Activate(append(c.position, append(a, 0.0)...))
					}
					if err != nil {
						return
					}
					if min > outputs[t] {
						min = outputs[t]
					}
					c.position[i] = x
				}
				if max < min {
					max = min
				}
			}
			if max > d.BandThreshold() {
				// Create new connection specified by source, target, weight
				// and scale weight based on weight range
				var conn *esconn
				if outgoing {
					conn = &esconn{source: a, target: c.position}
				} else {
					conn = &esconn{source: c.position, target: a}
				}
				if !conns.contains(conn) {
					conn.weight = c.weight * d.WeightRange()
					conns = append(conns, conn)
				}
			}
		}
	}
	return
}
Beispiel #2
0
func (d *ESHyperNEAT) divAndInit(cppn neat.Network, t int, a []float64, outgoing bool) (root *espoint, err error) {
	root = &espoint{
		position: make([]float64, d.dims),
		width:    1,
		level:    1,
		children: make([]*espoint, len(d.divs)),
	}
	q := make([]*espoint, 0, 16)
	q = append(q, root)
	for len(q) > 0 {
		// Dequeue the next item
		p := q[0]
		q[0] = nil
		q = q[1:]

		// Divide into subregions
		for i := 0; i < len(p.children); i++ {
			c := &espoint{
				position: make([]float64, len(p.position)),
				width:    p.width / 2.0,
				level:    p.level + 1,
			}
			for j := 0; j < d.dims; j++ {
				c.position[j] = p.position[j] + c.width*d.divs[i][j]
			}
			p.children[i+0] = c
		}

		// Process the children
		for _, c := range p.children {
			var outputs []float64
			if outgoing {
				outputs, err = cppn.Activate(append(a, append(c.position, 1.0)...))
			} else {
				outputs, err = cppn.Activate(append(c.position, append(a, 0.0)...))
			}
			if err != nil {
				return
			}
			c.weight = outputs[t]
		}

		// Divide until intial resolution or if variance is still high
		if p.level < d.InitialDepth() || (p.level < d.MaxDepth() && variance(p) > d.DivisionThreshold()) {
			for i, _ := range p.children {
				q = append(q, p.children[i])
			}
		}
	}
	return
}