从运行时间确定时间复杂度的最简单方法

时间:2010-10-14 05:35:41

标签: math complexity-theory big-o curve-fitting

让我们假设我正在尝试分析算法,我所能做的就是使用不同的输入运行它。我可以构造一组点(x,y)为(样本大小,运行时间)。 我想动态地将算法分类为复杂性类(线性,二次,指数,对数等)。 理想情况下,我可以给出一个或多或少接近行为的等式。 我不知道最好的办法是什么。

对于任何度数多项式,我都可以创建回归曲线并得出一些适应度,但我真的不知道如何为任何非多项式函数做到这一点。由于我以前没有任何关于我应该尝试适合的形状的知识,因此更难。

这可能更像是一个数学问题,而不是一个编程问题,但它对我来说非常有趣。我不是数学家,所以可能有一个更简单的建立方法,从一组我不知道的点中获得合理的函数。有没有人有解决这样的问题的想法?是否有一个C#的数字库可以帮助我处理这些数字?

2 个答案:

答案 0 :(得分:2)

那么你真的不关心那么多的复杂性类,所以我们说:线性,二次,多项式(度> 2),指数和对数。

对于其中每一个,您可以使用最大(x,y)对来求解未知变量。设y = f(x)表示算法的运行时间与样本大小的函数关系。假设f(1)= 0,如果不是,我们总是可以从每个y中减去该值y(1),这只是消除了f(x)中的常数。设y(end)表示(x,y)数据集中y的最后(和最大)值。

此时我们可以解决每种规范形式的未知:

f(x) = c*x
f(x) = c*x^2
f(x) = x^c
f(x) = c^x
f(x) = log(x)/log(c)

由于每个等式中只有一个未知数,我们可以为您解决任何问题。考虑从随机度的多项式生成的以下数据> 2:

x = [ 1 2 3 4 5 6 7 8 9 10 ];
y = [ 0 6 19 44 81 135 206 297 411 550 ];

如果我们使用最后一个点来解决每个可能性的c(假设这将是最小的噪声估计)

550 = c*10    -> c = 55
550 = c*10^2  -> c = 5.5
550 = 10^c    -> c = log(550)/log(10) ~= 2.74
550 = c^10    -> c = 550^(1/10) ~= 1.88
550 = log(x)/log(c) -> c = 10^(1/550) ~= 1.0042

我们现在可以比较这些函数与剩余数据的匹配程度,这是一个图:

我是新手,我无法发布图片,所以请看这里的情节:http://i.stack.imgur.com/UH6T8.png

真实数据显示在红色星号,与绿线呈线性关系,蓝色为二次方,黑色为多项式,粉红色为指数,绿色为O的对数图。从残差中可以清楚地看出哪种函数最适合您的数据。

答案 1 :(得分:1)

曲线拟合曾经是一门艺术,但现在有点颓废:)(对于物理学家来说这是一个笑话)

已经取得了很多进展,允许简单的凡人猜测(某些)非平凡的功能依赖。

我不会对方法和限制进行描述,但我会将您推荐给eureqa,这是康奈尔大学开发的一个非常好的软件。

  

Eureqa(发音为“eureka”)是一种用于检测数据中方程式和隐藏数学关系的软件工具。其目标是确定最简单的数学公式,这些公式可以描述产生数据的潜在机制。 Eureqa可免费下载和使用。查找程序下载,视频教程,用户论坛以及其他和参考资料。   

如果模型不是太复杂的话,我尝试了几次eureqa并取得了很好的效果。我认为它足以区分多项式,日志和指数。

HTH!

Post Scriptum:

令人遗憾的是该软件不再免费:(