河内的塔有两个辅助杆

时间:2014-08-23 21:12:49

标签: algorithm time-complexity towers-of-hanoi

我在其中一个网站上遇到过这个问题。

要求:

如果给出两个辅助杆而不是一个辅助杆,需要提出算法并解决河内塔问题的时间复杂性。

我的尝试:

河内的原始塔:

T(N)= T(N-1) // Moving N-1 disks from Source to Auxilary 
    + 1      // Moving Nth disk from Source to Destination  
    + T(N-1) // Moving N-1 disks from Auxilary to Destination

     T(N) = 2*T(N-1) + 1 

            = O(2 power N )   // exponential.

目前的问题是因为我们有两个辅助杆

`

     T(N) =

          T(N/2)  // Moving top N/2 from Source to Aux1

          + T(N/2)  // Moving the remaining N/2 from Source to Destination using Aux2.

           + T(N/2)  // Moving N/2 from Aux1 to Destination.

                T(N) = 3*T(N/2) 
                =O( 3 power log N base 2 ) 
                = O( N power log 3 base 2 )  // less than quadartic.

但我对此并不十分肯定,因为我不是计算时间为T(N / 2),用于将顶部N / 2移动到Aux1,也用于使用Aux2将botton N / 2从源移动到目的地。

为什么我认为这是不正确的,因为在第一种情况下,当移动顶部(N / 2)时我们可以玩三根杆:Destiation,Aux1& AUX2  但是当移动底部(N / 2)时,我们只能使用两根杆Destination,Aux2

所以我认为应该更好地解决这个问题。

2 个答案:

答案 0 :(得分:1)

这是Python中一个简单的memoized递归函数,它使用Frame–Stewart algorithm来查找最小移动次数。根据上面链接的维基百科文章,该算法被证明是4个钉和最多30个磁盘的最佳选择,并且它被认为是n磁盘和r的所有组合的最佳选择。钉(但未证明是这样)。它可能会对我的实现进行一些优化,但它的速度足以获得合理的nr值。

def hanoi(n, r, memo={}):    # deliberately using a mutable default argument here
    """Return the number of steps required to move n disks using a total of r pegs."""
    if n == 1:               # base case
        return 1
    if r <= 2:               # impossible cases
        return float("inf")
    if (n,r) not in memo:
        memo[n, r] = min(hanoi(k, r)*2 + hanoi(n-k, r-1)   # recursive calls
                         for k in range(1, n))
    return memo[n, r]

答案 1 :(得分:0)

基本情况-

  1. 如果没有铃声,请返回。
  2. 如果只有一个环,则直接转移到目的地。
  3. 将n-2转移到第二辅助塔。 第一次递归
  4. 将第二个最大的环转移到第一个辅助塔,然后将最大的环转移到目标塔。然后,转移第二大环形目的地塔。 3条印刷声明
  5. 将n-2传输到目标塔。 第二次递归

第4步背后的想法是,无论辅助塔的数量如何,都没有更快的方法将大小为2的堆栈传输到目的地。

// Number of rings, from tower, destination tower, 1st auxiliary tower and 2nd auxiliary tower.
void hanoi(int rings, int from, int to, int aux1, int aux2){
    if(rings==0)
        return;
    if(rings==1){
        cout<<from<<" to "<<to<<endl;ct++;
        return;
    }
    hanoi(rings-2, from, aux2, aux1, to);
    cout<<from<<" to "<<aux1<<endl;
    cout<<from<<" to "<<to<<endl;
    cout<<aux1<<" to "<<to<<endl;
    ct+=3;
    hanoi(rings-2,aux2, to, from, aux1);
}

int main(){
    int i,n,j,k,l,m;
    cin>>n;
    hanoi(n,0,1,2,3);
    cout<<ct<<endl;
}
相关问题