【问题标题】:O Notation HelpO 符号帮助
【发布时间】:2010-12-07 18:46:11
【问题描述】:

我被本周的课堂作业困住了,这是我真的很想学习的主题,所以有一次我想我会做额外的阅读!!!!

该方法是为我们提供的,我只是编写一些测试用例。这是我的知识变得有点模糊的地方。如果时间增加,那么我低估了我认为的复杂性?在这种情况下,n^3 不够,n^4 太多,因此逐渐减少到 0。

这意味着在 2 之间存在一个复杂性,这就是 log n 出现的地方,因为 log n 是一个小于 n 的值?但这是据我所知

我真的希望有人能用比讲座幻灯片上的解释更好的解释为我解开这个困惑,因为它们对我毫无意义,谢谢

/**
 * Number 5
 */
public int Five(int n)
{
    int sum=0; 
    for(int i=0; i<n; i++){
        for(int j=0; j<i*i; j++){
            sum++;
        }
    }

    return sum;
}

   public void runFive()
    {
// Test n^2 complexity 
//         System.out.println("We are passing the value 5, This returns us an n value of " + Five(5) + " , With a time complexity of " + complexityN2(Five(5), 5) + " This is to test the value of 5 in a n^2 test" );
//         System.out.println("We are passing the value 10, This returns us an n value of " + Five(10) + " , With a time complexity of " + complexityN2(Five(10), 10) + "This is to test the value of 10 in a n^2 test" );
//         System.out.println("We are passing the value 100, This returns us an n value of " + Five(100) + " , With a time complexity of " + complexityN2(Five(100), 100) + "This is to test the value of 100 in a n^2 test" );
//         System.out.println("We are passing the value 1000, This returns us an n value of " + Five(1000) + " , With a time complexity of " + complexityN2(Five(1000), 1000) + "This is to test the value of 1000 in a n^2 test" );
//         System.out.println("We are passing the value 10000, This returns us an n value of " + Five(10000) + " , With a time complexity of " + complexityN2(Five(10000), 10000) + "This is to test the value of 10000 in a n^2 test" );

// Test n^3 complexity          
//         System.out.println("We are passing the value 5, This returns us an n value of " + Five(5) + " , With a time complexity of " + complexityN3(Five(5), 5) + " This is to test the value of 5 in a n^3 test" );
//         System.out.println("We are passing the value 10, This returns us an n value of " + Five(10) + " , With a time complexity of " + complexityN3(Five(10), 10) + "This is to test the value of 10 in a n^3 test" );
//         System.out.println("We are passing the value 100, This returns us an n value of " + Five(100) + " , With a time complexity of " + complexityN3(Five(100), 100) + "This is to test the value of 100 in a n^3 test" );
//         System.out.println("We are passing the value 1000, This returns us an n value of " + Five(1000) + " , With a time complexity of " + complexityN3(Five(1000), 1000) + "This is to test the value of 1000 in a n^3 test" );
//         System.out.println("We are passing the value 10000, This returns us an n value of " + Five(10000) + " , With a time complexity of " + complexityN3(Five(10000), 10000) + "This is to test the value of 10000 in a n^3 test" );
//         

//Test n^4 complexity
        System.out.println("We are passing the value 5, This returns us an n value of " + Five(5) + " , With a time complexity of " + complexityN4(Five(5), 5) + " This is to test the value of 5 in a n^3 test" );
        System.out.println("We are passing the value 10, This returns us an n value of " + Five(10) + " , With a time complexity of " + complexityN4(Five(10), 10) + "This is to test the value of 10 in a n^3 test" );
        System.out.println("We are passing the value 100, This returns us an n value of " + Five(100) + " , With a time complexity of " + complexityN4(Five(100), 100) + "This is to test the value of 100 in a n^3 test" );
        System.out.println("We are passing the value 1000, This returns us an n value of " + Five(1000) + " , With a time complexity of " + complexityN4(Five(1000), 1000) + "This is to test the value of 1000 in a n^3 test" );
        System.out.println("We are passing the value 10000, This returns us an n value of " + Five(10000) + " , With a time complexity of " + complexityN4(Five(10000), 10000) + "This is to test the value of 10000 in a n^3 test" );

    }        

这里是复杂的方法

public double complexityN2(double time, double n)
{
    return time / (n * n);
}

public double complexityN3(double time, double n)
{
    return time / (n * n * n);
}

 public double complexityN4(double time, double n)
{
    return time / (n * n * n * n);
}

public double complexityLog(double time, double n)
{
    return time / (Math.log(n) * (n*n));
}

【问题讨论】:

  • n^2、n^3 和 n^4 比较产生什么样的输出?
  • 我当然希望你的作业问题比这更多。首先,他们应该要求您草绘证明该方法的 O 复杂性。你知道这真的很容易......

标签: java algorithm big-o time-complexity


【解决方案1】:

