簡體   English   中英

試圖用 Python 實現自上而下的 DP,相信緩存不起作用

[英]Attempting to implement top down DP with Python, believe caching is not working

這是家庭作業,但由於目前的封鎖,我無法向我的導師尋求幫助,所以我想我會上網 :)

我正在嘗試為最長公共子序列算法專門實現自上而下(因此緩存)DP。 這是我寫的:

def lcs(s1, s2, known=None):
    if(known == None):
        known = {}
    if len(s1) == 0:
        return 0
    if len(s2) == 0:
        return 0
    else:
        if((s1, s2) in known):
            return known[(s1, s2)]
        elif(s1[-1] == s2[-1]):
            now_known = (1 + lcs(s1[:-1], s2[:-1]))
            known[(s1, s2)] = now_known
            return now_known
        else:
            now_known = max((lcs(s1, s2[:-1])), (lcs(s1[:-1], s2)))
            known[(s1, s2)] = now_known
            return now_known

我對所寫內容的理解是:

  • 我的代碼檢查其中一個字符串是否為空,如果是這樣,最長公共子序列將為 0
  • 我的代碼然后檢查它正在檢查的兩個字符串是否在緩存中,如果是,則返回緩存中與其關聯的值。
  • 然后我的代碼檢查兩個字符串中的最后一個元素是否相同,在這種情況下,最長的子序列將是 1 加上字符串其余部分的 lcs。
  • 否則,我的代碼遞歸調用自己兩次,每個字符串減去它的最后一個元素一次

當上面的代碼在兩個小字符串上運行時:

s1 = "abcde"
s2 = "qbxxd"
lcs = lcs(s1, s2)
print(lcs)

我得到了正確的輸出 2 :) 但是,在較大的輸入上運行時,例如:

s1 = "Look at me, I can fly!"
s2 = "Look at that, it's a fly"
print(lcs(s1, s2))

我的代碼超時。 這一點,加上一些打印語句測試(當我添加到“已知”時測試添加到“已知”的內容)讓我相信我沒有正確地實現我的緩存。 這可能是一個簡單愚蠢的錯誤修復問題,在這種情況下,我深表歉意,但我相信這是我對緩存理解的問題。 另外,我知道“lru cache”為我做緩存,但是為了這個家庭作業的目的,我需要編寫自己的緩存。

任何見解將不勝感激。

正如評論所指出的,您不會在遞歸調用中傳遞known 因此它總是以None開頭,然后用{}填充,並且您永遠不會從緩存中受益。

我個人喜歡以下模式

def lcs(s1, s2):
    cache = {}

    def _lcs (i, j):
        if (i, j) not in cache:
            ... (logic here) ...

        return cache[(i, j)]

    return _lcs(0, 0)

這個想法是現在創建了一次緩存和序列,而您只是在使用索引。 我也不會忘記傳遞緩存。 :-)

暫無
暫無

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

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