iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
AI & Data

了解AI多一點點系列 第 20

【Day 20】傳教士與食人族 – 展開結點

  • 分享至 

  • xImage
  •  

接下來要做最主要的部分就是展開結點,展開結點時,我們分成四大類情形來看,分別為船A在右岸且船B在右岸、船A在左岸且船B在右岸、船A在右岸且船B在左岸、船A在右岸且船B在右岸。而每種情形下又可再細分成接下來開A船、開B船或是開A船且開B船。
我們以雙層巢狀迴圈去展開結點的可能,外層所代表的為開船的總人數,最低為1最高為該船的承載上限人數,內層所代表的為開船的人中傳教士的人數。

只開A船的設計如下:

# sail boatA
for a1 in range(1, A + 1):
    for a2 in range(0, a1 + 1):
        next_state = state.State(current.m - a2, current.c - (a1 - a2), not current.a, current.b)
        next_state.g = current.g + A_COST
        next_state.h = state.h(next_state)
        next_state.f = next_state.g + next_state.h
        boat_state = state.BoatState(a2, a1 - a2, 0, 0)
        if state.isLegal(next_state, boat_state):
            next_state.num = number
            number += 1
            next_state.parent = current.num
            next_state.boat = boat_state
            list.append(next_state)

只開B船的情形和只開A船時相似,兩者之差在船的承載上限不同,因此只須更改一下外層迴圈的便數即可。

只開B船的設計如下:

# sail boatB
for b1 in range(1, B + 1):
    for b2 in range(0, b1 + 1):
        next_state = state.State(current.m - b2, current.c - (b1 - b2), current.a, not current.b)
        next_state.g = current.g + B_COST
        next_state.h = state.h(next_state)
        next_state.f = next_state.g + next_state.h
        boat_state = state.BoatState(0, 0, b2, b1 - b2)
        if state.isLegal(next_state, boat_state):
            next_state.num = number
            number += 1
            next_state.parent = current.num
            next_state.boat = boat_state
            list.append(next_state)

而開A船又開B船的情形,我們使用四層巢狀迴圈做結點展開,概念其實都和上面的相同,只是需要考慮A船和B船一起行駛,大概就是將上面兩部分合併即可。

開A船且開B船設計如下:

# sail boatA and boatB
for a1 in range(1, A + 1):
    for a2 in range(0, a1 + 1):
        for b1 in range(1, B + 1):
            for b2 in range(0, b2 + 1):
                next_state = state.State(current.m - a2 - b2, current.c - (a1 - a2) - (b1 - b2), not current.a, not current.b)
                next_state.g = current.g + AB_COST
                next_state.h = state.h(next_state)
                next_state.f = next_state.g + next_state.h
                boat_state = state.BoatState(a2, a1 - a2, b2, b1 - b2)
                if state.isLegal(next_state, boat_state):
                    next_state.num = number
                    number += 1
                    next_state.parent = current.num
                    next_state.boat = boat_state
                    list.append(next_state)

上面三部分只是船A和船B皆在右岸時的結點展開,後面還須加上另外三大類(A船在左岸且B船在右岸、A船在右岸且B船在左岸、A船在左岸且B船在左岸),但概念上都是相同的,因此不再額外花篇幅多加敘述。
Github連結:https://github.com/Ming06-22/Missionaries-cannibals


上一篇
【Day 19】傳教士與食人族 – 函式設計
下一篇
【Day 21】傳教士與食人族 – 介面設計
系列文
了解AI多一點點30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言