zoukankan      html  css  js  c++  java
  • HDU.2899.Strange fuction(牛顿迭代)

    题目链接

    (Description)

      求函数(F(x)=6 imes x^7+8 imes x^6+7 imes x^3+5 imes x^2-y imes x)(xin left[0,100 ight])时的最小值。

    (Solution)

      (xgeq 0)(F(x))为单峰凹函数,三分即可。
      而且由此可知(F(x))的导数应是单增的。函数最值可以转化为求导数零点问题,于是也可以二分求(F'(x))的零点,或者用牛顿迭代求。
      峰值函数最值也可以用模拟退火求。
      练习下牛顿迭代。其它代码可以见这

      牛顿迭代:$$x=x_0-frac{F(x_0)}{F'(x_0)}$$
      对(F(x))泰勒展开,(F(x)=F(x_0)+F'(x_0)(x-x_0)+frac{F''(x_0)}{2!}(x-x_0)^2+ldots+frac{F^{(n)}(x_0)}{n!}(x-x_0)^n+R_n(x))
      为方便计算?只保留线性部分(F(x)=F(x_0)+F'(x_0)(x-x_0)),令其等于(0)
      就可以得到(x=x_0-frac{F(x_0)}{F'(x_0)})
      多次迭代、多次选取(x_0)即可。

    //0MS	1628K
    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    #define eps (1e-7)
    
    double y;
    inline double f(double x){
    	return 6*pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*x*x-y*x;
    }
    inline double fd(double x){
    	return 42*pow(x,6)+48*pow(x,5)+21*x*x+10*x-y;
    }
    inline double fdd(double x){
    	return 252*pow(x,5)+240*pow(x,4)+42*x+10;
    }
    double Get_zero(double x)//求导函数零点 
    {
    	double las=x+1;
    	while(fabs(las-x)>eps) las=x, x=x-fd(x)/fdd(x);
    	return x;
    }
    
    int main()
    {
    	int T; scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%lf",&y);
    		double ans=1e15;
    		for(int i=0; i<=100; i+=10) ans=std::min(ans,f(Get_zero(i)));
    		printf("%.4lf
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Install Postgresql on Ubuntu
    Pytest
    Pytest
    wrk 压力测试
    Objective-C 格式化字符串Format
    安装BeyondCompare on Ubuntu
    eclipse + python + pydev (Pydev安装成功确看不到插件的解决办法)
    如何解决: Ubuntu 系统 adb devices出现no permissions
    oracle rac搭建
    CentOS6.8编译安装LAMP
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9162128.html
Copyright © 2011-2022 走看看