파이썬에서 재귀를 통해 살아남는 목록에 문제가 있습니다. 그래프에서 가능한 모든 경로 찾기

경멸 적으로

저는 완전히 연결된 그래프 (다른 노드에서 그래프의 모든 노드로 이동할 수 있음)를 가져 와서 주어진 최대 거리보다 짧은 해당 그래프에서 가능한 모든 경로를 찾는 파이썬 프로그램을 작성하고 있습니다.

이것이 내가 지금까지 코딩 한 것입니다.

def find_all_routes (cur_node, graph, willing_to_travel, visited, routesdict):
    """ Finds all routes possible within a certain distance.
    inputs
        cur_node: a dictionary with n entries, each of which is the distance to the nth
            dictionary in graph.
        graph: a list of n dictionaries, each of which contains n entries, each of which
            is the distance to the nth item in the list.
        willing_to_travel: the maximum distance we are willing to travel.
        visited: initialized as an empty list, will be populated nodes we've been to.
        all_routes: initialized as an empty list.
    Affects:
        all_routes is populated with every route permutation that can be traveled in under willing_to_travel distance.
    """
    #Add our current location to the visited list.
    for i in cur_node:
        if cur_node[i] == 0:
            visited.append(graph[i])

    # Add the current route to the dictionary.
    entry_no = len(routesdict)
    routesdict[entry_no] = visited
    print ("routesdict", routesdict)            # Just for diagnostic purposes.

    # Recursion with other nodes we can reach as the new start node.
    for i in cur_node:                               # For every place in the dictionary
        if graph[i] not in visited:                  # if we have not been there
            if cur_node[i] <= willing_to_travel:     # And if we can afford to go there
                find_all_routes(graph[i], graph, willing_to_travel - cur_node[i], visited, routesdict)

    return routesdict

def main():

    graph = [
        {0: 0.00, 1: 0.12, 2: 0.10},
        {0: 0.12, 1: 0.00, 2: 0.22},
        {0: 0.10, 1: 0.22, 2: 0.00}]

    max_distance = 10.0
    been_to = []
    routesdict = dict()

    routes = find_all_routes (graph[0], graph, max_distance, been_to, routesdict)

print ("Final output: ", routes)

if __name__ == "__main__":
    main()

이 결과는 다음과 같습니다.

routesdict:    {0: [{0: 0.0, 1: 0.12, 2: 0.1}]}
routesdict:    {0: [{0: 0.0, 1: 0.12, 2: 0.1}, {0: 0.12, 1: 0.0, 2: 0.22}], 1: [{0: 0.0, 1: 0.12, 2: 0.1}, {0: 0.12, 1: 0.0, 2: 0.22}]}
routesdict:    {0: [{0: 0.0, 1: 0.12, 2: 0.1}, {0: 0.12, 1: 0.0, 2: 0.22}, {0: 0.1, 1: 0.22, 2: 0.0}], 1: [{0: 0.0, 1: 0.12, 2: 0.1}, {0: 0.12, 1: 0.0, 2: 0.22}, {0: 0.1, 1: 0.22, 2: 0.0}], 2: [{0: 0.0, 1: 0.12, 2: 0.1}, {0: 0.12, 1: 0.0, 2: 0.22}, {0: 0.1, 1: 0.22 , 2: 0.0}]}
Final output:  {0: [{0: 0.0, 1: 0.12, 2: 0.1}, {0: 0.12, 1: 0.0, 2: 0.22}, {0: 0.1, 1: 0.22, 2: 0.0}], 1: [{0: 0.0, 1: 0.12, 2: 0.1}, {0: 0.12, 1: 0.0, 2: 0.22}, {0: 0.1, 1: 0.22, 2: 0.0}], 2: [{0: 0.0, 1: 0.12, 2: 0.1}, {0: 0.12, 1: 0.0, 2: 0.22}, {0: 0.1, 1:0.22, 2: 0.0}]}

도대체 추악하지만 우리가 방문하는 노드의 관점에서 다시 말하면 다음과 같이 진행됩니다.

routesdict [0]
routesdict [0, 1] [0, 1]
routesdict [0, 1, 2]  [0, 1, 2] [0, 1, 2]
Final out: [0, 1, 2]  [0, 1, 2] [0, 1, 2]

3 노드 그래프의 경우 가능한 모든 경로를 완료 할 수있을만큼 최대 거리가 충분히 높으면 출력이 다음과 같이 표시되기를 바랍니다.

All possible routes*: [0], [0,1], [0,1,2], [0,2], [0,2,1]
*If we must start at node 0.

===============

이제는 문제가 있다고 생각하지만 해결을 통해 생각할 수 없습니다. 문제는 "방문 된"목록의 현재 값을 뜯어 내고 계속 진행하는 대신 "방문한"목록의 정체성을 유지하고 있다는 것입니다.

따라서 재귀를 통해 처음으로 routedict [0]은 "visited"로 정의되고 노드 [0]이 첫 번째 경로로 올바르게 지정됩니다. 그러나 방문이 변경되면 routedict [0]이 업데이트되고 이제 [0,1]이라고 표시됩니다.

이것은 함수가 내가 원하는 재귀를 수행하는 것을 막는 것과 똑같은 일이며, 이것이 내가 기대하는 5 개 대신 3 개의 가능한 경로를 제공하는 이유입니다.

그래서, 더 깊은 재귀로 들어가면서 내 "방문한"목록을 유지하는 좋은 방법이 있지만 목록이 나머지 세계에 소급 적용되지 않도록 할 수 있습니까?

읽어 주셔서 감사합니다!

편집하다:

나는 이미 노선을 routedict로 변경하여 경로를 가져 오는 문제를 해결했습니다.

routesdict[entry_no] = visited[:]

그러나 방문 목록이 내 재귀를 깨지 않는 것에 대해 훨씬 더 단서가 없습니다!

Kittsil

두 가지 문제 모두 같은 원인으로 인해 발생합니다. Python은 값이 아닌 참조로 목록을 전달합니다.

첫째, 이것이 의미하는 바는 다음과 같습니다.

foo(a)with a를 int로 호출하면 내부 에서 실제 메모리 위치가 아닌 foo()값을 얻습니다 a. 당신은 a당신의 종이에 썼고 foo(), "이것은 a적어 두십시오."라고 보여줍니다 .

그러나 목록이나 객체로 bar(b)with 를 호출 b하면 값을 b얻지 못하고 b메모리 위치를 습니다. 여전히 b종이에 남아 있지만 bar()"이봐, b꽤 복잡하고 새 종이에 복사 할 가치가 없을 것입니다. 내 문서를 공유 할 수 있습니다."라고 말합니다. 이것은 프로그램이 정말 느려지는 것을 방지하는 데 유용하지만 경험하고 있듯이 모든 변경 사항 bar()모든 곳 에서 b변경 된다는 것을 의미합니다 b.

문제를 해결하려면 변경하지 않으려는 개체의 복사본을 전달해야합니다. 에 추가 visited때 이미 이것을 알아 routesdict냈지만 실제로는

find_all_routes(graph[i], graph, willing_to_travel - cur_node[i], visited[:], routesdict)

즉,에 대한 모든 호출 find_all_routes()visited.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관