【问题标题】:Trying to compare a recursive and an iterative algorithm尝试比较递归和迭代算法
【发布时间】:2016-12-12 16:49:32
【问题描述】:

我有两种算法可以解决这个问题:Generate all sequences of bits within Hamming distance t。现在我想从理论上比较它们(如果需要,我确实有时间测量)。

iterative algorithm 的复杂度为:

O((n 选择 t) * n)

其中n 是位串的长度,t 是所需的汉明距离。

recursive algorithm,到目前为止我们最好的是:

O(2^n)

但是如何比较这两个时间复杂度,而不在第二个时间复杂度中引入t?因此,我正在尝试这样做,您能帮忙吗?

递归算法:

// str is the bitstring, i the current length, and changesLeft the
// desired Hamming distance (see linked question for more)
void magic(char* str, int i, int changesLeft) {
        if (changesLeft == 0) {
                // assume that this is constant
                printf("%s\n", str);
                return;
        }
        if (i < 0) return;
        // flip current bit
        str[i] = str[i] == '0' ? '1' : '0';
        magic(str, i-1, changesLeft-1);
        // or don't flip it (flip it again to undo)
        str[i] = str[i] == '0' ? '1' : '0';
        magic(str, i-1, changesLeft);
}

【问题讨论】:

  • n choose t is n!/(t!.(nt)!) 这有最小值 1(t==0),最大值 n!/(n/2) !²(t==n/2)。
  • 没有。 t==n/2 是迭代复杂度最大的地方!
  • 有趣的是,没有一个回答算法在另一个位向量上使用next_permutation
  • 最后,观察到对于小的 t,递归复杂度优于 2^n。如果 t==0,它将立即返回,如果 t=1,“翻转”分支将不再递归。另外,如果勾选changesLeft &gt; i并返回,如果t接近n,则可以提前返回。
  • 没有@samgak(真的很抱歉造成混乱)。修复t,假设n/2 计算函数的时间复杂度,我想这样就足够了。

标签: c++ algorithm performance recursion time-complexity


【解决方案1】:

递归算法也是O((n choose t) * n),通过分析向每个打印的组合收取打印时整个调用堆栈的成本。我们可以这样做,因为每次调用magic(除了两个O(1) 叶调用,其中i &lt; 0,我们可以很容易地取消)打印一些东西。

如果您指定打印的真实成本,则此界限是最好的。否则,我很确定这两种分析都可以收紧到 O(n choose t),不包括 t &gt; 0 的打印,详细信息在 Knuth 4A 中。

【讨论】:

    【解决方案2】:

    在最一般的时间复杂度级别上,我们有 t = n/2 的“最坏情况”。现在,修复 t 并逐渐增加 n。我们以n=8, t=4为起点

    C(8 4) = 8*7*6*5*4*3*2*1 / (4*3*2*1 * 4*3*2*1)
        = 8*7*6*5 / 24
    n <= n+1 ... n choose t is now
    
    C(9 4) = ...
        = 9*8*7*6 / 24
        = 9/5 of the previous value.
    

    现在,进度更容易观察了。

    C( 8 4) = 8*7*6*5 / 24
    C( 9 4) =  9/5 * C( 8 4)
    C(10 4) = 10/6 * C( 9 4)
    C(11 4) = 11/7 * C(10 4)
    ...
    C( n 4) = n/(n-4) * C(n-1 4)
    

    现在,作为学生的引理:

    • 求基本复杂度,n! / ( (n-1)!^ 2)
    • 求常数 c 的乘积 (n / (n-c)) 的组合复杂度

    【讨论】:

      猜你喜欢
      • 2011-01-18
      • 2015-09-20
      • 1970-01-01
      • 2011-02-08
      • 2016-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-05
      相关资源
      最近更新 更多