public void Minimize(double x_0, CostFunction f, int max_iterations) { double x = x_0; double fx = f.Evaluate(x); double newtonX = 0; double denominator = 0; ContinuousSolution best_solution = new ContinuousSolution(new double[] { x }, fx); double?improvement = null; for (int k = 0; k < max_iterations; ++k) { f.CalcGradient(x, out denominator); if (Math.Abs(denominator) < ZERO) { break; } newtonX = x - fx / denominator; if (Math.Abs(newtonX - x) < SIGMA) { break; } x = newtonX; fx = f.Evaluate(x); if (best_solution.TryUpdateSolution(new double[] { x }, fx, out improvement)) { OnSolutionUpdated(best_solution, k); } OnStepped(new ContinuousSolution(new double[] { x }, fx), k); } }
public virtual ContinuousSolution Minimize(CostFunction f, int max_iterations) { return(Minimize((x, lower_bounds, upper_bounds, constraints) => { return f.Evaluate(x); }, (x, gradX, lower_bounds, upper_bounds, constraints) => { f.CalcGradient(x, gradX); }, (improvement, iterations) => { return iterations > max_iterations; })); }
public static bool LineSearch(double[] x_0, double fx_0, double[] direction, out double[] x_out, out double fx_out, out double alpha, CostFunction f) { int dimension = x_0.Length; double[] Vfx = new double[dimension]; x_out = new double[dimension]; alpha = 1.0; fx_out = double.MaxValue; f.CalcGradient(x_0, Vfx); double direction_length = 0; for (int d = 0; d < dimension; ++d) { direction_length += direction[d] * direction[d]; } direction_length = Math.Sqrt(direction_length); if (direction_length > 0) { for (int d = 0; d < dimension; ++d) { direction[d] /= direction_length; } } double p = 0.0; for (int d = 0; d < dimension; ++d) { p += (direction[d] * Vfx[d]); } //Console.WriteLine("p: {0}", p); if (double.IsNaN(p)) { return(false); } if (p >= 0.0) // not in the descending direction return false; { return(false); } for (int k = 0; ; ++k) { for (int d = 0; d < dimension; ++d) { x_out[d] = x_0[d] + alpha * direction[d]; } fx_out = f.Evaluate(x_out); if (fx_out < fx_0 + SIGMA * alpha * p) { return(true); } else { if (k == 0) { double enumerator = (p + fx_0 - fx_out); if (enumerator == 0) { alpha = 0.5 * p / enumerator; } else { alpha = 0.5 * p; } //Console.WriteLine("alpha: {0}", alpha); } else { alpha *= BETA; } } //Console.WriteLine("alpha: {0}", alpha); if (alpha < ZERO) { if (fx_out > fx_0) { for (int d = 0; d < dimension; ++d) { x_out[d] = x_0[d]; } fx_out = fx_0; return(true); } else { return(true); } } } }
public void Minimize(double x_0, CostFunction f, int max_iterations, double lower_bound, double upper_bound) { double lambda = (Math.Sqrt(5) - 1) / 2; double x1 = lower_bound + (1 - lambda) * (upper_bound - lower_bound); double x2 = lower_bound + lambda * (upper_bound - lower_bound); double f_x1 = f.Evaluate(x1); double f_x2 = f.Evaluate(x2); double a = lower_bound; double b = upper_bound; double x = 0; double fx = 0; if (f_x1 < f_x2) { fx = f_x1; x = x1; } else { fx = f_x2; x = x2; } ContinuousSolution best_solution = new ContinuousSolution(new double[] { x }, fx); double?improvement = null; for (int k = 0; k < max_iterations; ++k) { if (Math.Abs(b - a) <= ZERO) { break; } if (f_x1 < f_x2) { b = x2; x2 = x1; x1 = a + (1 - lambda) * (b - a); f_x1 = f.Evaluate(x1); f_x2 = f.Evaluate(x2); x = x1; fx = f_x1; } else { a = x1; x1 = x2; x2 = a + lambda * (b - a); f_x1 = f.Evaluate(x1); f_x2 = f.Evaluate(x2); x = x2; fx = f_x2; } if (f_x1 < f_x2) { fx = f_x1; x = x1; } else { fx = f_x2; x = x2; } if (best_solution.TryUpdateSolution(new double[] { x }, fx, out improvement)) { OnSolutionUpdated(best_solution, k); } OnStepped(new ContinuousSolution(new double[] { x }, fx), k); } if (best_solution.TryUpdateSolution(new double[] { x }, fx, out improvement)) { OnSolutionUpdated(best_solution, max_iterations); } }