首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

多项式求的两种方法运行时间与理论值不符,为什么?该如何处理

2012-03-02 
多项式求的两种方法运行时间与理论值不符,为什么?求多项式FxA(n)*X(n)+A(n-1)*X(n-1)+....+A(0)//A(i)为

多项式求的两种方法运行时间与理论值不符,为什么?
求多项式Fx=A(n)*X(n)+A(n-1)*X(n-1)+....+A(0)   //A(i)为系数,X(i)为X的i次幂
方法1:
Fx=(   (A(n)*X+A(n-1))*X+A(n-2)   )*X+...A(0)
C++的代码为:
Fx=a[N-1];//Fx初始值,a[0--n-1]为系数
for(int   i=N-1;i> =1;i--)
{
  Fx=Fx*x+a[i-1];    
}
方法2:
Fx=a[0];//Fx初始值
X=x;
for(int   i=1;i <N;i++)
{
    b=a[i]*X;
    Fx=Fx+b;  
    X=X*x;  
}
/************************/
理伦分析,
方法1中操作步数为:
'* '操作n-1次
'+ '操作n-1次
方法2中操作步数为:
'* '操作2*(n-1)次
'+ '操作n-1次
可知方法1比方法2少n-1次 '* '操作,其优于方法2.
然而,如果运行两种方法的话(VC6.0),发现方法2用的时间少于方法1.
以下是本人写的代码,求CSDN中的高手们帮帮小弟,说一下为什么.
/**************************************************************/
#include   <iostream.h>
#include   <ctime>
void   method1(   double   x,   double*   a,   double   Fx);
void   method2(   double   x,   double*   a,   double   Fx);
const   long   N0=10000000;//两种方法各重复做的次数
const   long   N=100;
const   long   NUM=10;
void   main(void)
{
        double   x=2;                   //给x赋值
        double   a[N];
        double   Fx;
        for(int   i=0;i <N;i++)//initialize   the   array,其为多项式的系数
{
a[i]=i+1;
}
cout < < "The   first: " < <endl;   //第一次测试两种方法
Fx=0;
method2(x,a,Fx);
                  Fx=0;
method1(x,a,Fx);

cout < < "The   second: " < <endl;//第二次测试两种方法,
                                                                      //但调用两种方法次顺相反
Fx=0;
method1(x,a,Fx);
Fx=0;
method2(x,a,Fx);
}
void   method1(double   x,   double*   a,   double   Fx)
{
clock_t   start,finish;
double   time;
                  Fx=a[N-1];           //initialize   the   Fx
start=clock();
for(int   j=1;j <=N0;j++)//repeat   N0次
{
/**方法1核心代码**/
                                    Fx=a[N-1];
for(int   i=N-1;i> =1;i--)
{
Fx=Fx*x+a[i-1];
}
}
finish=clock();
cout < < "Dida= " < <finish-start < <endl;
time=(finish-start)/(CLK_TCK+0.0);
cout < < "Time   used   in   method1= " < <time/N0 < <endl;
cout < < "Fx= " < <Fx < <endl;  
}
void   method2(double   x,   double*   a,   double   Fx)
{
double   b=0;
double   X;
clock_t   start,finish;
double   time;
        Fx=a[0];                                         //initialize   the   Fx
start=clock();
for(int   j=1;j <=N0;j++)//repeat   N0次


{
/**方法2核心代码**/
                                    Fx=a[0];
                  X=x;
for(int   i=1;i <N;i++)
{
                                        b=a[i]*X;
    Fx=Fx+b;  
    X=X*x;  
}
}
finish=clock();
cout < < "Dida= " < <finish-start < <endl;
time=(finish-start)/(CLK_TCK+0.0);
cout < < "Time   used   in   method2= " < <time/N0 < <endl;
cout < < "Fx= " < <Fx < <endl;
}
/************************************************************/
运行结果:
/************************************/
The   first:
Dida=11281
Time   used   in   method2=1.1281e-006
Fx=1.25497e+032
Dida=13172
Time   used   in   method1=1.3172e-006  
Fx=1.25497e+032
The   second:
Dida=13297
Time   used   in   method1=1.3297e-006
Fx=1.25497e+032
Dida=11110
Time   used   in   method2=1.111e-006
Fx=1.25497e+032
Press   any   key   to   continue
/***********************************/
(程序中两种方法各重复了N0=10000000)
方法1中两次用的滴答数分别为:13172,13297
方法2中两次用的滴答数分别为:11281,11110
可知方法1所用时间是多于方法2的.



[解决办法]
从算法角度说两种方法的复杂度是一样的,就差一个常数,很难说那种好。

从具体程序来说,涉及的内容就不同了。方法1的方法每次迭代有数据依赖性(Fx)。所以方法二更适合现在的CPU并行执行(现在的CPU可是超标量的,每个时钟周期可以执行多条指令)。而且这个结果也和编译器,编译参数以及执行的cpu有关。你测出的时间差也只有20%左右,差距也不大。

[解决办法]
支持楼上的!
大O表示法只能度量算法的阶,不可能精确度量运行时间。只能说大O表示法所表示的复杂度近似的表示了算法的性能,但是并不是说复杂度低的算法在实际中效率一定比复杂度高的算法好,因为有常数因子的作用以及编译有关。
[解决办法]
主要原因是这样,编译器会循环展开,减少数据冲突,近似并行。
[解决办法]
"Fx=Fx*x+a[i-1]; "的右端表达式复杂,编译器要化更多的时间进行分析,
先要确定计算步骤,才能进行计算,而且计算时也一定会利用堆栈来实现,
而不是直接地址,速度就会变慢,而第二种方案没有这种问题,你已经为它
确定了每一个步骤(加,乘),CPU立刻就可进行运算,用不着分析,所以就快.
[解决办法]
试试N=10000;

热点排行