<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>漢諾塔 on kenji.blog</title><link>http://kenji.blog/zh-tw/tags/%E6%BC%A2%E8%AB%BE%E5%A1%94/</link><description>Recent content in 漢諾塔 on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><copyright>kenjinote</copyright><lastBuildDate>Thu, 17 Apr 2025 22:23:14 +0900</lastBuildDate><atom:link href="http://kenji.blog/zh-tw/tags/%E6%BC%A2%E8%AB%BE%E5%A1%94/index.xml" rel="self" type="application/rss+xml"/><item><title>漢諾塔</title><link>http://kenji.blog/zh-tw/p/hanoi-tower/</link><pubDate>Thu, 17 Apr 2025 22:23:14 +0900</pubDate><guid>http://kenji.blog/zh-tw/p/hanoi-tower/</guid><description>&lt;img src="http://kenji.blog/p/%E3%83%8F%E3%83%8E%E3%82%A4%E3%81%AE%E5%A1%94/img.png" alt="Featured image of post 漢諾塔" />&lt;h1 id="漢諾塔">漢諾塔
&lt;/h1>&lt;p>你好！&lt;/p>
&lt;p>今天，我想透過一個 Python 範例程式來解釋「漢諾塔」。&lt;/p>
&lt;hr>
&lt;h2 id="什麼是漢諾塔">什麼是漢諾塔？
&lt;/h2>&lt;p>漢諾塔是一個使用 3 根柱子和多個圓盤的謎題。圓盤的大小各不相同，最初它們按從大到小的順序堆疊在一根柱子上。規則如下：&lt;/p>
&lt;ol>
&lt;li>每次只能移動一個圓盤。&lt;/li>
&lt;li>較大的圓盤不能放在較小的圓盤上。&lt;/li>
&lt;/ol>
&lt;p>這個謎題被認為是學習遞迴思考的最佳教材。遞迴是一種透過將問題分解成相同類型的更小問題來解決問題的方法。在漢諾塔中，為了移動 n 個圓盤，我們重複移動 n-1 個圓盤的操作。&lt;/p>
&lt;hr>
&lt;h2 id="用-python-解決漢諾塔">用 Python 解決漢諾塔
&lt;/h2>&lt;p>以下是用 Python 解決漢諾塔的範例程式碼。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">hanoi&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">source&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">target&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">auxiliary&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">n&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Move disk 1 from &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">source&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> to &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">target&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">hanoi&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">source&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">auxiliary&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">target&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Move disk &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> from &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">source&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> to &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">target&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">hanoi&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">auxiliary&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">target&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">source&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 範例：將 3 個圓盤從 A 移動到 C&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">hanoi&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;A&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;C&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;B&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>在這個程式碼中，&lt;code>hanoi&lt;/code> 函數被遞迴呼叫，並顯示移動圓盤的步驟。例如，在 3 個圓盤的情況下，可以獲得以下輸出：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">Move disk 1 from A to C
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 2 from A to B
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 1 from C to B
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 3 from A to C
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 1 from B to A
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 2 from B to C
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Move disk 1 from A to C
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>透過這種方式，使用遞迴方法，可以簡單地解決複雜的問題。&lt;/p>
&lt;hr>
&lt;h2 id="移動-64-個圓盤需要多長時間">移動 64 個圓盤需要多長時間？
&lt;/h2>&lt;p>漢諾塔的移動次數最少需要 2^n - 1 次。也就是說，要移動 64 個圓盤，需要 2^64 - 1 次，約 1.84×10^19 次移動。即使 1 秒移動 1 次，也需要大約 5849 億年。這大約是宇宙年齡（約 137 億年）的 42 倍。&lt;/p>
&lt;p>因此，隨著圓盤數量的增加，所需的移動次數呈指數級增長。所以，在現實中移動 64 個圓盤是不切實際的。&lt;/p>
&lt;hr>
&lt;h2 id="總結">總結
&lt;/h2>&lt;p>漢諾塔是學習遞迴思考的最佳謎題。使用 Python，您可以輕鬆實現其解決方案。然而，請注意，隨著圓盤數量的增加，所需的移動次數會急劇增加。&lt;/p>
&lt;p>了解遞迴方法並嘗試實際編寫程式碼，可以幫助您提高程式設計技能。請務必挑戰一下漢諾塔。&lt;/p>
&lt;hr></description></item></channel></rss>