我是Python的新手。我在合理的时间里坚持在Project-Euler中做问题15。 memoize func中的问题。没有memoize所有工作好,但只适用于小网格。我尝试过使用Memoization,但是这些代码的结果是" 1"适用于所有网格。
def memoize(f): #memoization
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
@memoize
def search(node):
global route
if node[0] >= k and node[1] >= k:
route += 1
return route
else:
if node[0] < k + 1 and node[1] < k + 1:
search((node[0] + 1, node[1]))
search((node[0], node[1] + 1))
return route
k = 2 #grid size
route = 0
print(search((0, 0)))
如果注释掉代码以禁用memoize func:
#@memoize
一切正常,但对于大网格而言要慢一些。我究竟做错了什么?帮助debbug。很多!
更新1:
感谢您的帮助,我也找到了答案:
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
@memoize
def search(node):
n = 0
if node[0] == k and node[1] == k:
return 1
if node[0] < k+1 and node[1] < k+1:
n += search((node[0] + 1, node[1]))
n += search((node[0], node[1] + 1))
return n
k = 20
print(search((0, 0)))
问题不在于memoize func,正如我之前想的那样。问题在于搜索&#39;功能。在没有全局的情况下,它正在朝着我所希望的方向前进。感谢您的评论,他们真的非常有用。
答案 0 :(得分:1)
你的记忆功能很好,至少对于这个问题。对于更一般的情况,我使用此:
def memoize(f):
f.cache = {} # - one cache for each function
def _f(*args, **kwargs): # - works with arbitrary arguments
if args not in f.cache: # as long as those are hashable
f.cache[args] = f(*args, **kwargs)
return f.cache[args]
return _f
实际问题 - 正如Kevin在评论中所指出的那样 - 只有当函数不能通过副作用工作时,才能使用memoization。虽然您的函数的结果为return
,但您不会在递归计算中使用它,而只是依赖于递增全局计数器变量。当您通过memoization获得更早的结果时,该计数器不再增加,并且您也不使用返回的值。
更改您的函数以总结递归调用的结果,然后它将起作用。
您也可以稍微简化一下代码。特别是,在递归调用之前进行if
检查是不必要的,因为无论如何都要检查>= k
,但是您应该检查x
组件或是否y
组件>= k
,而不是两者;一旦击中了k
,就会有另一条路线进入目标。此外,您可以尝试倒计时到0
而不是k
,因此代码不再需要k
。
@memoize
def search(node):
x, y = node
if x <= 0 or y <= 0:
return 1
return search((x - 1, y)) + search((x, y - 1))
print(search((20, 20)))
答案 1 :(得分:0)
试试这个代码。即使网格超过 1000x1000,它也能快速运行!不一定是方形的。 但我还不知道记忆化...
import time
def e15():
x=int(input("Enter X of grid: "))
y=int(input("Enter Y of grid: "))
start = time.time()
lst=list(range(1,x+2))
while lst[1]!=y+1:
i=0
for n in lst[1:]:
i+=1
lst[i]=n+lst[i-1]
print(f"There are {lst[-1]} routes in {x}x{y} grid!")
end = time.time() - start
print("Runtime =", end)
e15()