function* run({
options = requiredParam('options'),
generate = requiredParam('generate'),
evaluate = requiredParam('evaluate'),
order = requiredParam('order'),
select = requiredParam('select'),
getElite = requiredParam('getElite'),
mutate = requiredParam('mutate'),
crossover = requiredParam('crossover'),
updateState = requiredParam('updateState'),
stop = requiredParam('stop'),
best = requiredParam('best')
} = {}) {
let population, elite, mutated, offspring, state, i
population = generate({options: options})
population = evaluate({population: population, options: options})
population = order({population: population, options: options})
i = 0
state = updateState({state: state, population: population, options: options, iteration: i, bestFn: best})
while (i < options.maxIterations && !stop({state: state, population: population, options: options})) {
i++
population = select({population: population, options: options})
elite = getElite({population: population, options: options})
mutated = mutate({population: population, options: options})
offspring = crossover({population: population, options: options})
population = elite.concat(mutated).concat(offspring)
population = evaluate({population: population, options: options})
population = order({population: population, options: options})
state = updateState({state: state, population: population, options: options, iteration: i, bestFn: best})
yield {population: population, state: state, options: options, last: state.last}
}
}