// Path: src/jeco/core/problem/Problem.java
// public abstract class Problem<V extends Variable<?>> {
//     //private static final Logger logger = Logger.getLogger(Problem.class.getName());
// 
//     public static final double INFINITY = Double.POSITIVE_INFINITY;
//     protected int numberOfVariables;
//     protected int numberOfObjectives;
//     protected double[] lowerBound;
//     protected double[] upperBound;
// 
//     protected int maxEvaluations;
//     protected int numEvaluations;
// 
//     public Problem(int numberOfVariables, int numberOfObjectives) {
//         this.numberOfVariables = numberOfVariables;
//         this.numberOfObjectives = numberOfObjectives;
//         this.lowerBound = new double[numberOfVariables];
//         this.upperBound = new double[numberOfVariables];
//         this.maxEvaluations = Integer.MAX_VALUE;
//         resetNumEvaluations();
//     }
// 
//     public int getNumberOfVariables() {
//         return numberOfVariables;
//     }
// 
//     public int getNumberOfObjectives() {
//         return numberOfObjectives;
//     }
// 
//     public double getLowerBound(int i) {
//         return lowerBound[i];
//     }
// 
//     public double getUpperBound(int i) {
//         return upperBound[i];
//     }
// 
//     public int getMaxEvaluations() {
//         return maxEvaluations;
//     }
// 
//     public void setMaxEvaluations(int maxEvaluations) {
//         this.maxEvaluations = maxEvaluations;
//     }
// 
//     public int getNumEvaluations() {
//         return numEvaluations;
//     }
// 
//     public final void resetNumEvaluations() {
//         numEvaluations = 0;
//     }
//     
//     public void setNumEvaluations(int numEvaluations) {
//         this.numEvaluations = numEvaluations;
//     }
// 
//     public abstract Solutions<V> newRandomSetOfSolutions(int size);
// 
//     public void evaluate(Solutions<V> solutions) {
//         for (Solution<V> solution : solutions) {
//             evaluate(solution);
//         }
//     }
// 
//     public abstract void evaluate(Solution<V> solution);
// 
//     @Override
//     public abstract Problem<V> clone();
// 
//     public boolean reachedMaxEvaluations() {
//         return (numEvaluations >= maxEvaluations);
//     }
// }
// 
// Path: src/jeco/core/problem/Variable.java
// public class Variable<T> {
//     protected T value;
// 
//     public Variable(T value) {
//         this.value = value;
//     }
// 
//     public T getValue() { return value; }
// 
//     public void setValue(T value) { this.value = value; }
//     
//     @Override
//     public Variable<T> clone() {
//         return new Variable<T>(value);
//     }
// 
//     @SuppressWarnings("unchecked")
// 		@Override
//     public boolean equals(Object right) {
//         Variable<T> var = (Variable<T>)right;
//         return this.value.equals(var.value);
//     }
//     
//     @Override
//     public String toString()
//     {
//     	return value.toString();
//     }
// }
// 
// Path: src/jeco/core/problem/solution/NeutralMutationSolution.java
// public class NeutralMutationSolution extends Solution<Variable<Integer>> {
//     protected ArrayList<Integer> noOptionsPhenotype = new ArrayList<Integer>();
// 
//     public NeutralMutationSolution(int numberOfObjectives) {
//         super(numberOfObjectives);
//     }
// 
//     public ArrayList<Integer> getNoOptionsPhenotype() {
//         return noOptionsPhenotype;
//     }
// 
//     public void setNoOptionsPhenotype(ArrayList<Integer> noOptionsPhenotype) {
//         this.noOptionsPhenotype = noOptionsPhenotype;
//     }
// 
//     @Override
//     public NeutralMutationSolution clone() {
//         NeutralMutationSolution clone = new NeutralMutationSolution(objectives.size());
//         for (int i = 0; i < objectives.size(); ++i) {
//             clone.objectives.set(i, objectives.get(i));
//         }
//         for (int i = 0; i < variables.size(); ++i) {
//             clone.variables.add(variables.get(i).clone());
//         }
// 
//         for (Map.Entry<String, Number> entry : properties.entrySet()) {
//             clone.properties.put(entry.getKey(), entry.getValue());
//         }
// 
//         for (int i = 0; i < noOptionsPhenotype.size(); ++i) {
//             clone.noOptionsPhenotype.add(noOptionsPhenotype.get(i).intValue()); // clone doesn't work
//         }
// 
//         return clone;
//     }
// 
//     // noOptionsPhenotype is dependent of variables array, thus no equals method modification is needed
// }


import jeco.core.problem.Problem;
import jeco.core.problem.Solution;
import jeco.core.problem.Variable;
import jeco.core.problem.solution.NeutralMutationSolution;
import jeco.core.util.random.RandomGenerator;
package jeco.core.operator.mutation;


