在分析算法的有效性时,我有兴趣了解除空间和时间之外的参数。例如,我们可以在开发加密算法时专注于有效的陷阱功能。您还能想到其他什么?
答案 0 :(得分:8)
首先,正确性。无论输入是什么,请确保您的算法始终有效。即使对于算法未设计处理的输入,您也应该打印错误消息,而不是使整个应用程序崩溃。如果您使用贪心算法,请确保它们真正适用于所有情况,而不仅仅是您手动尝试的几种情况。
然后是实际效率。在实践中,O(N 2 )算法可以比O(N)算法快得多。做实际测试并且不要太依赖理论结果。
然后易于实施。您通常不需要最佳的介绍排序实现来对100个整数的数组进行一次排序,所以不要打扰。
查看算法中的最坏情况,如果可能,请尽量避免使用它们。如果你有一个通常很快的算法,但是最坏的情况非常糟糕,考虑检测最坏的情况,并使用另一种通常较慢但更好的单一情况的算法来解决它。
考虑空间和时间的权衡。如果你能负担得起内存以获得更好的速度,那么可能没有理由不去做,特别是如果你真的需要速度的话。如果你买不起记忆,但可以放慢速度,那就去做吧。
如果可以,请使用现有库。如果您可以使用GMP,请不要滚动自己的多精度库。对于C ++来说,诸如boost,甚至是STL容器和算法之类的东西已经被一大群人所使用了很多年,而且很可能比单独使用它更好。
答案 1 :(得分:6)
稳定性(排序) - 算法是否保持相等元素的相对顺序?
数字稳定性 - 当使用非常大或小的实数时算法是否容易出错?
正确性 - 算法是否始终给出正确的答案?如果没有,误差幅度是多少?
一般性 - 算法在许多情况下是否有效(例如,有多种不同的数据类型)?
紧凑性 - 算法程序是否简洁?
可并行性 - 当并发执行线程数增加时,性能如何扩展?
缓存意识 - 算法是否旨在最大限度地利用计算机的缓存?
缓存遗忘 - 算法是针对特定的缓存大小/缓存行大小进行调整,还是与缓存的参数无关地运行良好?
答案 2 :(得分:5)
稳定性 - 某些算法可能会在某些测试条件下“爆炸”,例如:需要花费非常长的时间来执行,或者使用非常大量的内存,或者甚至不能终止。
答案 3 :(得分:5)
复杂性。 2个算法在所有其他方面都是相同的,更简单的算法将成为未来定制和使用的更好的候选者。
易于并行化。根据您的使用情况,它可能没有任何区别,或者另一方面,使算法无用,因为它不能使用10000个核心。
答案 4 :(得分:4)
对于执行浮点运算的算法,通常需要考虑舍入误差的累积。
答案 5 :(得分:4)
嵌入式算法的功耗(想想智能卡)。
答案 6 :(得分:3)
在算法分析中经常测量的一个重要参数是Cache命中和缓存未命中。虽然这是一个非常依赖于实现和体系结构的问题,但可以进行一些概括。该算法的一个特别有趣的特性是Cache-oblivious,这意味着该算法将在具有不同高速缓存大小和结构的多台机器上最佳地使用高速缓存而无需修改。
答案 7 :(得分:3)
时间和空间是最重要的,它们似乎如此简单明确,通常应该 限定 (1)。 OP使用单词“参数”而不是说“标准”或“属性”的事实在某种程度上表明了这一点(好像时间和空间上的大O值足以构建基础算法。) 其他标准包括:
(1)“ qualified ”:正如在其他答案中暗示的那样,可以发现-technical-O(n ^ 2)算法比O(n)算法更快,< em> 90%的案例(其中,顺便说一下,可能是100%的实际案例)
答案 8 :(得分:2)
最坏情况和最佳情况也很有趣,特别是当链接到输入中的某些条件时。如果您的输入数据显示某些属性,则通过利用此属性,算法可能比执行相同任务但不使用该属性的另一算法执行得更好。
例如,当输入以特定方式部分排序时,许多排序算法非常有效地执行,这最小化了算法必须执行的操作的数量。 (如果您的输入主要是排序的,插入排序将很好地适合,否则您将永远不会使用该算法)答案 9 :(得分:2)
如果我们一般都在谈论算法,那么(在现实世界中)你可能不得不考虑CPU /文件系统(读/写操作)/带宽使用。
确实,他们在你需要担心的事情列表中走得很远,但是如果有足够大量的数据和足够便宜的基础设施,你可能需要调整你的代码以便在一个或另一个上轻松自如。 / p>
答案 10 :(得分:1)
您感兴趣的不是参数,而是算法的内在属性。
无论如何,您可能感兴趣的另一个属性,并分析算法,关注启发式(或更确切地说,approximation algorithms),即找不到精确解决方案的算法但是而且(希望)足够好。
在最坏的情况下,您可以分析解决方案与理论最优解的距离。例如,现有算法(忘记哪一个)将最佳旅行推销员旅行近似为两倍,即在最坏的情况下,它是最佳旅行的两倍。
另一个指标涉及randomized algorithms,其中随机化用于防止不必要的最坏情况行为。一个例子是随机快速排序; quicksort的运行时间最短 O ( n 2 ),我们希望避免这种情况。通过预先对阵列进行混洗,我们可以以非常高的概率避免最坏情况(即已经排序的阵列)。只要多高这个概率可能很重要;这是算法的另一个内在属性,可以使用随机分析。
答案 11 :(得分:1)
对于数值算法,还有连续性的属性:也就是说,如果稍微改变输入,输出也只会稍微改变。另请参阅Lambda The Ultimate上的Continuity analysis of programs以进行讨论,并链接到学术论文。
对于懒惰语言,还有严格性:f
被称为严格f _|_ = _|_
(其中_|_
表示bottom(在某种意义上)域理论),由于非终止,错误等而无法产生结果的计算,否则它是非严格的。例如,函数\x -> 5
不严格,因为(\x -> 5) _|_ = 5
,而\x -> x + 1
是严格的。
另一个属性是确定性:算法的结果(或其他属性,如运行时间或空间消耗)是否仅取决于其输入。
答案 12 :(得分:0)
关于各种算法质量的其他答案中的所有这些内容都很重要,应予以考虑。
但是时间和空间是两个与输入(n)的大小相比以某种速率变化的东西。那么还有什么可以根据n?
而变化有几个与I / O相关。例如,对磁盘的写入次数很重要,单独的空间和时间估计可能无法直接显示。对于闪存而言,这一点尤为重要,因为在某些算法中,写入到同一存储位置的次数是显着的指标。
另一个I / O指标是“chattiness”。网络协议可能更频繁地发送更短的消息,与另一个网络协议相加的空间和时间相同,但系统的某些方面(可能是计费?)可能会使所需消息的大小或数量最小化。
这将我们带到了Cost,这有时是一个非常重要的算法考虑因素。算法的成本可能会受到不同数量的空间和时间的影响(考虑服务器存储空间的单独成本和数据传输的千兆位数),但成本是您希望最小化的因素,因此它可能具有自己的大O估计。