예제 #1
0
파일: pattern.go 프로젝트: gidden/cloudlus
// Iterate mutates m and so for each iteration, the same, mutated m should be
// passed in.
func (m *Method) Iterate(o optim.Objectiver, mesh optim.Mesh) (best *optim.Point, n int, err error) {
	if m.count == 0 {
		m.origstep = mesh.Step()
	} else if mesh.Step() < m.ResetStep {
		mesh.SetStep(m.origstep)
	}

	var nevalsearch, nevalpoll int
	var success bool
	defer m.updateDb(&nevalsearch, &nevalpoll, mesh.Step())
	m.count++

	prevstep := mesh.Step()
	if !m.DiscreteSearch {
		mesh.SetStep(0)
	}

	success, best, nevalsearch, err = m.Searcher.Search(o, mesh, m.Curr)
	mesh.SetStep(prevstep)

	n += nevalsearch
	if err != nil {
		return best, n, err
	} else if success {
		m.Curr = best
		return best, n, nil
	}

	// It is important to recenter mesh on new best point before polling.
	// This is necessary because the search may not be operating on the
	// current mesh grid.  This doesn't need to happen if search succeeds
	// because search either always operates on the same grid, or always
	// operates in continuous space.
	mesh.SetOrigin(m.Curr.Pos) // TODO: test that this doesn't get set to Zero pos [0 0 0...] on first iteration.

	success, best, nevalpoll, err = m.Poller.Poll(o, m.ev, mesh, m.Curr)
	m.Poller.Spanner.Update(mesh.Step(), success)

	n += nevalpoll
	if err != nil {
		return m.Curr, n, err
	} else if success {
		m.Curr = best
		m.nsuccess++
		if m.nsuccess == m.NsuccessGrow { // == allows -1 to mean never grow
			mesh.SetStep(mesh.Step() * 2.0)
			m.nsuccess = 0 // reset after resize
		}

		// Important to recenter mesh on new best point.  More particularly,
		// the mesh may have been resized and the new best may not lie on the
		// previous mesh grid.
		mesh.SetOrigin(best.Pos)

		return best, n, nil
	} else {
		m.nsuccess = 0
		var err error
		mesh.SetStep(mesh.Step() * 0.5)
		if mesh.Step() == 0 {
			err = ZeroStepErr
		}
		return m.Curr, n, err
	}
}