거리와 관련이없는 비용을 최소화하면서 여러 줄의 방문 지점


18

이 ACM ICPC 문제에 대한 도움이 필요합니다. 내 현재 아이디어는 이것을 가장 짧은 경로 문제로 모델링하는 것입니다.이 문제는 문에서 설명합니다.

문제

를 제외한 다른 위치 N = 1000의 1 차원 수선을 따라 위치한 핵 폐기물 용기가 있습니다 . 사람은 모든 쓰레기통을 수집해야합니다. 폐기물 컨테이너가 수집되지 않은 1 초마다 1 단위의 방사선을 방출합니다. 그 사람은 1 초에 시작하여 1 초마다 유닛 을 움직일 수 있으며 , 폐기물을 수집하는 데는 상당한 시간이 걸립니다. 모든 컨테이너를 수집하는 동안 방출되는 최소 방사량을 찾고 싶습니다.-500,000 to 500,000x=0x = 01

샘플 입력 :

4에 위치한 컨테이너 [-12, -2, 3, 7].

이러한 용기를 수거하는 최선의 순서 [-2, 3, 7, -12]는 최소 50단위 방출입니다 . 설명 : 사람이 -22 초 안에 가면서 그 시간 동안 2 units방사선이 방출됩니다. 그런 다음 배럴이 방사선 단위를 방출하도록 3(거리 :)로 이동합니다 . 그는 그 배럴이 유닛 을 방출 한 곳 으로 가기까지 몇 초가 걸립니다 . 그는 그 배럴이 유닛 을 방출 한 곳 으로 가기 위해 몇 초가 걸립니다 . , 이것이 정답입니다.52 + 5 = 74x = 72 + 5 + 4 = 1119x = -122 + 5 + 4 + 19 = 302 + 7 + 11 + 30 = 50

노트

확실한 O(N!)해결책이 있습니다. 그러나 가장 가까운 것으로 이동하거나 가장 가까운 클러스터로 이동하는 것과 같은 욕심 많은 방법을 살펴 보았지만 작동하지 않았습니다.

나는이 문제에 대해 오랫동안 생각해 왔으며 그래프 검색 문제로 모델링했습니다.

  1. 0기준 위치로 삽입 합니다 (초기 상태 임).
  2. 그런 다음 위치를 최소에서 최대로 정렬합니다.
  3. 우리는 다음이 BFS / PFS, 이렇게 state구성을
    • 두 정수 lr우리가 이미 방문한 것을 정렬 된 위치에 배열의 연속 범위를 나타냅니다
    • loc우리가 범위의 왼쪽 또는 오른쪽 끝점에 있는지 알려주 는 정수
    • time경과 시간을 알려주 는 정수
    • 지금까지 총 비용을 알려주는 정수 '비용'(방문한 노드 기준)
  4. 각 상태에서 [l-1, r] 및 [l, r + 1]로 이동하여 그에 따라 다른 3 개의 정수를 조정할 수 있습니다.
  5. 최종 상태는 [0, N]이며 두 종료 위치를 모두 확인합니다.

그러나 [L, R, loc]상태를 고유하게 정의하는 것은 아니며 각 L, R, loc, and time상태를 최소화하면서 저장해야합니다 cost. 이것은 지수 알고리즘으로 이어지며, 여전히 좋은 결과를 얻기에는 너무 느립니다.

누구든지 내 아이디어를 넓히거나 올바른 방향으로 나아가도록 도울 수 있습니까?

편집 : 아마도 이것이 동적 프로그래밍 최적화 문제로 모델링 될 수 있습니까? 그것에 대해 생각하면 그래프 검색 솔루션과 동일한 문제가 있습니다. 전류 cost가 낮다는 것이 그 하위 문제에 대한 최적의 대답이라는 것을 의미하지는 않습니다 time.

욕심이 작동하지 않습니다 : 나는 특정 장소로 ​​이동하는 비용을 추정하는 탐욕스러운 선택 알고리즘을 가지고 있습니다 (예를 들어 우리가 오른쪽으로 이동하면 왼쪽 배럴까지의 거리를 두 배로 늘림).

휴리스틱으로 우선 순위 우선 검색을 수행 할 수 있습니까? 휴리스틱은 현재 여행 비용과 경과 시간을 결합 할 수 있습니다.


최단 경로 알고리즘은 어떻습니까? Dijkstra의 알고리즘처럼?
suraj_fale

나는 그것을 시도했지만, 내가 정말로 잘못하고 있다고 생각합니다. 번호가 매겨진 목록과 함께 내 알고리즘 (최우선 우선 검색 또는 BFS)을 맨 아래에 설명했습니다.
Barron W.

이것은 당신을 도울 것입니다 ... stackoverflow.com/q/14639346/585398
suraj_fale

죄송합니다.이 두 가지 문제가 어떻게 관련되어 있는지 모르겠습니다. 설명 할 수 있습니까?
Barron W.

2
이것은 실제 문제가 아닌 ACM ICPC 연습 문제입니다. 다른 참고로, 나는 상태를 줄이려고 노력했지만 아무 소용이 없었습니다. DP 솔루션 작성을 시도했지만 작동하지 않았습니다. 상태는 L, R, POS였습니다.
Barron W.

답변:


4

문제를 위치 쌍의 직접 그래프로 보면이를 향상시킬 수 있다고 생각합니다.

이 예에서는 값이 -9, -6, -1, 3 및 5 인 행을 사용합니다.

텍스트만으로 그래프를 그리는 것이 너무 어렵 기 때문에 쌍을 표로 표현하겠습니다. 우리는 세포가 그 두 위치 사이의 모든 용기가 수집 된 상태를 나타내는 것으로 생각할 수 있습니다. 각 셀에는 두 개의 값이 있습니다. 하나는 남은 비용을 나타내고 다른 하나는 오른쪽으로가는 비용을 나타냅니다 (다음 컨테이너로).

값은 단순히 두 점 사이의 거리에 두 점 외부의 배럴 수를 곱한 값 + 1 로 계산할 수 있습니다 . 두 숫자가 동일한 부호를 갖는 셀은 반대 부호의 모든 배럴이 수집 된 경우를 나타냅니다. 이들은 0에서 멀어지는 방향의 배럴 수만 사용하여 계산됩니다.

X의 표 값은 해당 방향으로 이동할 수 없음을 의미합니다 (해당 방향의 모든 배럴이 사용됨). 행은 수집기의 현재 위치를 나타내고 열은 다음 반대 배럴의 위치를 ​​나타냅니다.

    +------+------+------+------+------+
    |  -9  |  -6  |  -1  |   3  |   5  |
+---+------+------+------+------+------+
|-9 |      |      |      | X, 24| X, 14|
+---+------+------+------+------+------+
|-6 | 3, X |      |      | 9, 27| 6, 22|
+---+------+------+------+------+------+
|-1 |      |10, X |      |20, 8 |15, 18|
+---+------+------+------+------+------+
| 3 |24, 4 |27, 6 |16, 8 |      | X, 2 |
+---+------+------+------+------+------+
| 5 |14, X |22, X |18, X |      |      |
+---+------+------+------+------+------+

사각형 사이를 이동하는 규칙은 다소 혼란 스러울 수 있습니다.

음수 열의 경우 규칙은 다음과 같습니다.

  • 오른쪽으로 이동하면 한 셀 아래로 이동합니다.
  • 왼쪽으로 이동하면 한 셀 아래로 이동 한 다음 대각선을 따라 미러링됩니다.
  • 오른쪽 값이 X 인 경우 왼쪽으로 이동하면 대각선 (열과 행이 같은 곳)으로 이동하고 1만큼 왼쪽으로 이동합니다.

양수 열의 경우 규칙은 다음과 같습니다.

  • 왼쪽으로 이동하면 한 셀 위로 이동합니다.
  • 오른쪽으로 이동하면 한 셀 위로 이동 한 다음 대각선을 따라 미러링됩니다.
  • 왼쪽 값이 X 인 경우 오른쪽으로 이동하면 대각선으로, 오른쪽으로 하나씩 이동합니다.

이제 Dijkstra의 알고리즘을 실행하여 그래프를 탐색하기 위해 이러한 이동 규칙을 사용하여 최상의 경로를 계산할 수 있습니다. 우리의 시작 위치는 (-1, 3)과 (3, -1)이며 각각 초기 비용은 5와 15입니다. 일단 두 개의 끝 위치 ((-9, -9)와 (5, 5)의 오른쪽)에 대한 값을 계산하면 두 값 중 작은 것이 우리의 답입니다.

각 단계의 실행 시간은 다음과 같습니다.

  • 라인을 따라 입력 값을 처음 정렬하기위한 O (N log N)
  • 테이블 / 그래프 계산을위한 O (N ^ 2)
  • 그래프에서 Dijkstra를 실행하기위한 O (N ^ 2 log N) (주 : 주어진 정점에 대해 최대 두 개의 모서리가 있습니다).

처음 두 단계는 마지막 단계에 의해 결정되므로 전체 런타임은 O (N ^ 2 log N)이며 이는 문제에 대한 충분한 런타임이어야합니다.


1

최단 거리

어제 Java 응용 프로그램을 작성하여 문제를 해결했습니다. SRJ가 그의 의견에서 말했듯이 문제는 기본적으로 가장 짧은 거리 문제입니다. 방사선은 단지 가장 짧은 거리와 함께 값을 축적 할 수 있음을 보여줍니다.

기본적으로 여기 내가 한 일이 있습니다.

  • 컨테이너 번호를 List <Integer>에 넣습니다.
  • 리스트에는 요소가 있지만;
    • 가장 가까운 요소 찾기
    • 요소가 하나 있으면 걸어서 제거하십시오.
    • 요소가 두 개인 경우 경로를 복사하고 두 요소로 이동하십시오.
  • 가장 작은 방사선 값을 가진 경로를 찾으십시오.

다음은 응용 프로그램의 일부 출력입니다.

10 containers are located at [-90, -75, -47, -9, 9, 26, 48, 50, 64, 79].

You walk to position -9 and pick up the container.  The total radiation emitted is 90 units.
You walk to position 9 and pick up the container.  The total radiation emitted is 252 units.
You walk to position 26 and pick up the container.  The total radiation emitted is 388 units.
You walk to position 48 and pick up the container.  The total radiation emitted is 542 units.
You walk to position 50 and pick up the container.  The total radiation emitted is 554 units.
You walk to position 64 and pick up the container.  The total radiation emitted is 624 units.
You walk to position 79 and pick up the container.  The total radiation emitted is 684 units.
You walk to position -47 and pick up the container.  The total radiation emitted is 1,062 units.
You walk to position -75 and pick up the container.  The total radiation emitted is 1,118 units.
You walk to position -90 and pick up the container.  The total radiation emitted is 1,133 units.

나는 어떤 식 으로든 알고리즘을 최적화하지 않았습니다. 입력 숫자 목록이 정렬되어 있음을 알지 못했습니다. (나는 doofus입니다.)

최대 값, 컨테이너 1,000 개 및 -500,000-500,000 범위의 코드로 코드를 실행하면 코드를 실행하는 데 3 초가 걸렸습니다. 그 시간의 대부분은 콘솔에 1,000 개의 인쇄 라인을 쓰는 것이 었습니다.

나는 큰 O 사람은 아니지만 가장 짧은 경로 알고리즘을 걷는 무차별 힘은 O (N!)이 아니라 O (N squared)라고 생각합니다.

입력 번호가 정렬되어 현재 위치의 양쪽에서 두 숫자 만 확인해야한다는 사실을 활용하면 응용 프로그램을 O (N)에 가깝게 얻을 수 있습니다. 내가 얻을 때 List에서 요소를 제거하기 때문에 2 개의 숫자 만 확인하면됩니다.

욕심 많은 알고리즘과 같은 다른 알고리즘을 사용하여 대략적인 솔루션을 찾았습니다.

내 프로그램이 3 초가 아닌 3 시간 동안 실행 되었다면, 선택할 수 있습니다.

충분한 솔루션으로 충분합니까?

다시 말해, 충분한 답변을 얻기 위해 처리 속도를 바꾸고 자합니까?

충분한 대답이 충분하면 근사 알고리즘을 사용합니다.

완벽한 답을 원한다면 가장 짧은 길을 걸어야합니다. 바로 가기가 없습니다.

누군가 내가 내 코드를 게시하기를 원한다면 그렇게 할 것입니다. 가장 짧은 보행 알고리즘을 구현할 수 있는지 확인하고 싶었으므로 여전히 버그가 있다고 확신합니다.


1

나는이 문제를 제 2^N시간에 해결할 수있는 해결책을 가지고 있지만 문제가 있지만 문제를 해결 하는 데 도움이되는 방법이라고 생각합니다.

문제를 그래프로 모델링하는 대신 이진 결정 트리 (예 :)로 모델링합니다 T. 각 수준에서 오른쪽 또는 왼쪽으로 이동 중에서 선택해야합니다. 각 모서리의 '비용'을 계산하는 것은 매우 쉽습니다. 하자 h(K)현재 노드의 높이가 될, K가장자리의 다음 비용은 가고 left_child(K) = h(K) x dist(K, left_child(K)). 비슷한 계산으로 오른쪽 자식에 대한 가장자리 비용이 충분합니다. 이 트리를 구성하고 누적 에지 비용을 추적하고 총 비용이 가장 작은 리프 노드 경로를보고합니다.

각 에지의 길이 dist(K, left_child(K))는 다음 사이트로 이동하는 시간을 나타내며 하위 트리의 높이는 남아있는 사이트의 수 (예 : 여전히 방사선을 방출) 이므로 비용 계산이 작동합니다 .

이제이 프레임 워크의 트릭은 일부 지점을 따라 검색을 확장하는 것을 무시할 수있는 '증명'하는 데 사용할 수있는 휴리스틱이 있는지 확인하는 것입니다. 내 직감은 그러한 휴리스틱에 대해 그것을 물리 칠 사이트 배열이 있지만 누군가가 무언가를 생각해 낼 수 있다는 것입니다.

많은 사람들이 그래프에 최단 경로 솔루션을 적용 할 것을 제안했지만 그러한 솔루션이 작동 할 수 있는지에 대한 의구심이 있습니다. 문제의 '그래프'에있는 이웃은 당신이 따르는 경로에 따라 바뀔 것입니다. 로 원래의 게시물에 예를 들어 [-12, -2, 3, 7]당신이 가면 -2다음 -123'이웃'이되고 경우에 이동 3한 후-27이웃입니다. 양수 및 음수 값의 모든 가능한 '쌍'은 최종 그래프에서 잠재적으로 근시 일 수 있습니다. 동적 그래프에서 아마도 가장 짧은 경로 알고리즘을 알지 못합니다.


0

모든 단계를 가장 가까운 배럴로 이동하는 것과 가장 가까운 배럴로 이동하는 것 사이의 이진 선택으로 생각하는 것이 가장 합리적이라고 생각합니다. 모션을 만들어 전체적으로 발생할 수있는 방사 장치의 수를 자세히 설명하는 비용 함수를 사용하고 비용이 가장 저렴한 장치를 선택하십시오.

가장 가까운 배럴을 단순히 고려하지 말고 배럴에서 멀리 이동하면 두 배의 방사선을 효과적으로 추가한다고 가정합니다. 멀리 이동하면 나중에 해당 방향으로 뒤로 이동해야하는 비용이 발생했기 때문입니다.

[-12, -2,3,7]의 예에서 왼쪽으로 이동하면 왼쪽에 총 14 (2 + 2 + 10), 오른쪽에 18 (2 + 2 + 5 + 9)이 발생합니다. 오른쪽으로 이동하면 오른쪽에 10 (3 + 3 + 4), 오른쪽에 26 (3 + 3 + 5 + 15)가 발생합니다. 처음에는 올바른 해결책이 분명 왼쪽입니다. 모든 연속적인 움직임에 대해 유사한 계산을 수행 할 수 있습니다.

그 후 문제는 기본적으로 검색으로 감소하므로 복잡도는 O (nlog (n))이어야하며 이는 O (n!)보다 훨씬 낫습니다. 나는 이것이 기본적으로 O (nlog (n))보다 더 잘 할 수없는 비교 기반 검색 알고리즘이기 때문에 이것이이 문제에 대해 존재할 수있는 가장 낮은 복잡성이라고 생각합니다.

분명히 나는이 설명에 대해 충분히 명확하지 않았으므로 좀 더 프로그래밍 방식으로하기로 결정했습니다. 1. 왼쪽으로 이동하여 발생하는 비용과 현재 위치를 기준으로 오른쪽으로 이동하여 발생하는 비용을 계산하십시오. 가장 비싼 방향 3. 방향으로 이동하는 비용을 계산할 때 도달 한 배럴을 고려에서 제거하십시오.

비용 계산 : 1. 주어진 방향에서 가장 가까운 배럴을 식별합니다. $ dist는 현재 위치에서 주어진 방향으로 가장 가까운 배럴까지의 거리라고 가정하십시오. 2. 비용은 N * $ dist로 초기화되며 여기서 N은 활성 배럴 만 고려합니다. 3. 여기에 $ dist로 표시되는 새 위치가 남아있는 모든 배럴과의 거리를 추가하십시오.


1
항상 작동하지는 않습니다. 좌표를 정렬 한 다음 상태에 [i..j] 범위 (방문한 범위를 나타냄)와 비용 및 현재 시간이 포함 된 검색을 수행 할 수 있습니다.
Barron W.

언제 작동하지 않습니까?
Slater Victoroff

실패한 간단한 테스트 사례가있었습니다. 찾아 보려고했지만 N = 4 또는 5였습니다.
Barron W.

[43, -18, -98, -82, 63]
Barron W.

또한 같은 경우 [-10,-11, 10,20,30,40,50,60,70]. 정확하고 유일한 해결책은 모든 부정적인 것을 모은 다음 긍정적 인 것을 모으는 것입니다. 455의 답변입니다.
Barron W.

0

부분 솔루션-나중에 다시 설명하겠습니다.

"기본"전략이 왼쪽 또는 오른쪽으로 실행되는 것으로 가정하십시오. 이제 한 통을 집어 올리는 다른 방법으로 조금만 여행해도되는지 물어보십시오. 답을 계산하는 것은 상당히 쉽습니다.

샘플 입력의 경우 오른쪽 끝까지 실행하는 것이 왼쪽 끝보다 저렴합니다. -2의 가치가있는 사이드 트립입니까? 기본 전략에서 0에서 3으로 이동 당 4 개의 방사선 단위를 "지불"했기 때문에 이제는 3으로 3을 지불했습니다. 7에서 이제는 2 등입니다.) +0에서 -2로 이동하는 비용이 한 이동 당 1 씩 감소하여 총 16 개에 대해 2 개 더 절약합니다.

그러나 순이익이 (16-14) = 2 인 경우 -2로 이동 한 다음 다시 14 중 0 (-2로 이동하면 4 단위, 0으로 다시 이동하면 3)으로 돌아가는 비용이 추가됩니다. 이를 계산하기 위해 각 결정에 대한 전체 문제를 해결하기위한 정확한 비용을 평가할 필요는 없습니다. 모든 방법을 올바르게 실행하는 것이 올바른 방법으로 실행하는 것보다 비용이 적게 듭니다. 많은 폐기물 용기가 당신의 양쪽에 있고 가장 가까운 2까지의 거리입니다. 그래서 그것은 O (N ^ 2)입니다.

한 가지 중요한 문제를 제외하고 – 나는 당신이 끝까지 끝까지 달려 갈 것이라고 가정했으며, 우리는 당신이 두 배로 돌아갈 수 있다는 것을 알고 있습니다. 이를 정리하려면 계산을 업데이트해야합니다. 샘플 입력의 경우 0에서 7까지의 속도로 실행하는 동안 초당 초당 1 개의 적은 총 방사를 방출하여 14를 절약한다고 가정했습니다. 그러나 7로 돌아 가기 전에 두 배로 돌아 가면 비용이 절감됩니다.

모든 가능성을 시도하지 않고 다음 더블 백을 계산하는 방법을 모르기 때문에 우리는 O (2 ^ N)으로 되돌아갑니다.

예외-가지 치기와 함께 2 ^ N입니다. 나는 -2 로의 "side trip"비용이 14이지만 비용이 가장 많이 들기 전에 더 많은 side trip을하지 않으면 16을 얻는다고 계산했다. 가장 오른쪽의 숫자가 5라면 -2에 대한 사이드 트립이 지불 할 수 없다는 것을 즉시 알 것입니다. (아직도 14, 최대 혜택 12). -2로 가서 6에 도달하기 전에 사이드 트립을하는 것도 고려할 필요가 없습니다. 왜냐하면 항상 처음에 그 지점으로 바로가는 것보다 열등하기 때문입니다.


0

나는 경로가 복잡한 한 문자열이있는 곳에서 2 * N ^ 2 튜플 (부울, int, int, int, 문자열)을 유지하면서 너비 우선 탐색을 사용하여 해결할 수 있다고 생각합니다.

튜플은 (최소 또는 최대 부울, 최소 위치 이동, 최대 위치 이동, 총 방사 방출, 경로 기록)입니다.

알고리즘은 다음과 같습니다.

  1. 튜플 풀을 단일 항목 (최소, 0, 0, 0, "")으로 초기화하십시오.
  2. 수영장에서 최소한의 방사선이 방출되는 요소를 찾으십시오. 최소 및 최대가 모든 배럴의 최소 및 최대에 해당하는 경우 경로 기록이 최적의 솔루션입니다. 그렇지 않으면 풀에서 삭제하십시오.
  3. 이 튜플의 두 자손을 계산하십시오. 각 튜플은 다음 처리되지 않은 배럴에 대해 왼쪽이나 오른쪽으로 걷는 것과 같습니다.
  4. 자손을 수영장에 넣습니다. 풀에 새 하위 항목과 동일한 부울, 최소 및 최대를 가진 요소가 이미있는 경우 더 높은 방사 계수를 가진 요소를 버립니다.
  5. 고토 2.

지배적 인 튜플을 찾아서 제거하면 성능이 크게 향상됩니다. 각 튜플에 'bred'플래그를 추가하고 플러드 튜플을 풀에 두는 것이 좋습니다.

튜플을 저장하는 방법을 결정하고 번식을위한 지배와 새로운 요소를 찾기 위해 결정해야 할 중요한 결정도 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.