문제

나는 무방향을 그래프로 약 100 노드에 대해 200 가장자리입니다.하나는 노드가'이 시작,하나는'엔',그리고 다스에 대해'이라는 mustpass'.

나를 찾을 필요가 가장 짧은 경로를 통해 이 그래프에서 시작되는'시작'을 종료에는'말', 를 통해 전달 모든의'mustpass'노드(어떤 순서로).

( http://3e.org/local/maize-graph.png / http://3e.org/local/maize-graph.dot.txt 그래프에 나타 옥수수에서 미로 Lancaster,PA)

도움이 되었습니까?

해결책

다른 사람들이 비교를 여행하는 외판원 문제는 아마 하지 않은 읽기 당신의 질문에 신중하다.에서 작은 술,목적을 찾기 위해 방문하는 가장 짧은 주기 모든 꼭지점(은 해밀턴 사이클)-그것에 해당하는 노드 표시'mustpass'.

귀하의 경우,주어진만 있는 것으로 다스에 대해'이라는 mustpass',그리고는 12!보(479001600),당신은 단순히 모든 시도 순열의'mustpass'노드에 가장 짧은 경로에서'시작'에서'말'을 방문하는'mustpass'노드에는 순서-그것은 단순히 연결하는 가장 짧은 경로 사이의 모든 두 개의 연속된 노드에서는 목록이다.

다른 말로는,먼저 찾아 사이의 최단 거리의 각 쌍점(사용할 수 있습 dijkstra 알고리즘이나 다른 사람,하지만 사람들과 작은 숫자(100 노드),심지어 가장 간단한 코 드 Warshall 알고리즘 에서 실행됩니다 시간).다음 한 번,당신이 테이블에 있는 모든 시도 순열의'mustpass'노드,나머지.

무언가 이것을 좋아한다:

//Precomputation: Find all pairs shortest paths, e.g. using Floyd-Warshall
n = number of nodes
for i=1 to n: for j=1 to n: d[i][j]=INF
for k=1 to n:
    for i=1 to n:
        for j=1 to n:
            d[i][j] = min(d[i][j], d[i][k] + d[k][j])
//That *really* gives the shortest distance between every pair of nodes! :-)

//Now try all permutations
shortest = INF
for each permutation a[1],a[2],...a[k] of the 'mustpass' nodes:
    shortest = min(shortest, d['start'][a[1]]+d[a[1]][a[2]]+...+d[a[k]]['end'])
print shortest

(물론 실제 코드는,당신이 원하는 경우에 당신은 실제 경로에 당신을 추적하는 순열은 짧은 거리,또한 무엇이든 쌍 가장 짧은 경로는,하지만 당신은 아이디어를 얻을 수 있습니다.)

그것은에서 실행됩니다 대부분에서 몇 초 만에 모든 합리적인 언어:)
[있는 경우 n 노드와 k'mustpass'노드 실행 시간은 오(n3 도)드 Warshall 부분 O(k!n)에 대한 모든 순열 부분 100^3+(12!)(100) 은 실제로 땅콩하지 않는 한 당신은 정말 제한적 제약 조건이 있습니다.]

다른 팁

실행 Djikstra 의 알고리즘 을 찾기 위해 가장 짧은 경로 사이의 중요한 모든 노드(의 시작,종료하고해),그 후 깊이 먼저 통과해 당신에게 가장 짧은 경로를 통해 결과 를 본다면 이를 만지는 모든 노드가 시작하...mustpasses...말

실제로,문제는 당신이 게시 유사한 판매원은,그러나 제 생각에 가까이하는 간단하 pathfinding 문제입니다.을 필요로 하는 것보다 서로를 방문하는 모든 노드에,당신은 단순히 당신이 방문해야는 특정 설정 노드의 짧은 시간에(거리)가능합니다.

그 이유는 것과는 달리,외판원 문제는 옥수수는 미로에 당신을 허용하지 않습니다 여행에서 직접 어떤 하나의 포인트를 다른 어떤 시점에서 필요를 통해 전달하는 다른 노드를 얻을 수 있습니다.

나는 것이 실제로 추천*경로 탐색하는 기술로 고려해야 합니다.당신이 설정에 의해 결정되는 노드에 액세스할 수 있는 다른 노드는 바로,그리고 무엇""비용을 각각의에서 특정 노드입니다.이 경우에,그것은 다음과 같이 각 베스트 웨스턴 플라자 될 수 있는 동등한 비용 때문에,귀하의 노드 보이 상대적으로 밀접한 간격.A*이 정보를 사용할 수 있습을 찾기 위해 저 경로 사이의 두 개의 포인트입니다.해야 하므로 얻는 지점에서 B 지점을 방문에 대한 12inbetween,심지어 무차별 접근 방식을 사용하여 경로 탐색 해치지 않을 것 이다.

그냥 있는 대안을 고려해야 합니다.지 놀랍게도 다음과 같 외판원 문제,그리고 사람들은 좋은 논문을 읽지만,가까이 보면 그만 놓았 것들입니다.^_^이에서 오는 마음의 비디오 게임 프로그래머는 이런 종류의 것들이다.

이것은 두 가지 문제...스티븐 로우 지적이지만 충분히 존경을 포기 후반의 문제입니다.

을 발견한 가장 짧은 경로 사이의 중요한 모든 노드(start,end,mustpass).이 경로는 발견을 작성할 수 있습니다 간편 그래프,각 가장자리에 새로운 그래프의 경로 중 하나에서 중요한 다른 노드에서 원래 그래프입니다.많은 경로 탐색 알고리즘에 사용할 수 있는 가장 짧은 경로를 찾을 수 있습니다 여기.

일단 당신이 새로운 그래프,하지만,당신이 정확하게 여행하는 판매원제(만,거의...할 필요가 없으로 돌아가려면 시작 지점).모든 게시물의 관,위에서 언급한이 적용됩니다.

앤드류 최고 권 아이디:

1)Djikstra 의 알고리즘 2)일부 술을 휴리스틱.

추천 Lin-커 휴리스틱:그것은 하나의 가장 잘 알려진 모든 NP 완전한 문제입니다.다른 것을 기억하는 확장된 그래프 후 다시 2 단계 수 있는 루프를 확장 경로를,그래서 당신이 가야 하위 단락시키는 이러(모습에서도 정점의 경로를 따라).

실제로 얼마나 좋은 확실하지 않는 이 솔루션은 상대적 최적합니다.거기에 아마 어떤 병리학적인 경우와 회로 단락.후에,이 문제를 처럼 많은 슈타이너리: http://en.wikipedia.org/wiki/Steiner_tree 그리고 당신은 확실히 수 없 대략적인 슈타이너리에 의해 계약의 그래프와 실행 Kruskal 의 예입니다.

TSP 문제에 대한 NP-어렵기 때문에 원래 질문하는 것이 필요하지 않해 노드를 방문했습니다.이 답을 훨씬,훨씬 간단하 brute-force 후 컴파일 목록의 가장 짧은 경로를 사해 노드를 통해 dijkstra 알고리즘.이있을 수있는 좋은 방법이지만 간단한 것을 간단히 작업을 바이너리 나무 뒤에 있다.상상의 목록 노드[시작,a,b,c,끝].Sum 간단한 거리[시작->a>b>c>끝]이것은 새로운 대상 거리를 이길 수 있습니다.지금 시도[시작->a->c>b>끝]과는 경우에는 설정을 대상으로(그리고 그 기억에서 온 그 패턴의 노드).거꾸로 작업을 통해 순열:

  • [시작->a>b>c>끝]
  • [시작->a->c>b>끝]
  • [시작->b>a>c>끝]
  • [시작->b>c>a>끝]
  • [시작->c>a>b>끝]
  • [시작->c>b>a>끝]

그 중 하나는 것이다.

(어디는'여러 번 방문하'노드의 경우,어떤?그들은 단지 숨겨진에서 가장 짧은 경로를 초기화하는 단계입니다.가장 짧은 경로를 사과 b 포함될 수 있습 c 또는 끝 지점입니다.당신이 필요하지 않료)

의 양을 고려하여 노드 및 가장자리에 상대적으로 유한할 수 있습을 계산한 가능한 모든 경로 및 짧은 하나입니다.

일반적으로 이것으로 알려진 여행 salesman 문제,그리고 결정적이지 않은 다항식 runtime,상관없이 사용하는 알고리즘.

http://en.wikipedia.org/wiki/Traveling_salesman_problem

는 방법에 대한 무력을 사용하에서 다스의'방문해야하는'노드입니다.당신은 커버할 수 있는 모든 가능한 조합의 12 노드를 쉽게 충분하고,이를 최적의 회로를 따를 수 있습니다 그들을 커버합니다.

지금 당신의 문제는 단순화 하나를 찾는 최적의 경로에서 시작 노드의 회로,당신이 그 주위에 따를 때까지 커버,그리고 그런 다음 경로를 찾을 수 있는 끝입니다.

최종 경로로 구성됩니다:

시작->경로를 회로*->회로의 방문해야하는 노드->경로 끝*->말

을 찾는 경로가 표시*다음과 같이

하이*****에서 검색을 시작하는 노드가 모든 지점에서 회로 에 대한 각각의 이러한 하이*****다음 검색 및 이전 노드에 회로 끝(할 수 있기 때문에 따라 회로 라운드에서 하나 방향) 당신이 무엇을 끝으로 많은 검색 경로를 당신이 선택할 수 있습니다 가장 낮은 비용.

많은 최적화를 캐싱하여 검색,하지만 제가 생각하는 이성이 좋은 솔루션입니다.

그는 아무데도 가지 않는다 근처를 찾고 최적의 솔루션이기 때문에,하지만 그를 포함할 수 있었을 떠나 방문해야하는 회로 내에 검색합니다.

한 것이 언급되지 않는,어디서나 여부를 확인에 대한 동일한 정점을 두 번 이상을 방문에서의 경로입니다.답변의 대부분은 여기에 그 확인을 방문하는 가장자리로 여러 번,그러나 나의 가진 질문(경로를 방문하지 같은 정점을 두 번 이상!) 다는 것입 확인 방문 같은 정점을 두 번.

너무 무력한 접근 방법 적용,하지만 당신을 제거해야 정점을 이미할 때 사용하려는 시도를 계산하는 각 하위 집합의 경로입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top