版权声明:博主的博客不值钱随便转载但要注明出处 https://blog.csdn.net/easylovecsdn/article/details/84112101
问题背景:本次我们来求取 f(x) = -2x^3 + 5x^2 + 9,这个函数,在给定区间[2, 4]上的零点。
解决方法:二分法
编程语言:c++、python
说明:这里将分别使用两种编程语言和3种二分法的终止条件来完成二分的求解。
函数图像:
二分的终止条件:
1.区间小于某标准值
2.循环次数
3.真实误差小于某值 |(Xnew - Xold) / Xnew| * 100%
流程图:(偷个懒我这里之画一个)
c++篇
1.循环次数
//凭借循环次数来终止二分
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 9999;
double f(double x)
{
return -2 * x * x * x + 5 * x * x + 9;
}
int main()
{
double a = 2; //卡取两个端点值
double b = 4;
double mid;
if (f(a) > 0) //区间增函数
{
for (int i = 0; i <= maxn; i++)
{
mid = (a + b) / 2;
if (f(mid) == 0) break;
if (f(mid) > 0) a = mid;
else b = mid;
}
}
else //区间减函数
{
for (int i = 0; i <= maxn; i++)
{
mid = (a + b) / 2;
if (f(mid) == 0) break;
if (f(mid) > 0) b = mid;
else a = mid;
}
}
printf("f(%.3lf) = %.3lf\n", mid, f(mid));
return 0;
}
2.区间小于某标准值
//区间小于某值来终止二分
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double board = 1e-2;
double f(double x)
{
return -2 * x * x * x + 5 * x * x + 9;
}
int main()
{
double a = 2; //卡取两个端点值
double b = 4;
double mid;
if (f(a) > 0) //区间增函数
{
while (fabs(a - b) >= board)
{
mid = (a + b) / 2;
if (f(mid) == 0) break;
if (f(mid) > 0) a = mid;
else b = mid;
}
}
else //区间减函数
{
while (fabs(a - b) >= board)
{
mid = (a + b) / 2;
if (f(mid) == 0) break;
if (f(mid) > 0) b = mid;
else a = mid;
}
}
printf("f(%.3lf) = %.3lf\n", mid, f(mid));
return 0;
}
3.真实误差小于某值
//真实误差小于某值来终止二分
#include <iostream>
#include <cstdio>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std;
const double rate = 1e-2;
double f(double x)
{
return -2 * x * x * x + 5 * x * x + 9;
}
int main()
{
double a = 2; //卡取两个端点值
double b = 4;
double mid, r = INF;
if (f(a) > 0) //区间增函数
{
while (r > rate)
{
mid = (a + b) / 2;
if (f(mid) == 0) break;
if (f(mid) > 0)
{
r = fabs((mid - a) / a);
a = mid;
}
else
{
r = fabs((mid - b) / b);
b = mid;
}
}
}
else //区间减函数
{
while (r > rate)
{
mid = (a + b) / 2;
if (f(mid) == 0) break;
if (f(mid) > 0)
{
r = fabs((mid - b) / b);
b = mid;
}
else
{
r = fabs((mid - a) / a);
a = mid;
}
}
}
printf("f(%.3lf) = %.3lf\n", mid, f(mid));
return 0;
}
python篇
1.循环次数
# -*- coding: utf-8 -*-
#最大循环次数
maxn = 9999
#定义函数f(x)
def f(x):
return -2.0 * x**3 + 5.0 * x**2 + 9.0
#规定两区间端点
a = 2.0
b = 4.0
#进行二分
if f(a) > 0 :
for i in range(maxn) :
mid = (a + b) / 2;
if f(mid) == 0 : break
if f(mid) > 0 : a = mid
else : b = mid
else :
for i in range(maxn) :
mid = (a + b) / 2;
if f(mid) == 0 : break
if f(mid) > 0 : b = mid
else : a = mid
#输出结果
print("f(%.3lf) = %.3lf\n" %(mid, f(mid)))
2.区间小于某标准值
# -*- coding: utf-8 -*-
import math
#定义边界
board = 1e-2
#定义函数f(x)
def f(x):
return -2.0 * x**3 + 5.0 * x**2 + 9.0
#规定两区间端点
a = 2.0
b = 4.0
#进行二分
if f(a) > 0 :
while math.fabs(a - b) >= board :
mid = (a + b) / 2;
if f(mid) == 0 : break
if f(mid) > 0 : a = mid
else : b = mid
else :
while math.fabs(a - b) >= board :
mid = (a + b) / 2;
if f(mid) == 0 : break
if f(mid) > 0 : b = mid
else : a = mid
#输出结果
print("f(%.3lf) = %.3lf\n" %(mid, f(mid)))
3.真实误差小于某值
# -*- coding: utf-8 -*-
import math
#定义误差率,与最大值
rate = 1e-2
INF = 0x3f3f3f3f
#定义函数f(x)
def f(x):
return -2.0 * x**3 + 5.0 * x**2 + 9.0
#规定两区间端点
a = 2.0
b = 4.0
r = INF
#进行二分
if f(a) > 0 :
while r > rate :
mid = (a + b) / 2;
if f(mid) == 0 : break
if f(mid) > 0 :
r = math.fabs((mid - a) / a)
a = mid
else :
r = math.fabs((mid - b) / b)
b = mid
else :
while r > rate :
mid = (a + b) / 2;
if f(mid) == 0 : break
if f(mid) > 0 :
r = math.fabs((mid - b) / b)
b = mid
else :
r = math.fabs((mid - a) / a)
a = mid
#输出结果
print("f(%.3lf) = %.3lf\n" %(mid, f(mid)))
mid的变化趋势:
为了使变化折线明显这里将区间段点值改为[1, 3.9]
图像生成代码:
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
plt.figure(1)
#最大循环次数
maxn = 9999
#定义函数f(x)
def f(x):
return -2.0 * x**3 + 5.0 * x**2 + 9.0
#规定两区间端点
a = 1.0
b = 3.9
#图像生成所需要的集合
m = []
n = []
scope = np.linspace(2, 4, 100)
#进行二分
if f(a) > 0 :
for i in range(maxn) :
mid = (a + b) / 2;
m.append(mid)
n.append(f(mid))
if f(mid) == 0 :
break
if f(mid) > 0 :
a = mid
else :
b = mid
else :
for i in range(maxn) :
mid = (a + b) / 2;
if f(mid) == 0 :
break
if f(mid) > 0 :
b = mid
else :
a = mid
#输出结果
print("f(%.3lf) = %.3lf\n" %(mid, f(mid)))
#生成图像
plt.plot(m, n)
plt.show()
变化图像: