通过最接近给定数字的总和查找2D数组的路径

时间:2014-12-18 08:50:47

标签: python arrays algorithm

我想找到通过2D整数数组的路径(没有负数,大小为N * N),其中所有传递的数字的总和最接近给定的数字。从左上角开始,在导航数组的每个步骤中,您只能向下或向右移动。目的地是阵列的右下角。

示例:

field = [
  [0,5,1],
  [1,3,5]
  [2,1,1]
]

n = 5

solution(field, n) => 0
// down, down, right, right

solution(field, 7) => 1

如果找不到解决方案,则产生正数,则返回-1

我的低效解决方案:

def solution(n, field)
  res​ ​=​ ​closest(n,​ ​field)
  if​ ​res​ ​<​ ​0:
    return​ ​-1
  ​return​ ​res

def closest(n, field)
  best = n - field[0][0]
  if len(field) > 1:
    "Remove upper most row and call recursively"
    tmp = solution(n - field[0][0], field[1:])
    if tmp >= 0:
  ​    best = tmp
  if len(field[0]) > 1:
    "Remove left most column and call recursively"
    tmp = solution(n - field[0][0], [(x[0:0] + x[1:]) for x in field])
    if tmp < best:
      best = tmp
  return best

这适用于小型领域,但效率极低。 对于包含20列和20行的字段,找到解决方案需要很长时间。

有没有更有效的方法来解决这个问题。 (即20 * 20几秒钟) (代码不必在python中

2 个答案:

答案 0 :(得分:2)

您可以使用动态编程或memoization来有效地解决此问题。首先,递归函数的表达方式如下:

C(x, y, n) =   -1 if x < 0 or y < 0 or x >= n or y >= n or n < 0 (1)
             | field[x][y] if x = n - 1 and y = n - 1 and n >= 0 (2)
             | -1 if FromUp = -1 and FromLeft = -1 (3)
             | field[x][y] + Max(FromUp, FromLeft) (4)
where C(x, y, n) is the length of the path closest to n ending at x and y
      FromLeft = C(x - 1, y, n - field[x][y])
      FromUp = C(x, y - 1, n - field[x][y])

有2个基本情况(1)和(2),(1)表示无效的行或列或n。 (2)表示您已经使用有效的n到达右下角的单元格。对于特定的x,y和n,您可以来自上部单元格或左侧单元格。因此(3)是失败的递归情况,(4)如果递归情况中的1个成功,则计算C(x,y,n)的正确长度。

如果您想使用动态编程,您可以构建一个3D表并用3个嵌套for循环填充它。如果你想使用memoization,只需编写上面的递归函数;但每次返回某些内容时,请将其记录在3D表格中,然后在其他步骤之前尝试使用该表格中的结果

答案 1 :(得分:0)

我认为你正在寻找这个

F = [[0,5,1],
    [1,3,5],
    [2,1,1]]

N = 3

SUM = [[0 for x in range(N)] for y in range(N)]

n = 7

def solution(row, col):
    if row==N or col==N :
        return 10**10;
    if row==N-1 and col==N-1:
        return F[row][col]

    if(SUM[row][col]):
        return SUM[row][col]

    A =  solution(row+1, col) + F[row][col]
    B =  solution(row, col+1) + F[row][col]
    if(abs(n-A)<=abs(n-B)):
        SUM[row][col] = A
    else:
        SUM[row][col] = B

    return SUM[row][col]


def RES(n):
    res = solution(0,0)
    if(res<0):
        return -1
    else:
        return abs(res-n)


print RES(n)