算法学习之自适应辛普森法

一.啥子是自适应辛普森法呢?

   简而言之,就是一种用二次函数来逼近被积函数。
   把求原来函数的积分换成求二次函数的积分的一种近似求积分的方法

二.自适应辛普森法的推导


什么?你想看推倒过程?
小小年纪怎么净想着推倒?
莫得推倒,这就是simpson公式(嘿嘿)
那这玩应和自适应辛普森法又有啥子关系呢?

所谓自适应

就是我们可以以二分的方式,把函数划分成一个个小的区间进行求和,使得函数划分的区间和精度满足题里的要求。
具体就是分别算两边simpson(l,mid)与simpson(mid,r),比较两者的和与simpson(l,r)的关系,如果误差足够小的话,就可以返回,否则继续二分计算。

三.模板题

T1 洛谷P4525 【模板】自适应辛普森法1
试计算积分

结果保留至小数点后6位。

数据保证计算过程中分母不为0且积分能够收敛。
这种沙雕题为什么要用辛普森公式,直接数学推导就行了
(下面的代码并没有辛普森公式,嘿嘿)

#include<cstdio>
#include<vector>
#include<algorithm>
#include <cmath>
#include <iostream>
using namespace std;
double a,b,c,d,l,r;
double ans1;
double ans2;
int main(){
   
	cin>>a>>b>>c>>d>>l>>r;
	if(a!=0){
   
	ans1=(c/a)*(r-l);
	ans2=(d-(b*c/a))/a*(log(fabs((a*r+b)))-log(fabs(a*l+b)));
	printf("%.6lf",ans2+ans1);		
	} 
    else if(a==0){
   
    	ans1=(c*r*r*0.5+d*r)/b;
    	ans2=(c*l*l*0.5+d*l)/b;
    	printf("%.6lf",ans1-ans2);
	}
	return 0;
} 

T2 P4526 【模板】自适应辛普森法2
试计算积分

保留至小数点后5位。若积分发散,请输出orz。
以我上学期学的啥也不是的数分进行了一个简单的判断,发现a<0的时候函数发散,否则收敛
我下学期好好学数分,争取不当个废物
然后用simpson乱搞一下就过了
上代码,么么哒

#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
double a;
double l,r,mid;
inline double f(double x){
   
	return pow(x,a/x-x);
}
inline double simpson(double l,double r){
   
   return (r-l)*(f(l)+f(r)+4.0*f((l+r)/2.0))/6.0;
}
inline double work(double l,double r,double ans){
   
    double mid=(l+r)/2.0;
	double ll=simpson(l,mid),rr=simpson(mid,r);
    if(fabs(ll+rr-ans)<=1e-9)return ans;
    return work(l,mid,ll)+work(mid,r,rr);
}
int main(){
   
	cin>>a;
	if(a<0) cout<<"orz";
	else printf("%.5lf",work(1e-9,20,simpson(1e-9,20)));
	return 0;
} 

唔,精度什么的随便yy一下就行啦
这两个题的数据还是比较水的呢,嘿嘿

全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务