Python中短路径算法的功能解决方案

时间:2016-04-07 11:40:12

标签: python shortest-path

我正在阅读Learn You Some Erlang for Great Good!并发现了有趣的谜题。我决定以最实用的方式在Python中实现它。 short path map

请参阅我的代码:

def open_file():
    file_source = open('resource/path.txt', 'r') # contains 50\n 10\n 30\n 5\n 90\n 20\n 40\n 2\n 25\n 10\n 8\n 0\n
    return file_source


def get_path_tuple(file_source, pathList=[]):
    try:
        node = int(next(file_source)), int(next(file_source)), int(next(file_source))
        pathList.append(node)
        get_path_tuple(file_source, pathList)
    except StopIteration:
        pass
    return pathList


def short_step(pathList, n, stepList):
    try:
        stepA = pathList[n][0] + pathList[n][1]
        stepB = pathList[n][1] + pathList[n][2]
        stepList.append(min([stepA, stepB]))
        short_step(pathList, n+1, stepList)
    except IndexError:
        pass
    return stepList


pathList = get_path_tuple(open_file(), [])
pathList.reverse()
print(short_step(pathList, 0, []))

但是我遇到了问题,我不知道如何保持当前位置的状态。结果是:[8, 27, 95, 40]。 你可以帮忙修改我的代码。

2 个答案:

答案 0 :(得分:1)

事实上,我认为,与所有寻路问题一样,您必须计算从开始到每个点的总路径长度。然后你必须计算A的路径列表和B的路径列表。

我不知道递归算法是否是练习的一部分,但我使用了一个简单的循环。

pathList = [[50,10,30],[5,90,20],[40,2,25],[10,8,999999]]

def all_steps(pathList):

    stepListA,stepListB = [],[]
    for n in range(0,len(pathList)):

        #Step to A
        if pathList[n][0]<=pathList[n][1] + pathList[n][2]:#A to A
            new_stepListA = list(stepListA)
            new_stepListA.append(pathList[n][0])
        else: #B to A 
            new_stepListA = list(stepListB)
            new_stepListA.extend([pathList[n][1],pathList[n][2]])          

        #Step to B
        if pathList[n][1]<=pathList[n][2] + pathList[n][2]:#B to B
            new_stepListB = list(stepListB)
            new_stepListB.append(pathList[n][1])
        else: #A to B 
            new_stepListB = list(stepListA)
            new_stepListB.extend([pathList[n][0],pathList[n][2]])   

        stepListA = list(new_stepListA)
        stepListB = list(new_stepListB)

    if sum(stepListA)<=sum(stepListB):
        print "finish on A"
        return stepListA
    else:
        print "finish on B"
        return stepListB


print  all_steps(pathList)

答案 1 :(得分:1)

在这种特定情况下,使用您的数据结构,您似乎应该能够并行运行两个场景:

  • A的费用
  • B的费用

您可以维持当前费用,并且您收集的数据会提供转换成本&#34;在第三个元素中。

所以你需要问:哪个更便宜?保持起跑路线,或切换到另一条路径?

path_list = [
        (50, 10, 30),
        (5, 90, 20),
        (40, 2, 25),
        (10, 8, 0),
]

A = 0
B = 1
Switch = 2

def cheapest_path(path_list, path=None, history=None):
    if history is not None:
        # Terminate when path_list is empty
        if not path_list:
            return history

        # Determine cost to stay this path, vs. cost to switch
        step = path_list[0]
        path_list = path_list[1:]

        stay_on_path = cheapest_path(path_list, path, history + [step[path]])
        switch_path = cheapest_path(path_list, B if path == A else A, history + [step[path], step[Switch]])

        return switch_path if sum(switch_path) < sum(stay_on_path) else stay_on_path
    else:

        pathA = cheapest_path(path_list, A, [])
        pathB = cheapest_path(path_list, B, [])
        return pathA if sum(pathA) < sum(pathB) else pathB

print(", ".join(map(str, cheapest_path(path_list))))