请记住,大 O 表示法描述了项目数量接近无穷大时的行为。因此,在处理几乎任何实际计算量时,您不应该期望看到精确匹配。事实上,在任何情况下,您都不一定会看到一个 exact 拟合——它可能会渐近地接近一个拟合,但即使(从实际的角度来看)所涉及的数字非常大,它仍然不是非常贴合。对于您在部分测试中使用的少量数字(例如,5、10、100),即使充其量,拟合度通常非常很差。

从时间的角度来看,Java 的大多数实现也使生活变得更加困难。问题是大多数 JVM 将解释某些代码的前几次(其中“很少”定义相当松散)迭代,然后才决定它的执行频率足以值得编译成更优化的机器代码。您使用的数字几乎肯定足够小,以至于在某些情况下,您正在计时解释代码和其他编译代码(并且在那里的某个地方,执行包括编译代码所花费的时间)。这对 big-O 表示法的准确性没有实际影响,但(尤其是对于小数字)可以并且将会对您的时间与 big-O 预测值的拟合程度产生重大影响。

【讨论】:

    【解决方案2】:

    您问题中唯一的问号出现在这句话的末尾:

    这意味着在 2 之间存在一个复杂性,这就是 log n 的来源,因为 log n 的值小于 n?

    那句话不是问题,而是陈述:你在这里问什么?

    如果您要问log(n) 是什么,那么它是数字 p,当 10(表示 log10)或 e(当谈论自然时 对数)的幂次方(即 10p, ep)产生n。因此,随着 n 的增加,它的上升非常缓慢(实际上与指数增加正好相反):

    log10(10) 为 1 (101 == 10)
    log10(100) 是 2 (102 == 100)
    log10(1000) 是 3 (103 == 1000)

    如果您已经知道这一切,我们深表歉意。

    【讨论】:

    • OP 似乎对 n^3 和 n^4 之间是否存在一定程度的复杂性感到困惑,如果是,那么 logN 是否出现。有时人们可以在没有问号的情况下提问 -在我看来,这是一个非常明显的例子。
    【解决方案3】:

    在这种情况下 n^3 是不够的

    那不是真的。 Five 中的外循环恰好运行 n 次。对于 i 的每个值,内部循环恰好运行 i² 次,因此外部循环执行的步数是 i² 的总和,而 i 从 0 运行到 n-1,即 n/6 - n²/2 + n³/ 3(用归纳法简单证明)。这是一个三次多项式,因此它是 O(n³)。

    【讨论】:

      【解决方案4】:

      恐怕你没有正确解决这个问题:盲目地测试函数只会让你走这么远。

      O() 表示法实际上就像是说,对于一个非常大的 x 值,函数在时间 (aO(x)) 中完成,其中 a 是一个任意常数(可以是 0.00001 以及 6305789932)。

      我们看代码:内循环执行i2次,而(外循环)执行n次,i从0到n。

      现在,执行内部操作(sum++) Sumi=1,ni2, 其中,根据维基百科的智慧变成 (*):

      然后是应用 O() 表示法的时候了。对于一个大的 n(比如 10100),n3 压倒 n2 甚至更多 n1,所以您只需丢弃它们:O(*) = O(n3),这是练习的解决方案。

      HTH

      【讨论】:

        【解决方案5】:

        试着像这样理解它- 我们需要找到循环执行的次数来计算时间复杂度。 这里的总和也代表相同的数字,这就是为什么您可以在复杂性函数中使用它来代替时间。这个假设是基于这样一个假设,即一个语句的每个处理都需要一个恒定的时间。 如果我们计算循环运行的次数 - 对于 i = 0 内循环运行 0 次 对于 i = 1 内循环运行 1 次 对于 i = 2 内循环运行 4 次 对于 i = 3 内循环运行 9 次 所以对于 i = m 内循环运行 m*m 次

        所以处理的语句总数可以找到-- 总和 = 0 + 1 + 4 + 9 + .... + mm + ... +(n-1)(n-1) 总和 = 1 + 4 + 9 + .... + mm + ... +(n-1)(n-1) 这些是自然数的平方 前 N 个自然数之和可以找到为 - N(N+1)(2N+1) / 6 在我们的例子中 N=n-1 所以总和 = (n-1)(n)(2n-1) / 6 总和 = (n.n -n) (2n -1) /6 总和 = (2n.n.n - 2n.n - n.n -n) /6 总和 = (2n^3 -3n^2 -n) / 6 总和 = 1/3n^3 - 1/2n^2 -1/6n

        现在,Big O 将只考虑 n 的最高阶。 所以你的复杂性是 n^3 的数量级

        现在你的 n^3 时间复杂度函数将精确地取这个数字并除以 n^3 所以你的总和应该是 1/3 - 1/2n^-1 -1/6n^-2。

        对于 n^4 来说,这是一个更小的数字,随着 n 的增加它会变得更小,这解释了逐渐减少到 0。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-18
          相关资源
          最近更新 更多