二分法求多项式曲线区间极值
二分法求解,设置left为左边界,right为右边界,则解一定位于left和right之间,当左右边界之间的差值小于某一精确度时,就认为找到了解。具体操作如下,若是先减后增,首先判断左右边界差值作为循环条件,接着每次循环找到左右边界的中间值,一旦该点导数值小于0,说明该点的右侧存在正确解,则将左边界设置为该点,反之将右边界缩进,左右边界通过循环不断的向正确解缩进(先增后减与之相反)。满足某一精确度后即可输出结果(注意这里的函数在区间中是比较常规简单的单调函数)。
代码如下:
#include <vector>
#include <iostream>
using namespace std;
//计算多项式曲线的在x处的值
double fx(vector<double> coefficient, double x)
{
double fx = coefficient[coefficient.size() - 1];
for (int i = coefficient.size() - 2; i >= 0; i--)
{
fx = fx*x + coefficient[i];
}
return fx;
}
//计算多项式曲线的导函数在x处的值
double fdx(vector<double> coefficient, double x)
{
vector<double> coefficient_df;//导函数系数数组
for (int i = 1; i < coefficient.size(); i++)
{
coefficient_df.push_back(coefficient[i] * i);
}
double fdx = coefficient_df[coefficient_df.size() - 1];
for (int i = coefficient_df.size() - 2; i >= 0; i--)
{
fdx = fdx*x + coefficient_df[i];
}
return fdx;
}
int main()
{
vector<double> m_coefficient;//多项式曲线系数数组
m_coefficient.push_back(3813.237503);
m_coefficient.push_back(2409.040543);
m_coefficient.push_back(412.086525);
m_coefficient.push_back(20.007034);
m_coefficient.push_back(-0.887868);
m_coefficient.push_back(-0.078038);
m_coefficient.push_back(0.002762);
m_coefficient.push_back(0.000329);
m_coefficient.push_back(0.000007);
double left = -10.0, right = 0.0;//设置区间范围
int count = 0;
double preci = 1e-6;//设置精确度
while (right - left>preci) //若超时,在保证精度的情况下,可以改成count++<100
{
double mid = (left + right) / 2.0;
if (fdx(m_coefficient,mid)<0)//左减右增
//if (fdx(m_coefficient, mid)>0)//左增右减
{
left = mid;
}
else
{
right = mid;
}
}
cout << "left:" << left << endl;
cout << "fx(left):" << fx(m_coefficient, left) << endl;
cout << "right:" << right << endl;
cout << "fx(right):" << fx(m_coefficient, right) << endl;
}
运行结果如下: