public override ContinuousSolution Minimize(CostEvaluationMethod evaluate, GradientEvaluationMethod calc_gradient, TerminationEvaluationMethod should_terminate, object constraints = null) { double?improvement = null; int iteration = 0; ContinuousSolution[] pop = new ContinuousSolution[mPopSize]; double[] lower_bounds = null; double[] upper_bounds = null; if (mLowerBounds == null || mUpperBounds == null) { if (constraints is Tuple <double[], double[]> ) { Tuple <double[], double[]> bounds = constraints as Tuple <double[], double[]>; lower_bounds = bounds.Item1; upper_bounds = bounds.Item2; } else { throw new InvalidCastException(); } } else { lower_bounds = mLowerBounds; upper_bounds = mUpperBounds; } if (lower_bounds.Length < mDimension) { throw new IndexOutOfRangeException(); } if (upper_bounds.Length < mDimension) { throw new IndexOutOfRangeException(); } double[,] init_strategy_bounds = new double[mDimension, 2]; for (int j = 0; j < mDimension; ++j) { init_strategy_bounds[j, 0] = 0; init_strategy_bounds[j, 1] = (upper_bounds[j] - lower_bounds[j]) * 0.05; } ContinuousSolution best_solution = null; for (int i = 0; i < mPopSize; ++i) { double[] x = mSolutionGenerator(mDimension, constraints); double fx = evaluate(x, mLowerBounds, mUpperBounds, constraints); ContinuousSolution s = new ContinuousSolution(x, fx); double[] strategy = new double[mDimension]; for (int j = 0; j < mDimension; ++j) { strategy[j] = init_strategy_bounds[j, 0] + (init_strategy_bounds[j, 1] - init_strategy_bounds[j, 0]) * RandomEngine.NextDouble(); } s.SetMutationStrategy(strategy); pop[i] = s; } pop = pop.OrderBy(s => s.Cost).ToArray(); best_solution = pop[0].Clone() as ContinuousSolution; ContinuousSolution[] children = new ContinuousSolution[mPopSize]; ContinuousSolution[] generation = new ContinuousSolution[mPopSize * 2]; while (!should_terminate(improvement, iteration)) { for (int i = 0; i < mPopSize; ++i) { children[i] = Mutate(pop[i], lower_bounds, upper_bounds, constraints); children[i].Cost = evaluate(children[i].Values, mLowerBounds, mUpperBounds, constraints); } children = children.OrderBy(s => s.Cost).ToArray(); if (best_solution.TryUpdateSolution(children[0].Values, children[0].Cost, out improvement)) { OnSolutionUpdated(best_solution, iteration); } for (int i = 0; i < mPopSize; ++i) { generation[i] = pop[i]; } for (int i = 0; i < mPopSize; ++i) { generation[i + mPopSize] = children[i]; } for (int i = 0; i < generation.Length; ++i) { int wins = 0; ContinuousSolution si = generation[i]; for (int j = 0; j < mBoutSize; ++j) { ContinuousSolution sj = generation[RandomEngine.NextInt(generation.Length)]; if (si.Cost < sj.Cost) { wins++; } } si.SetWins(wins); } generation = generation.OrderByDescending(s => s.GetWins()).ToArray(); for (int i = 0; i < mPopSize; ++i) { pop[i] = generation[i]; } OnStepped(best_solution, iteration); iteration++; } return(best_solution); }