【历史背景】
秦九韶算法是中国南宋时期的数学家秦九韶表述求解一元高次多项式的值的算法——正负开方术。它也可以配合牛顿法用来求解一元高次多项式的根。在西方被称作霍纳算法(Horner algorithm或Horner scheme),是以英国数学家威廉·乔治·霍纳命名的。
【原理解释】
设有n+1项的n次函数
f(x)=anxn+ an-1xn-1+an-2xn-2+ an-3xn-3+…… a2x2+a1x+ a0
将前n项提取公因子x,得
f(x)=(anxn-1+ an-1xn-2+an-2xn-3+…… a2x+a1)+ a0
再将括号内的前n-1项提取公因子x,得
f(x)=((anxn-2+ an-1xn-3+an-2xn-4+…… a2)x+ a1)x+a0
如此反复提取公因子x,最后将函数化为
f(x)=(((anx+ an-1)x+ an-2)x+……+a1)x+a0
令f1= anx+ an-1
f2=f1x+ an-2
f3=f2x+ an-3
。。。
fn=fn-1x+ a0 则fn即为所求
【代码示例】
AlgorithmCalculatorService.java
/**
* 获取系数集合
* @param N 多项式个数
* @return 系数集合
*/
public static ArrayList<Double> getCoefficientList(Integer N) {
ArrayList<Double> AnList = new ArrayList<Double>();
//随机生成N个0到10之间的系数
Random random = new Random();
while(N > 0) {
AnList.add((double) (Math.round(random.nextFloat()*100)/10.0)); //随机一个[0-10]之间的一位小数
N--;
}
return AnList;
}
/**
* 执行传统算法并获取结果
* 模板为 An*X^n + An-1*X^n-1 + ... A1X + A0
* @param AnList 系数集合
* @param X X值
* @return 计算结果
*/
public static String getResultByTrandition(ArrayList<Double> AnList, Float X) {
int N = AnList.size() - 1;
Double result = 0D;
long start = System.currentTimeMillis(); //获取当前时间,单位为毫秒
for(Double An : AnList) {//遍历系数集合,每一次循环计算出一项的值,并相加
Double Xn = 1D;
int i = 0;
while(i<N) {
Xn = Xn*X;
i++;
}
N--;
result = result + An*Xn;
}
long end = System.currentTimeMillis();
String resultMsg = "计算结果: " + result + " ,耗时为:" + (end - start) + "毫秒!";
return resultMsg;
}
/**
* 执行秦九韶算法并获取结果
* 模板为((...(An*X + An-1)X + An-2)X + ... + A1)X + A0
* @param AnList 系数集合
* @return 计算结果
*/
@SuppressWarnings("unchecked")
public static String getResultByHorner(ArrayList<Double> anList, Float X) {
ArrayList<Double> AnList = (ArrayList<Double>) anList.clone();
Double V = (double)AnList.get(0);
AnList.remove(0);
long start = System.currentTimeMillis(); //获取当前时间,单位为毫秒
for(Double An : AnList) {
V = X*V + An;
}
long end = System.currentTimeMillis();
String resultMsg = "计算结果: " + V + " ,耗时为:" + (end - start) + "毫秒!";
return resultMsg;
}
public static void main(String[] args) {
ArrayList<Double> anlist = getCoefficientList(5);
String msg1 = getResultByTrandition(anlist, 3F);
System.out.println("传统算法: " + msg1);
String msg2 = getResultByHorner(anlist, 3F);
System.out.println("九韶算法: " + msg2);
}
传统算法: 计算结果: 8.992778799971419E137 ,耗时为:20毫秒!
九韶算法: 计算结果: 8.992778799971422E137 ,耗时为:0毫秒!
【结果分析】
当数据量较大时,在耗时方面秦九韶算法相比传统算法占据明显优势!