python實(shí)現(xiàn)三壺謎題的示例詳解
前言
有一個(gè)充滿水的8品脫的水壺和兩個(gè)空水壺(容積分別是5品脫和3品脫)。通過(guò)將水壺完全倒?jié)M水和將水壺的水完全倒空這兩種方式,在其中的一個(gè)水壺中得到4品脫的水。
一、算法思想
算法分析
- 采用的算法思想是將某個(gè)時(shí)刻水壺中水的數(shù)量看作一個(gè)狀態(tài),用一個(gè)長(zhǎng)度為3的數(shù)組表示。
- 初始狀態(tài)便為[8,0,0],再拓展他的下一結(jié)點(diǎn)的可能結(jié)構(gòu)。
- 若下一結(jié)點(diǎn)的結(jié)構(gòu)已經(jīng)被拓展過(guò)了便放棄,若沒(méi)有拓展過(guò)則加入拓展列表(open_list)中。然后遞歸上述操作。
- 直到拓展列表(open_list)為空或者找到目標(biāo)為止。
思想圖解
這里的第一個(gè)數(shù)就代表著是那個(gè)8品脫的瓶子,依次分別是8品脫,5品脫,3品脫

就如同上圖一樣,使用層次遍歷一次一次遞歸擴(kuò)展新的結(jié)點(diǎn),知道找到4品脫的水或者無(wú)結(jié)點(diǎn)可擴(kuò)展為止(類似于廣度優(yōu)先遍歷)。
二、代碼展示
1.創(chuàng)建樹(shù)節(jié)點(diǎn)結(jié)構(gòu)
節(jié)點(diǎn)包括兩個(gè)屬性,一個(gè)屬性是數(shù)組類型的,存儲(chǔ)當(dāng)前三個(gè)水壺的容量狀態(tài),另一個(gè)屬性是記錄它是由哪個(gè)結(jié)點(diǎn)擴(kuò)展過(guò)來(lái)的,以便找到解決路徑:
class node: # 創(chuàng)建樹(shù)節(jié)點(diǎn) def __init__(self, data): self.data = data # 存儲(chǔ)三個(gè)壺的容量狀態(tài) self.per = None # 存儲(chǔ)上一時(shí)刻三個(gè)壺的容量狀態(tài)
2.實(shí)現(xiàn)傾倒動(dòng)作
由于這里只有三個(gè)壺,互相傾倒的方案可以枚舉出來(lái),所有我就沒(méi)使用二重嵌套循環(huán),而是使用一層循環(huán):
def pour(n): # 擴(kuò)展子節(jié)點(diǎn)
r_list = n.data # 記錄當(dāng)前三個(gè)水壺的容量狀態(tài)
max_list = [8, 5, 3] # 水壺的最大容量
for i, j in ((0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (2, 1)):
if r_list[i] != 0:
n_list = r_list.copy() # 初始化下一結(jié)點(diǎn)的水壺狀態(tài)
if r_list[i] + r_list[j] > max_list[j]:
n_list[i] = r_list[i] - (max_list[j] - r_list[j])
n_list[j] = max_list[j]
else:
n_list[j] = r_list[i] + r_list[j]
n_list[i] = 0
flag = True # 記錄水壺的狀態(tài)是否已經(jīng)發(fā)生過(guò)(擴(kuò)展過(guò))
for one in closed_list:
if one.data == n_list: # 比較當(dāng)前水壺狀態(tài)和以往記錄過(guò)得水壺狀態(tài)
flag = False
if flag:
print("擴(kuò)展的新節(jié)點(diǎn)是:",n_list)
new_node = node(n_list) # 創(chuàng)建新節(jié)點(diǎn)存儲(chǔ)水壺的新?tīng)顟B(tài)
new_node.per = n
open_list.append(new_node)
主遞歸函數(shù)
查看當(dāng)前是否已經(jīng)擴(kuò)展到4品脫的水或者是否還有結(jié)點(diǎn)可以擴(kuò)展。
def BFS_node(root_1): # 遞歸查找子節(jié)點(diǎn)的擴(kuò)展?fàn)顟B(tài)以及查驗(yàn)是否找到4品脫的水壺
n = root_1
print("當(dāng)前節(jié)點(diǎn):",n.data)
if open_list is None:
return "沒(méi)有找到4品脫的水"
nodelist = n.data
if 4 in nodelist:
print("找到了4品脫的水")
print_node(n)
return "找到了4品脫的水"
closed_list.append(open_list.pop(0))
pour(n)
print("*******")
BFS_node(open_list[0])
數(shù)據(jù)初始化
數(shù)據(jù)初始化,以及找到4品脫水后打印路徑的打印函數(shù)。
def print_node(n): # 打印正確的水壺操作路徑 if n.per == None: return "" print(n.data) print_node(n.per) # 初始化數(shù)據(jù) root = node([8, 0, 0]) open_list = [root] # 存儲(chǔ)已找到卻未被擴(kuò)展的子節(jié)點(diǎn) closed_list = [] # 存儲(chǔ)已找到且被擴(kuò)展的子節(jié)點(diǎn) BFS_node(open_list[0])
總結(jié)
主要是用廣度優(yōu)先遍歷的思想和樹(shù)結(jié)構(gòu),當(dāng)然如果不在意找到4品脫的水的路徑,其實(shí)沒(méi)必要使用樹(shù)結(jié)構(gòu)。另外打印函數(shù)是從最后一層依次往上回溯的,所以顯示的是倒序的路徑。如果需要變成正向的話,可以加一個(gè)棧來(lái)實(shí)現(xiàn)。
到此這篇關(guān)于python實(shí)現(xiàn)三壺謎題的示例詳解的文章就介紹到這了,更多相關(guān)python三壺謎題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python實(shí)現(xiàn)TCPserver的使用示例
python實(shí)現(xiàn)TCPserver是一件簡(jiǎn)單的事情,只要通過(guò)socket這個(gè)模塊就可以實(shí)現(xiàn),本文就來(lái)介紹一下python實(shí)現(xiàn)TCPserver的使用示例,感興趣的可以了解一下2023-10-10
Python中l(wèi)ist循環(huán)遍歷刪除數(shù)據(jù)的正確方法
這篇文章主要給大家介紹了關(guān)于Python中l(wèi)ist循環(huán)遍歷刪除數(shù)據(jù)的正確方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
Python 解決logging功能使用過(guò)程中遇到的一個(gè)問(wèn)題
這篇文章主要介紹了Python 解決logging功能使用過(guò)程中遇到的一個(gè)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
python實(shí)現(xiàn)字符串和日期相互轉(zhuǎn)換的方法
這篇文章主要介紹了python實(shí)現(xiàn)字符串和日期相互轉(zhuǎn)換的方法,涉及Python中time和datetime函數(shù)使用技巧,需要的朋友可以參考下2015-05-05
最新Python?APScheduler?定時(shí)任務(wù)詳解
這篇文章主要介紹了Python使用apscheduler模塊設(shè)置定時(shí)任務(wù),APScheduler全稱Advanced?Python?Scheduler?作用為在指定的時(shí)間規(guī)則執(zhí)行指定的作業(yè),本文對(duì)Python?APScheduler?定時(shí)任務(wù)相關(guān)知識(shí)介紹的非常詳細(xì),需要的朋友參考下2022-05-05
Django 淺談根據(jù)配置生成SQL語(yǔ)句的問(wèn)題
今天小編就為大家分享一篇Django 淺談根據(jù)配置生成SQL語(yǔ)句的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
python基礎(chǔ)編程小實(shí)例之計(jì)算圓的面積
Python是最常用的編程語(yǔ)言,這種語(yǔ)言就是一種可以快速開(kāi)發(fā)應(yīng)用的解釋型語(yǔ)言,有些用戶不知道該怎么在Python編程里計(jì)算圓的面積,現(xiàn)在就給大家具體解釋一下,下面這篇文章主要給大家介紹了關(guān)于python基礎(chǔ)編程小實(shí)例之計(jì)算圓的面積的相關(guān)資料,需要的朋友可以參考下2023-03-03

