[英]Calculate Big-O Complexity
我最终会给这个程序一个类似60,000个400像素图像的输入文件,所以我试着想一想这个代码如何用大输入运行。 为了便于阅读,我用“blah”和所有带有简单字母( nn
, mm
和kk
)的ArrayList名称替换了不重要的东西。
for (Perceptron P : nn){
//blah
}
for (Perceptron P : mm) {
//blah
}
for (Perceptron P : kk){
//blah
}
for (Perceptron P : mm) {
for (int i = 0; i < nn; i++) {
//blah
}
for (int j = 0; j < kk; j++){
//blah
}
}
for (Perceptron X : nn){
for (Perceptron Y : mm){
//blah
}
}
for (Perceptron Z : kk){
for (Perceptron Y : mm){
//blah
}
}
我认为答案是O( nn+mm+kk+mm(nn+kk)+nnmm+kkmm
)。 如果我知道nn
是400, mm
是300, kk
是10,那么这是O(246710)。 但是现在我被卡住了。 我真的不知道O(246710)是什么意思。 我是否必须一次仅针对其中一个变量计算big-O? 如果是这样,那会有什么好处呢? 我只是想知道这将如何表现。 谢谢
Big-O仅涉及运行时间中的最大项,在这种情况下为O(mm*(nn+kk))
。 生成此术语的代码部分是以下嵌套循环:
for (Perceptron P : mm) {
for (int i = 0; i < nn; i++) {
//blah
}
for (int j = 0; j < kk; j++){
//blah
}
}
如果你告诉我们kk
, mm
和nn
与图像的实际大小有什么关系,那么我们可以用更有意义的术语来限制你的运行时间。
O(N)意味着程序的执行时间与N成线性比例。因此,O(246710)并不意味着什么。
程序的复杂程度实际上是O(mm *(nn + kk))。 这并没有告诉你任何关于输入特定尺寸需要多长时间的事情(为此,你需要知道所有单独操作需要多长时间),只有当mm
的尺寸加倍时,才会告诉你。所有其他条件都保持不变,那么你的程序执行时间大约是以前的两倍。
Big O并没有按照你的想法使用。 它用于确定最坏情况。 现在,如果nn
, mm
, kk
在数据存储中都是线性的,而非嵌套那么它就是O('the-largest-chain')
。 现在我们不知道nn
, mm
和kk
之间的关系,所以我能告诉你的最好的是; 因为你永远不会将它们与自己嵌套,所以它是线性的。
两个简单的例子来展示它的实际效果。
输入:
int[] arr = {1,2,3}
示例#1
for (int i : arr) {
// do something
}
在这种情况下,Big-O只是O(n)
,因为你只是从数组的开始到完成迭代,它与元素成正比。
例#2
for (int i : arr) {
for (int j : arr) {
// do something
}
}
现在输入和算法之间的关系是二次的,给你O(n2)
。
我建议在这里阅读 ,或者按照教程,因为它可以澄清比我的答案更多。
在你的情况下,你永远不会嵌套输入,并且因为没有给出变量之间的直接关系,所以Big-O将只是添加它们。 在你的情况下,应该是O(mm(nn+kk))
。
通过算法的运行时分析,您可以得到最坏情况 , 平均情况和最佳情况,但算法的顺序比处理器的速度更重要。 这与算法执行的操作数相关。 (也记为n )
以下是使用Big-O-Notation的一些示例:
线性: 60n + 5
或O(n)。 这意味着它需要n次操作,这是你的共同循环
二次方: 2n^2 + 2n
或O(n ^ 2)。 这在嵌套循环中很常见
对数: number of digits in n
或O(1)中number of digits in n
。 这在字典中使用,并且在很少的操作之后将访问元素。 (尝试并记住在适用的情况下应用此表现。)
当大小变为无穷大时,Big-O表示法表示输入大小方面的时间。
首先,您必须决定输入变量 。 在您的示例中,nn,mm和kk是输入变量。
然后我们计算我们需要做多少次迭代:
nn + mm + kk + mm(nn + kk) + nn + kk
简化:
2nn + 2kk + mm(nn + kk + 1)
我们有3个项,但是当所有项都进入无穷大时,只有具有最高渐近增长顺序的项才有意义,即mm(nn + kk + 1) 。 你应该检查渐近的命令,因为在这个答案中解释它太长了。
我们将mm(nn + kk + 1)简化为mm(nn + kk),因为当它变为无穷大时,常数不重要(不缩放)。
现在我们有mm(nn + kk) ,在这里我们选择nn和kk中增长较快的一个,如何知道哪个增长更快? 这取决于你的输入。 假设我们选择nn,那么我们有O(mm * nn) 。 属于O(n ^ 2)类别。
假设所有输入大小都向无穷大方向移动,那么大O符号应该减少到算法的最大最坏情况分母。
所以你的表达式O(nn + mm + kk + mm(nn + kk)+ nnmm + kkmm)应该减小到O(mmnn + mmkk)。
我认为关于复杂度O(nn + mm + kk + mm(nn + kk)+ nnmm + kkmm)的确切表达是正确的。 它用变量测量复杂度的变化,所以不要用值替换变量,在nn = 400,mm = 300,kk = 10的情况下,它可以简化为O(nn mm)或O(nn nn)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.