【问题标题】:Dynamic Programming Python path algorithm动态规划 Python 路径算法
【发布时间】:2018-04-14 17:25:05
【问题描述】:

我是一名助教,他的作业本应该比我的学生好,但有一个问题我似乎无法解决。这是大纲:

输入规范:第一行包含m,最高的街道号。请注意,从第 0 条街道到第 m 条街道共有 m+1 条街道。第二行包含 n,最高的街道编号。请注意,从第 0 条大道到第 n 条大道共有 n+1 条大道。接下来按照 m+1 行。这些行中的第一行包含第 0 条街道的值。下一行包含 1st street 的值。等等。每行包含 n 个值,值之间有一个空格。每个值都是 0 或 1。0 表示块已被铲起。 1 表示该块尚未被铲除。第一个值对应于第 0 大道和第 1 大道之间的街区。下一个值对应于第一大道和第二大道之间的街区。等等。接下来遵循 n+1 行。这些行中的第一行包含第 0 大道的值。下一行包含第一大道的值。等等。每行包含 m 个值,值之间有一个空格。每个值都是 0 或 1。0 表示块已被铲起。 1 表示该块尚未被铲除。第一个值对应于第 0 街和第 1 街之间的街区。下一个值对应于 1st street 和 2nd street 之间的街区。等等。你可以假设 n 和 m 都最多为 1000。

所以基本上我试图从 2D 数组上的 [0][0] 到 [n][m] 向下和向右移动取决于其他两个数组在该位置是否有 1 或 0 .这是我的代码

作者:贾斯汀·哈道克

铲子.py

def initialize():
    #Generate variables
    f = open("test.txt", "r")
    streets = int(f.readline().strip())
    aves = int(f.readline().strip())
    streetsArray = []
    avesArray = []
    for x in range(streets+1):
        streetsArray.append([int(x) for x in f.readline().strip().split(" ")])

    for y in range(aves+1):
        avesArray.append([int(x) for x in f.readline().strip().split(" ")])
    streetsArray = rotate(streetsArray)
    findPath(streetsArray, avesArray)

def printArray(arr):
    for x in arr:
        print(x)


def rotate(arr):
    #Rotate the aves array to make it more usable
    rotated = list(zip(*reversed(arr)))
    rotated2 = list(zip(*reversed(rotated)))
    rotated3 = list(zip(*reversed(rotated2)))
    new = []
    for x in reversed(range(len(rotated3))):
        new.append(list(rotated3[x]))
    return new


def findPath(a, b):
    print("-----A------")
    printArray(a)
    print("-----B------")
    printArray(b)
    print("------------")
    print(len(b))
    dynArray = [[0]*len(a[0]) for x in range(len(b))]
    printArray(dynArray)
    print("------------")
    for x in range(0, len(dynArray)):
        for y in range(0, len(dynArray[0])):
            dynArray[x][y] = x+y
            if (x == 0 and y == 0):
                dynArray[x][y] = 0
            elif (x == 0):
                print(x,y)
                dynArray[x][y] = dynArray[x][y-1]+b[x][y-1]
            elif (y == 0):
                # print(x, y)
                dynArray[x][y] = dynArray[x-1][y] + b[x][0]
            else:
                dynArray[x][y] = min((dynArray[x][y-1]+a[x-1][y]), dynArray[x-1][y] + b[x][y-1])
    printArray(dynArray)
    print(dynArray[-1][-1])




if __name__ == "__main__":
    initialize()

我正在针对这个 test.txt 文件对其进行测试

7
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
1 1 0 0
1 1 1 1
1 1 0 1
1 1 0 0
1 0 1 1 1 1 1
1 1 0 1 1 1 1
1 1 1 1 1 1 0
1 1 1 1 1 0 1
1 1 1 1 1 1 1

我的输出如下(包括打印语句)

-----A------
[1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 0, 1, 0, 0]
[1, 1, 1, 1, 0, 1, 1, 0]
-----B------
[1, 0, 1, 1, 1, 1, 1]
[1, 1, 0, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 0]
[1, 1, 1, 1, 1, 0, 1]
[1, 1, 1, 1, 1, 1, 1]
------------
5
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0]
------------
0 1
0 2
0 3
0 4
0 5
0 6
0 7
[0, 1, 1, 2, 3, 4, 5, 6]
[1, 2, 2, 2, 3, 4, 5, 6]
[2, 3, 3, 3, 4, 5, 6, 6]
[3, 4, 4, 4, 4, 5, 5, 5]
[4, 5, 5, 5, 5, 6, 6, 6]
6

答案应该是 5,我不知道我哪里错了。即使我在白板上用手做,我仍然得到 6。有什么明显的我遗漏的吗?谢谢。

【问题讨论】:

  • 我想我理解输入,但任务是什么?数字 5 代表什么?其他输出是什么?

标签: python multidimensional-array dynamic-programming


【解决方案1】:

要找到 5 的最低成本,您必须考虑沿街道移动和 所有 4 个可能方向的途径:

"""
ave_crossing[i][j] is the cost of crossing from avenue i to avenue i+1 (or vice versa) on street j
street_crossing[i][j] is the cost of crossing from street j to street j+1 (or vice versa) on avenue i
"""


def initialize():
    f = open("test.txt", "r")
    streets = int(f.readline().strip())
    aves = int(f.readline().strip())

    ave_crossing = []
    for x in range(streets + 1):
        ave_crossing.append([int(x) for x in f.readline().strip().split(" ")])
    ave_crossing = rotate(ave_crossing)

    street_crossing = []
    for y in range(aves + 1):
        street_crossing.append([int(x)
                                for x in f.readline().strip().split(" ")])
    return ave_crossing, street_crossing    

def printArray(arr):
    for x in arr:
        print(x)

def rotate(arr):
    return list(zip(*arr))

def findPath(ave_crossing, street_crossing):
    num_aves, num_streets = len(street_crossing), len(ave_crossing[0])
    dynArray = [[(ave + street) for street in range(num_streets)]
                for ave in range(num_aves)]
    printArray(dynArray)
    print("------------")

    queue = [(ave, street) for ave in range(num_aves)
             for street in range(num_streets)]

    for ave, street in queue:
        costs = []
        # consider the cost of all ways of arriving at (ave, street)
        if (street > 0):
            # start at (ave, street-1) and go to (ave, street)
            costs.append(dynArray[ave][street - 1] +
                         street_crossing[ave][street - 1])
        if (street < num_streets - 1):
            # start at (ave, street+1) and go to (ave, street)
            costs.append(dynArray[ave][street + 1] +
                         street_crossing[ave][street])
        if (ave > 0):
            # start at (ave-1, street) and go to (ave, street)
            costs.append(dynArray[ave - 1][street] +
                         ave_crossing[ave - 1][street])
        if (ave < num_aves - 1):
            # start at (ave+1, street) and go to (ave, street)
            costs.append(dynArray[ave + 1][street] + ave_crossing[ave][street])
        min_cost = min(costs, default=0)
        if (dynArray[ave][street] > min_cost):
            dynArray[ave][street] = min_cost
            # propagate the change in dynArray by recalculating dynArray
            # at neighboring locations
            neighbors = [(ave, street - 1), (ave, street + 1),
                         (ave - 1, street), (ave + 1, street)]
            neighbors = [(a, s) for a, s in neighbors if
                         0 <= a < num_aves and 0 <= s < num_streets]
            queue.extend(neighbors)

            print('dynArray[{}][{}] = {}'.format(
                ave, street, dynArray[ave][street]))
    printArray(dynArray)
    print(dynArray[-1][-1])

if __name__ == "__main__":
    ave_crossing, street_crossing = initialize()
    print("-----ave_crossing------")
    printArray(ave_crossing)
    print("-----street_crossing------")
    printArray(street_crossing)
    print("------------")
    print(len(street_crossing))
    findPath(ave_crossing, street_crossing)

产量

[0, 1, 1, 2, 3, 4, 5, 6]
[1, 2, 2, 2, 3, 4, 5, 6]
[2, 3, 3, 3, 4, 5, 5, 5]
[3, 4, 4, 4, 4, 5, 5, 5]
[4, 5, 5, 5, 4, 5, 6, 5]

dynArray 最低费用为 5。


上面的代码是通过应用以下三个想法从您的代码演变而来的:

  • 使用描述性变量名称。 x,y,a,b 不是描述性的。作为一个 阅读您的代码,它们的含义是一个谜。给自己一两个星期 并且您自己的代码的意图也可能成为您的难题。描述性的 变量名的行为类似于 cmets。他们将帮助澄清意图。到位 xy 让我们使用 avestreet,并代替 ab 让我们 (暂时)继续使用streetsArrayavesArray(但请参阅 下面)。

  • 在代码中预先说明:

    streetsArray[i][j] is the cost of crossing from avenue i to avenue i+1 (or vice versa) on street j
    avesArray[i][j] is the cost of crossing from street j to street j+1 (or vice versa) on avenue i
    

    当明确说明这一点时,streetsArrayavesArray 可能不是最具描述性的变量名。也许 ave_crossingstreet_crossing 会更好。但是请注意,这 在变量名中交换 streetave 的用法。

  • 修改算法以考虑“向上”移动或移动到 “左”——不仅仅是“下”和“右”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-26
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 2015-10-24
    相关资源
    最近更新 更多