傳教士野蠻人過河問題--python


三名傳教士和三個野蠻人同在一個小河渡口,渡口上只有一條可容兩人的小船。問題的目標是要用這條小船把這六個人全部渡到對岸去,條件是在渡河的過程中,河兩岸隨時都保持傳教士人數不少於野蠻人的人數,否則野蠻人會把處於少數的傳教士吃掉。這六個人怎樣才能安全渡過去?

狀態集合為(x,y,b)三元組,x表示左岸野人數,y表示左岸傳教士數,x,y取值0~3。b為0表示船在左邊,b為1表示船在右邊
動作集合為一個傳教士從左到右,兩個傳教士從左到右,一個野人從左到右,兩個野人從左到右,一個野人一個傳教士從左到右;從右到左類似也有5個動作,共10個動作,於是就可以畫出一個狀態轉換圖,下面的python代碼可以幫助我們完成這個任務(主要是用來練練python- -,所以看起來幼稚一點,別見怪^_^)。

state_legal判斷給定狀態是否合法,act_legal判斷在當前狀態執行給定動作是否合法,f(x,y,b)打印所有從(x,y,b)可以執行的動作和轉移到的狀態
def state_legal(x, y, b):
    if x < 0 or y < 0 or x > 3 or y > 3:
        return False
    if y < x and y > 0:
        return False
    elif (3-y) < 3-x and 3-y > 0:
        return False
    else:
        return True
def act_legal(x, y, b, xx, yy, bb):
    if b != bb:
        return False
    if b == 0 and state_legal(x - xx, y - yy, 1 - b):
        return True
    elif b == 1 and state_legal(x + xx, y + yy, 1 - b):
        return True
    else:
        return False
#when calling f, (x,y,b) is ensured to be state_legal
def f(x,y,b):
    for act in actions:
        if act_legal(x, y, b, act[0], act[1], act[2]):
            if act[2] == 0:
                print(x,y,b,"---",act, '---', x - act[0], y - act[1], 1 - b)
            else:
                print(x,y,b,"---",act, '---', x + act[0], y + act[1], 1 - b)
a = (0,1,2,3)
actions = []
for b in (0,1):
    for x in (0,1,2):
        for y in (0,1,2):
            if x + y >= 1 and x + y <= 2:
                actions.append((x,y,b))
print(actions)

for x in a:
    for y in a:
        for b in (0,1):
            if not(x == 0 and y == 0) and state_legal(x, y, b):
                f(x,y,b)




#x is num of savages, y is num of missionaries

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM