簡體   English   中英

在河內塔中找到第k個舉動

[英]to find the k-th move in an Hanoi Tower

def hanoi_move ( start , via , target ,n ,k ):
    """ finds the k-th move in an Hanoi Towers instance
    with n discs """
    if n <=0:
        return "zero or fewer disks"
    elif k <=0 or k >=2** n or type(k )!= int :
        return "number of moves is illegal"
    elif k ==2**( n -1):
        return str . format ("disk {} from {} to {}",n , start , target )
    elif k <2**( n -1):
         return hanoi_move ( start , target , via ,n -1 , k)
    else:
        return hanoi_move ( via , start , target ,n -1 ,k -2**( n -1))

為什么要看2 ^(n-1)的移動? 您可以解釋一下代碼嗎?

TL; DR版本-將n-1個磁盤堆棧從一個位置移動到另一位置需要2 ^(n-1)-1個動作,因此此代碼正在查看是否要移動第n個磁盤,或者將n-1個磁盤的堆棧移入或移出第n個磁盤。

完整答案:

要了解為什么此代碼着眼於第(n-1)個移動以便確定第k個移動是什么,需要了解移動整個河內塔的背后的基本思想。

讓我們看一個例子。 我們有點A,B和C,還有一個10塊磁盤的塔,該磁盤要從位置A開始移動到位置C。我們將說磁盤9是最大的,第二個磁盤是8,以此類推。 ,它看起來像這樣:

A 9876543210
B
C

那么我們如何將所有內容移至C? 好吧,我們需要將基礎磁盤(9)移至C,因此我們首先將其移走,如下所示:

A 9
B 876543210
C

然后我們可以移動磁盤9

A
B 876543210
C 9

然后將九個磁盤的堆棧移回到磁盤9上,最終像這樣:

A
B
C 9876543210

當然,我跳過了如何移動九個磁盤的堆棧的整個部分,但這為您提供了基本的思想-移動堆棧需要先移動除底部磁盤以外的所有磁盤,然后再移動底部磁盤,然后再移動將其余磁盤移回其頂部。

所以這段代碼問“我們在這個過程中在哪里?” 如果k等於2 ^(n-1),則我們當前正在移動我們當前要移動的堆棧的底部磁盤。 如果k小於該值,則我們仍處於將磁盤堆棧移出底部磁盤的中間階段。 如果k大於該值,我們將嘗試將磁盤堆棧移回底部磁盤。 使用上面的簡單示例,如果k = 2 ^(10-1)= 2 ^ 9 = 512,則我們將磁盤9從A移到C。如果k小於512,則我們仍在移動過程中將磁盤0到8從磁盤9移到點B。如果k大於512,則我們在k -512處將磁盤0到8從點B移回到點C的磁盤9中。

我們怎么知道2 ^(n-1)是要使用的正確值? 使用數學歸納法,我們可以證明最多需要(2 ^ n)-1個動作才能移動n個磁盤的堆棧。 這是一個快速證明:

歸納基礎:要移動n = 1個磁盤的堆棧,需要(2 ^ n)-1 =(2 ^ 1)-1 = 1的移動-移動唯一的磁盤。 歸納步驟:假設它適用於n個磁盤(即,最有效的移動堆棧方式需要(2 ^ n)-1個移動)。 然后,要移動一堆n + 1個磁盤,我們首先使用最有效的方法從底部磁盤移出頂部n個磁盤(采取(2 ^ n)-1個移動),移動底部磁盤(1個移動) ,然后將其他n個磁盤移回底部磁盤的頂部((2 ^ n)-1再次移動)。 因此,我們采取的總動作數為(2 ^ n)-1 + 1 +(2 ^ n)-1 = 2 *(2 ^ n)-1 =(2 ^(n + 1))-1個動作。

如果您以前沒看過歸納法,這看起來可能很復雜,但是基本思路是這樣的-因為我們知道它適用於一個磁盤,所以我們知道它適用於兩個磁盤。 由於我們現在知道它適用於兩個磁盤,因此它適用於三個磁盤。 因為我們現在知道它適用於三個磁盤...等等。 歸納步驟適用於任意n,因此我們可以根據需要多次應用它。 因此,對於任何有限的n,我們都知道,移動n個磁盤的最快方法是(2 ^ n)-1個移動。

因此,現在的問題是,第n個磁盤在哪個磁盤上移動? 在第(2 ^(n-1))-1個步驟中,我們可以完成將n-1個磁盤堆棧移至底部磁盤頂部的操作。 然后,在第(2 ^(n-1))-1 + 1 = 2 ^(n-1)次移動中,我們可以移動底部磁盤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM