在某些算法的时间复杂度中找到常数c

时间:2015-02-09 05:17:35

标签: algorithm sorting time-complexity mergesort insertion-sort

我需要帮助通过检查其运行时间的结果来查找和近似插入排序(cn ^ 2)和合并排序(cnlgn)的复杂性中的常量c。

有一些背景知识,我的目的是实现插入排序和合并排序(递减顺序)算法并测量这两种算法的性能。对于每个算法,并且对于每个n = 100,200,300,400,500,1000,2000,4000,在输入

时测量其运行时间
  1. 已经排序,即n,n-1,...,3,2,1;
  2. 反向排序1,2,3,... n;
  3. 1,2,...,n的随机排列。
  4. 运行时间应排除初始化时间。"

    我已经完成了两种算法的代码,并将测量值(微秒)放在电子表格中。现在,由于每种算法的每个条件的值不同,我不确定如何找到这个c。

    供参考,时间表:

    
              InsertionSort                    MergeSort      
     n      AS    RS   Random              AS     RS    Random
    100     12    419     231              192    191     211
    200     13   2559    1398             1303   1299    1263
    300     20    236      94              113    113     123
    400     25    436     293              536    641     556
    500     32    504     246               91     81     105
    1000    65   1991     995              169    246     214
    2000     9   8186    4003              361    370     454
    4000    17  31777   15797              774    751     952
    
    

    如有必要,我可以提供代码。

4 个答案:

答案 0 :(得分:0)

几乎不可能确定这些常量的值,特别是对于使用缓存,管道和其他“性能事物”的现代处理器而言。

当然,您可以尝试找到近似值,然后您需要Excel或任何其他电子表格。

输入您的数据,创建图表,然后添加趋势线。电子表格会为您计算常量值。

答案 1 :(得分:0)

首先注意一些事项:

  1. 你的身材很小

    • 仅当n足够大时
    • ,算法复杂度才会对应于运行时
    • n=4000~4KB数据,它仍然适合大多数CPU CACHE,因此增加到至少n=1000000可以并且将会更改运行时与n之间的关系
  2. 运行时测量

    • 对于随机数据,您需要平均运行时间测量而不是单个
    • 因此对于任何n至少进行5次测量,每次测量使用不同的数据集,并使用所有
    • 的平均时间
  3. 现在如何获取c

    • 程序具有复杂性O(n^2)意味着足够大n运行时为t(n)= c * n ^ 2
    • 所以进行一些测量
    • 我从您的插入排序中选择最后3个,反向排序
    • 因为如果我没弄错的话,那应该与最坏情况下的O(n ^ 2)复杂度匹配。
    • 这样:

          c*n^2   =t(n)
          c*1000^2= 1.991 
          c*2000^2= 8.186 
          c*4000^2=31.777
      
    • 求解方程式

          c=t(n)/(n^2)
          c= 1.991/ 1000000=1.991 us
          c= 8.186/ 4000000=2.0465 us
          c=31.777/16000000=1.9860625 us
      
    • 如果一切正常,那么不同c的{​​{1}}应该相对相同

    • 在您的情况下,每个元素<{1}}
    • 但正如我上面提到的增加n,这将因CACHE使用而改变
    • 如果使用任何动态容器,则必须将其使用的复杂性包括在算法
    • 有时可能很重要......

答案 2 :(得分:0)

首先要了解的是,复杂性运行时间不一样,彼此之间可能没什么关系。

复杂度是一种理论测量,可以了解算法与较小输入相比如何减慢较大输入的速度或与其他算法相比较。

运行时间取决于具体实现,运行它的计算机,在同一台计算机上运行的其他程序以及许多其他内容。您还会注意到,如果输入对于您的缓存来说很大,则运行时间会变慢,如果它对您的RAM也很大,则会跳转另一个时间。正如你所看到的那样n = 200你有一些奇怪的运行时间。这无助于您找到常数。

如果您没有代码,则没有其他选择使用运行时间来近似复杂性。那么你应该只使用大输入(1000应该是你的情况下最小的输入)。如果您的算法是确定性的,只需输入最坏的情况。随机情况可能是好的也可能是坏的,所以你永远不会得到任何真正的复杂性。另一个问题是,复杂度测量“操作”,因此评估和if - 声明或递增变量是相同的,但在运行时,if需要的时间比递增的东西要多。< / p>

所以你可以做的是绘制你的复杂性和你测量的价值,并寻找一个有...的因素......

E.g。这是1/500浏览的图表以及图表中的点数。 enter image description here

答案 3 :(得分:0)

以4000个元素为例,将时间除以各自的复杂度估计值,4000²或4000 Lg 4000。

这并不比其他任何方法都差。

为安全起见,无论如何都要检查最后一个值是否在相对平滑的曲线上对齐,以便4000的值具有代表性。

正如其他人评论的那样,这种方法很差。您还应该考虑运行时间的标准偏差,甚至更好的运行时间直方图,并涵盖更大范围的尺寸。

另一方面,获得准确的值并不重要,因为了解常数的值无助于比较两种算法。