Python 查找最接近给定值的路径旅行成本

Python 查找最接近给定值的路径旅行成本,python,python-2.7,recursion,multidimensional-array,pathing,Python,Python 2.7,Recursion,Multidimensional Array,Pathing,我最近遇到了一个问题。我必须找到一个多维整数数组从左上角到右下角的路径的代价。此路径的成本必须是不超过某个给定值的最大成本 路径的代价定义为该路径所经过的数组索引值之和。每条路径的起点始终是左上角,每条路径的终点始终是右下角。此外,您只能向右或向底部移动 假设这是我用来解决这个问题的多维数组,提供的值是12 +---+---+---+ | 0 | 2 | 5 | +---+---+---+ | 1 | 1 | 3 | +---+---+---+ | 2 | 1 | 1 | +---+---+--

我最近遇到了一个问题。我必须找到一个多维整数数组从左上角到右下角的路径的代价。此路径的成本必须是不超过某个给定值的最大成本

路径的代价定义为该路径所经过的数组索引值之和。每条路径的起点始终是左上角,每条路径的终点始终是右下角。此外,您只能向右或向底部移动

假设这是我用来解决这个问题的多维数组,提供的值是12

+---+---+---+
| 0 | 2 | 5 |
+---+---+---+
| 1 | 1 | 3 |
+---+---+---+
| 2 | 1 | 1 |
+---+---+---+
这是我应该找到的正确路径。此路径的成本为11,它是低于或等于给定值的任何路径的最高成本

+---+---+---+
| X | X | X |
+---+---+---+
| 1 | 1 | X |
+---+---+---+
| 2 | 1 | X |
+---+---+---+
我试图用Python解决这个问题,但我看不出哪里出了问题。下面是我的一段代码

def answer (food, grid):

    # Grid is N*N in size
    n = len(grid)

    # Memoize a given function
    def memoize (f):
        memo = {}
        def helper (r, c, k):
            i = c + (r * n)
            if i not in memo:
                memo[i] = f(r, c, k)
            return memo[i]
        return helper

    # Get cost function
    def get_cost (r, c, k):

        if r >= n or c >= n:
            return -1
        if k < grid[r][c]:
            return -1
        if r == n - 1 and c == n - 1:
            return grid[r][c]

        down = get_cost(r + 1, c, k - grid[r][c])
        right = get_cost(r, c + 1, k - grid[r][c])

        if down < 0 and right < 0:
            return -1

        return grid[r][c] + max(down, right)

    # Memoize the get cost function
    get_cost = memoize(get_cost)

    return get_cost(0, 0, food)

print answer (12, [[0, 2, 5], [1, 1, 3], [2, 1, 1]])

您可以将memoize函数更新为以下内容:

def memoize (f):
    memo = {}
    def helper(*args):
        if args not in memo:
            memo[args] = f(*args)
        return memo[args]
    return helper


只要参数是可散列的,就可以将
*args
用作函数的参数,并将
args
用作备忘录缓存的键。这与使用参数元组作为键相同

def fn(*args):
    print(args)

fn(1,2,3)
(1, 2, 3)

考虑到
k
,由
i=c+(r*n)
组成的原始记忆缓存键被排除在外,并且还允许不同的c和r组合可能发生冲突。

我想分享一种使用回溯的不同方法:

def find_path(food, grid):

    n = len(grid)

    def worker(cost, path):
        row, col = path[-1]
        if row == n - 1 and col == n - 1:
            # we reached the bottom right corner, exit now
            return cost, path

        possible_paths = []
        if row < n - 1:
            # we can go down
            cost_down = cost + grid[row+1][col]
            path_down = list(path)
            path_down.append((row+1, col))
            possible_paths.append(worker(cost_down, path_down))
        if col < n - 1:
            # we can go to the right
            cost_right = cost + grid[row][col+1]
            path_right = list(path)
            path_right.append((row, col+1))
            possible_paths.append(worker(cost_right, path_right))

        # a path is valid, if its cost is
        # less or equal to the food available
        valid_paths = [item for item in possible_paths
                       if item is not None
                       and item[0] <= food]

        if valid_paths:
            return max(valid_paths, key=lambda x: x[0])

        return None

    return worker(grid[0][0], [(0, 0)])

你能澄清什么是食物论证吗?食物论证是我用来寻找路径成本的给定值。我发现的路径的成本必须是所有可能路径中最大的成本,同时不超过食物价值。很抱歉在这一点上用词不当!这管用!我会接受这个答案,但我想让你先看看这个评论。请您解释一下这是如何解决我的问题的好吗?您尝试使用的键是
i=c+(r*n)
可能用于多组参数。例如,
c=3,r=1,n=3
c=0,r=2,n=3
将是
6
的相同键,但不应从缓存返回相同的值。
def fn(*args):
    print(args)

fn(1,2,3)
(1, 2, 3)
def find_path(food, grid):

    n = len(grid)

    def worker(cost, path):
        row, col = path[-1]
        if row == n - 1 and col == n - 1:
            # we reached the bottom right corner, exit now
            return cost, path

        possible_paths = []
        if row < n - 1:
            # we can go down
            cost_down = cost + grid[row+1][col]
            path_down = list(path)
            path_down.append((row+1, col))
            possible_paths.append(worker(cost_down, path_down))
        if col < n - 1:
            # we can go to the right
            cost_right = cost + grid[row][col+1]
            path_right = list(path)
            path_right.append((row, col+1))
            possible_paths.append(worker(cost_right, path_right))

        # a path is valid, if its cost is
        # less or equal to the food available
        valid_paths = [item for item in possible_paths
                       if item is not None
                       and item[0] <= food]

        if valid_paths:
            return max(valid_paths, key=lambda x: x[0])

        return None

    return worker(grid[0][0], [(0, 0)])
print(find_path(12, [[0, 2, 5],
                     [1, 1, 3],
                     [2, 1, 1]]))
# (11, [(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)])

print(find_path(12, [[0, 2, 5],
                     [1, 1, 3],
                     [2, 1, 10]]))
# None

print(find_path(42, [[3, 8, 6, 5],
                     [1, 5, 3, 9],
                     [1, 5, 8, 1],
                     [2, 1, 9, 4]]))
# (42, [(0, 0), (0, 1), (1, 1), (2, 1), (2, 2), (3, 2), (3, 3)])