#include
#include
#define F(x)(3*x*x*x-4*x+2)
double fun1(double x);
void goAndBackSectionPrint(double x1, double h, double (*f)(double), double *ret1, double *ret2);
void goldenSecton(double x0, double h, double (*f)(double), double e);
int main(void){
goldenSecton(0, 1, fun1, 0.1);
return 0;
}
//进退法打印区间
//x1搜索初值
//h搜索步长
//f 待搜索函数f(x)的指针
//ret1 ret2 返回区间指针
void goAndBackSectionPrint(double x1, double h, double (*f)(double), double *ret1, double *ret2){
double a1 = x1;
double y1 = (*f)(a1);
double a2 = a1 + h;
double y2 = f(a2);
double a3 = 0;
double y3 = 0;
if(y2 > y1){
h = -h;
a3 = a1;
y3 = y1;
a1 = a2;
y1 = y2;
a2 = a3;
y2 = y3;
}
a3 = a2 + h;
y3 = f(a3);
while(y3 < y2){
h = 2*h;
a1 = a2;
y1 = y2;
a2 = a3;
y2 = y3;
a3 = a2 + h;
y3 = f(a3);
}
*ret1 = a1;
*ret2 = a3;
printf("a1 = %f, y1 = %f.\n", a1, y1);
printf("a2 = %f, y2 = %f.\n", a2, y2);
printf("a3 = %f, y3 = %f.\n", a3, y3);
}
//黄金分割法
//进退法打印区间
//x0搜索初值
//h搜索步长
//f 待搜索函数f(x)的指针
//e 误差要求
void goldenSecton(double x0, double h, double (*f)(double), double e){
double a, b;
const double ratio = 0.618;
goAndBackSectionPrint(x0, h, f, &a, &b);
printf("确定区间为 [%f, %f].\n", a, b);
double a1 = b - ratio*(b - a);
double y1 = f(a1);
double a2 = a + ratio*(b - a);
double y2 = f(a2);
do{
if(y1 >= y2){
a = a1;
a1 = a2;
y1 = y2;
a2 = a + ratio*(b - a);
y2 = f(a2);
}
else{
b = a2;
a2 = a1;
y2 = y1;
a1 = b - ratio*(b - a);
y1 = f(a1);
}
}while((fabs((b-a)/b) >= e) || (fabs((y2-y1)/y2) >= e));
printf("a = %f, f(a) = %f.\n", a, f(a));
printf("b = %f, f(b) = %f.\n", b, f(b));
double minVal = (a+b)/2;
printf("函数的最小值点为:%f。\n", minVal);
printf("函数的最小值为: %f。\n", f(minVal));
}
double fun1(double x){
return F(x);
}