俄罗斯农民乘法算法的时间效率

时间:2019-02-21 07:27:56

标签: algorithm language-agnostic

从时间效率的角度来看,用Russian peasant multiplication算法将n乘以m还是将m乘以n无关紧要?

例如,当计算26 * 47时,时间效率是否类似于47 * 26计算?

3 个答案:

答案 0 :(得分:1)

由于算法为floor(log2(k))的乘数(第一个数字)运行k个迭代,因此运行时间肯定取决于顺序。如果nm位于两个相同的两个连续幂之间,则它们将花费相同的迭代次数来完成。否则,请始终将较小的数字放在第一位以最小化运行时间。

答案 1 :(得分:1)

unsigned int russianPeasant(unsigned int a, unsigned int b) { 
    int res = 0;  // initialize result 
    // While second number doesn't become 1 
    while (b > 0) 
    { 
         // If second number becomes odd, add the first number to result 
         if (b & 1) 
             res = res + a; 
         // Double the first number and halve the second number 
         a = a << 1; 
         b = b >> 1; 
     } 
     return res; 
}

当b变为0时,算法退出while循环。循环运行的次数为[log2(b)] + 1次。

换挡几乎需要固定的时间(1个CPU周期)

以较小的值b调用是有意义的。

奖金:速度比较

我编写了上面的代码,并以相同的数字47和26循环运行了10 ** 8次。

a = 26,b = 47时,平均花费1336852.2微秒。

a = 47,b = 26,平均花费1094454.4微秒。

有趣的旁注:

尽管就像@Dillon Davis提到的那样,如果日志相同,则迭代次数应该相同,但我发现以b表示的次数仍然较少。

(所有时间均以微秒为单位)
a = 46,b = 36-1204240.6
a = 36,b = 46-1295766.8

a = 44,b = 36-1204266.2
a = 36,b = 44-1253821.17。

TLDR: 以较小的第二个数字(while循环中的一个)运行

源代码:https://www.geeksforgeeks.org/russian-peasant-multiply-two-numbers-using-bitwise-operators/

答案 2 :(得分:0)

这取决于您如何实现俄罗斯农民算法。可以是:

  • a*b更快
  • b*a更快
  • 没有区别

我选择无差异,因为实数的数学乘法是可交换的:a*b=b*a,并且由于最终用户在调用函数时不希望打扰顺序争论

要做到这一点,您需要调整代码,例如:

Let the two given numbers be 'a' and 'b'.
1) If 'b' is greater than 'a' - swap 'a' with 'b'
2) Initialize result 'res' as 0.
3) Do following while 'b' is greater than 0
   a) If 'b' is odd, add 'a' to 'res'
   b) Double 'a' and halve 'b'
4) Return 'res'.

此代码会很复杂

  

O(log 2(min(a,b)))