public class NeutralMutation<T extends Variable<Integer>> extends MutationOperator<T> {
	protected Problem<T> problem;

// Path: src/jeco/core/problem/Problem.java
// public abstract class Problem<V extends Variable<?>> {
//     //private static final Logger logger = Logger.getLogger(Problem.class.getName());
// 
//     public static final double INFINITY = Double.POSITIVE_INFINITY;
//     protected int numberOfVariables;
//     protected int numberOfObjectives;
//     protected double[] lowerBound;
//     protected double[] upperBound;
// 
//     protected int maxEvaluations;
//     protected int numEvaluations;
// 
//     public Problem(int numberOfVariables, int numberOfObjectives) {
//         this.numberOfVariables = numberOfVariables;
//         this.numberOfObjectives = numberOfObjectives;
//         this.lowerBound = new double[numberOfVariables];
//         this.upperBound = new double[numberOfVariables];
//         this.maxEvaluations = Integer.MAX_VALUE;
//         resetNumEvaluations();
//     }
// 
//     public int getNumberOfVariables() {
//         return numberOfVariables;
//     }
// 
//     public int getNumberOfObjectives() {
//         return numberOfObjectives;
//     }
// 
//     public double getLowerBound(int i) {
//         return lowerBound[i];
//     }
// 
//     public double getUpperBound(int i) {
//         return upperBound[i];
//     }
// 
//     public int getMaxEvaluations() {
//         return maxEvaluations;
//     }
// 
//     public void setMaxEvaluations(int maxEvaluations) {
//         this.maxEvaluations = maxEvaluations;
//     }
// 
//     public int getNumEvaluations() {
//         return numEvaluations;
//     }
// 
//     public final void resetNumEvaluations() {
//         numEvaluations = 0;
//     }
//     
//     public void setNumEvaluations(int numEvaluations) {
//         this.numEvaluations = numEvaluations;
//     }
// 
//     public abstract Solutions<V> newRandomSetOfSolutions(int size);
// 
//     public void evaluate(Solutions<V> solutions) {
//         for (Solution<V> solution : solutions) {
//             evaluate(solution);
//         }
//     }
// 
//     public abstract void evaluate(Solution<V> solution);
// 
//     @Override
//     public abstract Problem<V> clone();
// 
//     public boolean reachedMaxEvaluations() {
//         return (numEvaluations >= maxEvaluations);
//     }
// }
// 
// Path: src/jeco/core/problem/Variable.java
// public class Variable<T> {
//     protected T value;
// 
//     public Variable(T value) {
//         this.value = value;
//     }
// 
//     public T getValue() { return value; }
// 
//     public void setValue(T value) { this.value = value; }
//     
//     @Override
//     public Variable<T> clone() {
//         return new Variable<T>(value);
//     }
// 
//     @SuppressWarnings("unchecked")
// 		@Override
//     public boolean equals(Object right) {
//         Variable<T> var = (Variable<T>)right;
//         return this.value.equals(var.value);
//     }
//     
//     @Override
//     public String toString()
//     {
//     	return value.toString();
//     }
// }
// 
// Path: src/jeco/core/problem/solution/NeutralMutationSolution.java
// public class NeutralMutationSolution extends Solution<Variable<Integer>> {
//     protected ArrayList<Integer> noOptionsPhenotype = new ArrayList<Integer>();
// 
//     public NeutralMutationSolution(int numberOfObjectives) {
//         super(numberOfObjectives);
//     }
// 
//     public ArrayList<Integer> getNoOptionsPhenotype() {
//         return noOptionsPhenotype;
//     }
// 
//     public void setNoOptionsPhenotype(ArrayList<Integer> noOptionsPhenotype) {
//         this.noOptionsPhenotype = noOptionsPhenotype;
//     }
// 
//     @Override
//     public NeutralMutationSolution clone() {
//         NeutralMutationSolution clone = new NeutralMutationSolution(objectives.size());
//         for (int i = 0; i < objectives.size(); ++i) {
//             clone.objectives.set(i, objectives.get(i));
//         }
//         for (int i = 0; i < variables.size(); ++i) {
//             clone.variables.add(variables.get(i).clone());
//         }
// 
//         for (Map.Entry<String, Number> entry : properties.entrySet()) {
//             clone.properties.put(entry.getKey(), entry.getValue());
//         }
// 
//         for (int i = 0; i < noOptionsPhenotype.size(); ++i) {
//             clone.noOptionsPhenotype.add(noOptionsPhenotype.get(i).intValue()); // clone doesn't work
//         }
// 
//         return clone;
//     }
// 
//     // noOptionsPhenotype is dependent of variables array, thus no equals method modification is needed
// }


// Path: src/jeco/core/operator/mutation/NeutralMutation.java
import jeco.core.problem.Problem;
import jeco.core.problem.Solution;
import jeco.core.problem.Variable;
import jeco.core.problem.solution.NeutralMutationSolution;
import jeco.core.util.random.RandomGenerator;

package jeco.core.operator.mutation;


public class NeutralMutation<T extends Variable<Integer>> extends MutationOperator<T> {
	protected Problem<T> problem;

	public NeutralMutation(Problem<T> problem, double probability) {