package ec.gp.semantic.breed;

import ec.EvolutionState;
import ec.gp.GPNode;
import ec.gp.breed.GPBreedDefaults;
import ec.gp.semantic.DesiredSemanticsBase;
import ec.gp.semantic.ISemantics;
import ec.gp.semantic.breed.deprecated.MetricMutation;
import ec.gp.semantic.utils.PoissonDistribution;
import ec.util.Parameter;

public class LM extends MetricMutation {
	private static Parameter DEFAULT_BASE = GPBreedDefaults.base().push("LM");
	private PoissonDistribution randomGenerator;

	@Override
	public Parameter defaultBase() {
		return DEFAULT_BASE;
	}

	@Override
	public void setup(final EvolutionState state, final Parameter base) {
		super.setup(state, base);

		randomGenerator = new PoissonDistribution();
		randomGenerator.setup(state, base);
	}

	@Override
	protected GPNode getSubtree(final EvolutionState state, final int thread, final ISemantics rootSemantics,
			final ISemantics intermediateSemantics, final int maxHeight) {

		if (this.random) {
			return library.getRandom(state.random[thread], maxHeight);
		}

		int k = randomGenerator.next(thread, library.size() - 1);
		
		// get the k-th closest program
		return (GPNode)library.getKthProgram(
				new DesiredSemanticsBase(intermediateSemantics),
				new DesiredSemanticsBase[0],
				k
				/* state.random[thread].nextInt(this.neighborCount) */, 
				maxHeight).getProgram();
	}

}
