项目Euler#15在Python中

时间:2014-07-24 11:45:32

标签: python

我是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;功能。在没有全局的情况下,它正在朝着我所希望的方向前进。感谢您的评论,他们真的非常有用。

2 个答案:

答案 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()