一維最優化:二次插值法(Quadratic interpolation method)
阿新 • • 發佈:2019-02-02
理論見參考《Practical Optimization》中4.5節,程式碼實現如下:(
可以將黃金分割法和二次插值法結合起來,想用黃金分割法快速搜尋得到最優解,然後用該最優解作為二次插值的初值,可以提高計算精度。Matlab中就是採用此組合策略。
)
OneDimensionalOptimization.h
#ifndef _OneDimensionalOptimization_ #define _OneDimensionalOptimization_ #include <algorithm> using namespace std; class OneDimensionalOptimization { public: //參考《Practical Optimization》中4.5節 double quadraticInterpolationSearch(double(*p)(double x),double& l, double& u, double& x, double tol = 1e-6); }; #endif
OneDimensionalOptimization.cpp
double OneDimensionalOptimization::quadraticInterpolationSearch(double(*p)(double x),double& l, double& u, double& x, double tol) { int mm = 0; //1) double x1 = l; double x3 = u; double x0_aver = 1e99; //2) double x2 = 0.5 * (x1 + x3); double f1 = p(x1); double f2 = p(x2); double f3 = p(x3); //3) while(true) { mm++; double x_aver = ((x2*x2 - x3*x3)*f1 + (x3*x3 - x1*x1)*f2 + (x1*x1 - x2*x2)*f3 )/(2*((x2 - x3)*f1 + (x3 - x1)*f2 + (x1 - x2)*f3)); double f_aver = p(x_aver); if(abs(x_aver - x0_aver) < tol) { x = x_aver; return f_aver; } //4) if(x1 < x_aver && x_aver < x2) { if(f_aver <= f2) { x3 = x2; f3 = f2; x2 = x_aver; f2 = f_aver; } else { x1 = x_aver; f1 = f_aver; } } else if(x2 < x_aver && x_aver < x3) { if(f_aver <= f2) { x1 = x2; f1 = f2; x2 = x_aver; f2 = f_aver; } else { x3 = x_aver; f3 = f_aver; } } x0_aver = x_aver;
}
}
測試程式碼如下:
main.cpp
#include "src\Optimizer\OneDimensionalOptimization.h" #include <fstream> using namespace std; double p(double x) { return -sin(x); } int main(int argv, char** argc) { OneDimensionalOptimization* one = new OneDimensionalOptimization(); double l = 0; double u = 2*3.1415926; double x; double res1 = one->quadraticInterpolationSearch(p,l,u,x,1e-10); return 1; }