[algorithm] 폭탄 적하 알고리즘

n x m음이 아닌 정수로 구성된 행렬 이 있습니다 . 예를 들면 다음과 같습니다.

2 3 4 7 1
1 5 2 6 2
4 3 4 2 1
2 1 2 4 1
3 1 3 4 1
2 1 4 3 2
6 9 1 6 4

“폭탄 제거”는 대상 군의 수와 그 이웃 8 개를 최소 0으로 줄입니다.

x x x
x X x
x x x

모든 셀을 0으로 줄이는 데 필요한 최소 폭탄 수를 결정하는 알고리즘은 무엇입니까?

B 옵션 (주의 독자가 아니기 때문에)

실제로 첫 번째 버전의 문제는 내가 찾고있는 것이 아닙니다. 나는 전체 작업을주의 깊게 읽지 않았으며 추가 제약이 있습니다.

연속 된 행이 증가하지 않아야하는 간단한 문제는 어떻습니까?

8 7 6 6 5 가능한 입력 순서입니다

7 8 5 5 2 7-> 8 시퀀스에서 성장하기 때문에 불가능합니다.

어쩌면 “쉬운”사례에 대한 답변을 찾는 것이 더 어려운 솔루션을 찾는 데 도움이 될 것입니다.

추신 : 나는 우리가 동일한 상황을 여러 번 가질 때 상단 줄을 정리하기 위해 최소 폭탄이 필요하다고 생각합니다. 행의 “왼쪽”에서 대부분의 폭탄을 사용하는 폭탄을 선택합니다. 여전히 올바른 증거가 있습니까?



답변

이것을 간단한 하위 문제로 줄이는 방법이 있습니다.

설명에는 알고리즘과 알고리즘이 최적의 솔루션을 제공하는 이유의 두 부분이 있습니다. 첫 번째는 두 번째가 없으면 이해가되지 않으므로 그 이유부터 시작하겠습니다.

직사각형 폭격을 생각한다면 (아직 큰 직사각형을 가정하십시오-가장자리가없는 것으로 가정하십시오) 경계에서 빈 사각형의 사각형을 0으로 줄이는 유일한 방법은 경계를 폭파하거나 중공 사각형을 폭파하는 것입니다. 주변의 정사각형. 경계 레이어 1을 호출하고 그 안의 직사각형을 레이어 2라고합니다.

중요한 통찰력은 포인트 폭격 레이어 1이 없다는 것입니다. 그렇게하는 “폭발 반경”은 항상 레이어 2의 다른 사각형 폭파 반경 내에 포함되어 있기 때문에 쉽게 확신 할 수 있어야합니다.

따라서 주변을 폭파시키는 최적의 방법을 찾는 데 따른 문제를 줄일 수 있으며 모든 제곱이 0이 될 때까지 반복 할 수 있습니다.

그러나 최적의 방식보다 주변을 폭격하는 것이 가능하다면 항상 최적의 솔루션을 찾지 못할 수도 있지만 X 여분의 폭탄을 사용하면> X 폭탄으로 내부 레이어를 단순화하는 문제가 발생합니다. 따라서 우리가 허가자 레이어 1이라고 부르면 레이어 2 어딘가에 (추가 레이어 1) 추가 X 폭탄을 배치하면 나중에 레이어 2를 X보다 더 폭격시키는 노력을 줄일 수 있습니까? 다시 말해, 우리는 바깥 둘레를 줄이는 데 욕심이있을 수 있음을 증명해야합니다.

그러나 우리는 우리가 탐욕 스러울 수 있다는 것을 알고 있습니다. 레이어 2의 폭탄은 레이어 3에 전략적으로 배치 된 폭탄보다 레이어 2를 0으로 줄이는 데 더 효율적일 수 없기 때문에 이전과 같은 이유로 항상 레이어 3에 배치 할 수있는 폭탄이 모든 사각형에 영향을 줄 수 있습니다 레이어 2에 배치 된 폭탄이 할 수있는 레이어 2의 그러므로 욕심을 느끼는 것은 결코 우리에게 해를 끼칠 수 없습니다 (이 욕심의 의미에서).

따라서 우리가해야 할 일은 다음 내층을 폭격함으로써 허가자를 0으로 줄이는 최적의 방법을 찾는 것입니다.

내부 레이어의 모서리 만 도달 할 수 있기 때문에 모서리를 0으로 먼저 폭파해도 결코 아프지 않습니다. 따라서 실제로는 선택의 여지가 없습니다 (모퉁이에 도달 할 수있는 주변의 모든 폭탄에는 내부 레이어의 모서리에서 폭발 반경).

일단 그렇게하면, 0 코너에 인접한 주변의 사각형은 내부 레이어에서 2 사각형까지만 도달 할 수 있습니다.

0       A       B

C       X       Y

D       Z

이 시점에서 주변은 효과적으로 닫힌 1 차원 루프입니다. 폭탄이 있으면 3 개의 인접한 사각형이 줄어들 기 때문입니다. 모퉁이 근처의 이상한 점을 제외하고 X는 A, B, C 및 D를 “치게”할 수 있습니다.

이제 우리는 블라스트 반경 트릭을 사용할 수 없습니다. 각각의 상황은 이상한 코너를 제외하고 대칭이며 블라스트 반경은 다른 부분의 하위 집합이 아닙니다. 폐 루프 대신에 (패닉 대령이 논의한 바와 같이) 이것이 선이라면 해결책은 사소한 것입니다. 끝점은 0으로 줄여야하며, 폭발 반경이 수퍼 셋이기 때문에 끝점에 인접한 점을 폭격하는 데 아무런 해가 없습니다. 엔드 포인트를 0으로 설정 한 후에도 여전히 새 엔드 포인트가 있으므로 반복하십시오 (라인이 모두 0이 될 때까지).

따라서 레이어의 단일 정사각형을 0으로 최적으로 줄일 수 있다면 알고리즘이 있습니다 (루프를 자르고 끝점과 직선을 가지기 때문에). 나는 가장 낮은 값을 가진 정사각형에 인접한 폭격 (2 옵션을 제공)이 가장 낮은 값의 2 제곱 내에서 가장 높은 값이 가능한 최소값이라고 생각합니다 (이를 관리하기 위해 폭탄을 분할해야 할 수도 있음) 아직 증거가 없습니다.


답변

Pólya는 “문제를 해결할 수 없으면 해결할 수있는 더 쉬운 문제가 있습니다. 문제를 찾으십시오”라고 말합니다.

가장 간단한 문제는 1 차원 문제입니다 (그리드가 단일 행인 경우). 가장 간단한 알고리즘부터 시작하겠습니다. 가장 큰 목표를 탐욕스럽게 폭파하십시오. 언제 잘못 되나요?

을 감안할 때 1 1 1, 욕심 알고리즘은 먼저 어느 셀이 폭탄에 무관심하다. 물론 가운데 셀이 더 좋습니다. 세 셀을 모두 한 번에 0으로 만듭니다. 이것은 새로운 알고리즘 A, “남은 합계를 최소화하기위한 폭탄”을 제안합니다. 이 알고리즘은 언제 잘못됩니까?

을 감안할 때 1 1 2 1 1, 알고리즘 A는 2, 3 또는 4 세포를 폭격 무차별입니다. 하지만 두 번째 칸을 떠나는 0 0 1 1 1것은 세 번째 칸을 떠나는 것보다 낫습니다.1 0 1 0 1 . 그것을 고치는 방법? 세 번째 셀을 폭격하는 문제는 우리가 왼쪽으로 일하고 오른쪽으로 일해야한다는 것입니다.

“남은 총계를 최소화하기 위해 폭탄을 쓰지만 폭탄의 왼쪽에 최소를 더하고 오른쪽에 최소를 최대화하는 것은 어떻습니까?” 이 알고리즘 B를 호출하십시오.이 알고리즘은 언제 잘못됩니까?


편집 : 의견을 읽은 후, 훨씬 흥미로운 문제는 1 차원 문제가 변경되어 끝이 합쳐질 것이라는 데 동의합니다. 그 진행 상황을보고 싶습니다.


답변

시간이 없어서 부분 솔루션 만 중단해야했지만이 부분 솔루션 조차도이 문제를 해결하기위한 하나의 잠재적 접근법에 대한 통찰력을 제공하기를 바랍니다.

어려운 문제에 직면했을 때 나는 문제 공간에 대한 직관을 개발하기 위해 더 간단한 문제를 생각해 내고 싶습니다. 여기서 제가 취한 첫 번째 단계는이 2 차원 문제를 1 차원 문제로 줄이는 것입니다. 라인을 고려하십시오 :

0 4 2 1 3 0 1

어떻게 든 또는 다른, 당신은 당신이 또는 그 주위에 폭탄을 투하해야합니다 알고 4폭격에 아무런 혜택이없는, 낮은 숫자가 그 자리의 왼쪽부터 0으로 내려 4 번 자리 0또는를 4을 폭격 이상은 2. 사실, 나는 24지점이 0으로 떨어질 때까지 폭탄을 터뜨리는 것이 적어도 다른 전략보다 좋은 것이라고 믿습니다 (그러나 엄격한 증거는 부족합니다)4 전략 왼쪽에서 오른쪽으로 선을 진행할 수 0 원에 다운 이처럼 :

index = 1
while index < line_length
  while number_at_index(index - 1) > 0
    bomb(index)
  end
  index++
end
# take care of the end of the line
while number_at_index(index - 1) > 0
  bomb(index - 1)
end

몇 가지 샘플 폭탄 주문 :

0 4[2]1 3 0 1
0 3[1]0 3 0 1
0 2[0]0 3 0 1
0 1[0]0 3 0 1
0 0 0 0 3[0]1
0 0 0 0 2[0]0
0 0 0 0 1[0]0
0 0 0 0 0 0 0

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

어떤 식 으로든 내려 가야하는 숫자로 시작한다는 아이디어는 매력적인 주장입니다. 어떤 사람들은 주장하는 해결책을 찾는 것이 갑자기 가능해지기 때문입니다. 다른 솔루션보다 적어도 좋은 입니다.

다음 단계의 복잡성으로이 검색은 최소한 것이 여전히 가능한 는 보드의 가장자리에 있습니다. 바깥 쪽 가장자리를 폭격 할 때 어떤 엄밀한 이점도 없다는 것이 분명합니다. 그 자리를 폭격하고 다른 3 곳을 무료로 얻는 것이 좋습니다. 이것을 감안할 때, 우리는 가장자리 안쪽에서 링 을 폭파시키는 것이 가장자리를 폭파시키는 것 이상 이라고 말할 수 있습니다 . 또한, 우리는 이것을 가장자리의 오른쪽에있는 폭탄을 폭파하는 것이 실제로 가장자리 공간을 0으로 낮추는 유일한 방법이라는 직관과 결합 할 수 있습니다. 모퉁이 숫자를 0으로 낮추는 것입니다. 우리는 이것을 모두 모아서 2 차원 공간의 솔루션에 훨씬 더 가까워 질 수 있습니다.

코너 조각에 대한 관찰을 감안할 때 모든 시작 보드에서 모든 코너에 0이있는 보드로가는 최적의 전략을 알고 있다고 말할 수 있습니다. 이것은 그러한 보드의 예입니다 (위의 두 선형 보드에서 숫자를 빌 렸습니다). 공백을 다르게 표시했는데 그 이유를 설명하겠습니다.

0 4 2 1 3 0 1 0
4 x x x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

하나는 상단 행에서 알 정말 밀접하게 우리가 이전에 보았던 선형 예제와 유사한. 앞줄을 모두 0으로 낮추는 가장 좋은 방법은 두 번째 줄 ( x줄) 을 폭파하는 것 입니다. 행을 폭격하여 맨 위 행을 지우는 방법은 없으며 y행의 해당 공간을 폭격하는 것보다 맨 위 행을 폭격하는 추가 이점이 없습니다 x.

우리는 (상의 해당 공간 폭격 위에서 선형 전략을 적용 x자신 직결 된 행) 상단의 행과 다른 아무것도. 다음과 같이 갈 것입니다.

0 4 2 1 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 3 1 0 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 2 0 0 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 1 0 0 3 0 1 0
4 x[x]x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

0 0 0 0 3 0 1 0
4 x x x x x x 4
2 y y y y y y 2
1 y y y y y y 1
3 y y y y y y 3
2 y y y y y y 2
1 y y y y y y 1
5 y y y y y y 5
0 4 2 1 3 0 1 0

이 접근 방식의 결함은 마지막 두 번의 폭탄 테러에서 매우 분명해집니다. 4두 번째 행의 첫 번째 열에 있는 숫자 를 줄이는 유일한 폭탄 사이트 는 첫 번째 xy. 마지막 두 번의 폭탄 공격은 첫 번째 폭탄을 공격 x하는 것 보다 분명히 열등합니다 . 현재 전략이 차선 책임을 입증 했으므로 전략을 수정해야합니다.

이 시점에서 복잡성을 한 단계 물러나 한 구석에 집중할 수 있습니다. 이것을 고려해 봅시다 :

0 4 2 1
4 x y a
2 z . .
1 b . .

그것은과 공간을 얻을 수있는 유일한 방법 분명하다 4의 조합을 폭격 할 수있는 제로에 이르기를 x, y하고 z. 내 곡예를 생각하면 최적의 솔루션이 x세 번 폭격 을 한 a다음 확실하게 확신합니다 b. 이제 솔루션에 어떻게 도달했는지 파악해야합니다. 직관이 드러나면이 로컬 문제를 해결하는 데 사용할 수도 있습니다. 나는 폭격 yz공간이 없다는 것을 알았습니다 . 해당 공간을 폭격하는 것이 적합한 코너를 찾으려면 다음과 같은 코너가 생성됩니다.

0 4 2 5 0
4 x y a .
2 z . . .
5 b . . .
0 . . . .

이를 위해 최적의 해결책은 y5 번 5 번 폭격하는 것이 분명합니다 z. 한 걸음 더 나아 갑시다.

0 4 2 5 6 0 0
4 x y a . . .
2 z . . . . .
5 b . . . . .
6 . . . . . .
0 . . . . . .
0 . . . . . .

여기서 최적의 솔루션은 폭탄 ab6 번, 그 다음 x4 번으로 하는 것이 직관적으로 느껴집니다 .

이제이 직관을 우리가 만들 수있는 원칙으로 바꾸는 방법에 대한 게임이되었습니다.

계속되기를 바랍니다!


답변

업데이트 된 질문의 경우 간단한 탐욕스러운 알고리즘이 최적의 결과를 제공합니다.

A [0,0] 폭탄을 셀 A [1,1]에 떨어 뜨린 다음 A [1,0] 폭탄을 셀 A [2,1]에 떨어 뜨린 다음이 과정을 아래쪽으로 계속 진행하십시오. 왼쪽 하단 모서리를 청소하려면 max (A [N-1,0], A [N-2,0], A [N-3,0]) 폭탄을 셀 A [N-2,1]에 떨어 뜨립니다. 처음 3 개의 열이 완전히 정리됩니다.

동일한 접근 방식으로 열 3,4,5를 청소 한 다음 열 6,7,8 등을 정리하십시오.

불행히도 이것은 원래 문제에 대한 해결책을 찾는 데 도움이되지 않습니다.


“큰 감소”제약이없는 “큰”문제는 NP-hard 인 것으로 입증 될 수 있습니다. 여기 증거의 스케치가 있습니다.

최대 3 도의 평면 그래프가 있다고 가정 해 봅시다 .이 그래프의 최소 정점 커버 를 찾아 봅시다 . Wikipedia 기사에 따르면이 문제는 최대 3 도의 평면 그래프에서 NP-hard입니다. 이는 Planar 3SAT의 감소로 증명 될 수 있습니다. 그리고 3SAT에서 감소하여 Planar 3SAT의 경도. 이 두 증거는 “알고리즘 하위 경계”의 최근 강의에서 발표됩니다. 교수님이 . Erik Demaine (강의 7과 9).

원래 그래프의 일부 가장자리 (다이어그램의 왼쪽 그래프)와 짝수의 추가 노드가있는 경우 결과 그래프 (다이어그램의 오른쪽 그래프)는 원래 꼭짓점에 대해 정확히 동일한 최소 정점 커버를 가져야합니다. 이러한 변환을 통해 그래프 정점을 그리드의 임의 위치에 맞출 수 있습니다.

여기에 이미지 설명을 입력하십시오

그래프 정점을 한 행과 열에 만 고르게 배치하는 경우 (한 정점에 입사하는 두 모서리가 예각을 형성하지 않는 방식으로) 모서리가있는 곳에 “1”을 삽입하고 다른 그리드 위치에 “0”을 삽입합니다. 최소 정점 표지를 찾기 위해 원래 문제에 대한 솔루션을 사용할 수 있습니다.


답변

이 문제를 정수 프로그래밍 문제 로 나타낼 수 있습니다 . (이것은이 문제에 접근 할 수있는 해결책 중 하나 일뿐입니다)

포인트 :

a b c d
e f g h
i j k l
m n o p

예를 들어 점 f에 대해 보유한 16 개의 방정식을 쓸 수 있습니다.

f <= ai + bi + ci + ei + fi + gi + ii + ji + ki

모든 인덱스와 정수 솔루션의 합계보다 최소화되었습니다.

솔루션은 물론이 인덱스의 합계입니다.

경계 0에서 모든 xi를 설정하면 더욱 단순화 할 수 있으므로이 예제에서는 4 + 1 방정식을 갖게됩니다.

문제는 그러한 문제를 해결하기위한 사소한 알고리즘이 없다는 것입니다. 나는 이것에 대해 전문가가 아니지만 선형 프로그래밍이 NP 어렵 기 때문에이 문제를 해결합니다.


답변

이것은 부분적인 대답이며 가능한 폭탄 수일 수있는 하한 및 상한을 찾으려고합니다.

3×3 이하 보드에서는 솔루션이 항상 가장 큰 숫자 셀입니다.

4×4보다 큰 보드에서 첫 번째 명백한 하한은 모서리의 합입니다.

*2* 3  7 *1*
 1  5  6  2
 2  1  3  2
*6* 9  6 *4*

그러나 폭탄을 배치하면 2 + 1 + 6 + 4 = 13 미만의 폭탄 으로이 4×4 보드를 지울 수 없습니다.

다른 답변에서 코너를 제거하기 위해 두 번째 코너에 폭탄을 배치하는 것이 코너 자체에 폭탄을 배치하는 것보다 결코 나쁘지 않다는 것이 언급되었습니다.

*2* 3  4  7 *1*
 1  5  2  6  2
 4  3  4  2  1
 2  1  2  4  1
 3  1  3  4  1
 2  1  4  3  2
*6* 9  1  6 *4*

우리는 새로운 보드를 제공하기 위해 두 번째 코너에 폭탄을 배치하여 코너를 제로로 만들 수 있습니다.

 0  1  1  6  0
 0  3  0  5  1
 2  1  1  1  0
 2  1  2  4  1
 0  0  0  0  0
 0  0  0  0  0
 0  3  0  2  0

여태까지는 그런대로 잘됐다. 모서리를 비우려면 13 개의 폭탄이 필요합니다.

이제 아래 표시된 6, 4, 3 및 2를 관찰하십시오.

 0  1  1 *6* 0
 0  3  0  5  1
 2  1  1  1  0
*2* 1  2 *4* 1
 0  0  0  0  0
 0  0  0  0  0
 0 *3* 0  2  0

을 폭파 방법이 없습니다하나의 폭탄을 사용하여 세포 최소 폭탄이 6 + 4 + 3 + 2 증가하여 모서리를 지우는 데 사용 된 폭탄 수를 추가하면 최소값을 얻습니다. 이지도에 필요한 폭탄 수는 28 개가되었습니다. 폭탄이 28 개 미만인 경우이지도를 지울 수 없습니다.이지도의 하한입니다.

탐욕스러운 알고리즘을 사용하여 상한을 설정할 수 있습니다. 다른 답변에 따르면 탐욕스러운 알고리즘은 28 개의 폭탄을 사용하는 솔루션을 생성합니다. 앞서 우리는 최적의 솔루션이 28 개 미만의 폭탄을 가질 수 없다는 것을 증명 했으므로 28 개의 폭탄이 실제로 최적의 솔루션입니다.

욕심과 위에서 언급 한 최소 한계를 찾는 방법이 수렴되지 않으면 모든 조합을 확인하는 것으로 되돌아 가야한다고 생각합니다.

하한값을 찾는 알고리즘은 다음과 같습니다.

  1. 숫자가 가장 높은 요소를 선택하고 이름을 P로 지정하십시오.
  2. P와 P 자체에서 2 단계 떨어진 모든 셀을 선택 불가능한 것으로 표시하십시오.
  3. P를 minimums목록에 추가 하십시오.
  4. 모든 셀을 선택할 수 없을 때까지 1 단계로 반복하십시오.
  5. minimums하한을 얻으려면 목록을 합산하십시오 .

답변

이것은 욕심 많은 접근 방식입니다.

  1. 차수 n X m의 “점수”행렬을 계산합니다. 여기서 점수 [i] [j]는 위치 (i, j)에 폭격이있는 경우 행렬의 총점 공제입니다. (점의 최대 점수는 9이고 최소 점수는 0입니다)

  2. 행을 현명하게 움직여서 가장 높은 점수를 가진 첫 번째 위치를 찾아서 선택하십시오 (예 : (i, j)).

  3. 폭탄 (i, j). 폭탄 수를 늘리십시오.

  4. 원래 행렬의 모든 요소가 0이 아닌 경우 1로 이동하십시오.

그래도 이것이 최적의 해결책이라는 의심이 있습니다.

편집하다:

위에서 언급 한 Greedy 접근 방식은 효과가 있지만 최적의 솔루션을 제공하지는 못합니다. 그래서 DP의 일부 요소를 추가해야한다고 생각했습니다.

어느 시점에서든 가장 높은 “점수”(점수 [i] [j] = (i, j)가 폭격 된 경우 총 점수 공제)가있는 위치 중 하나를 타겟팅해야한다는 점에 동의 할 수 있습니다. 이 가정에서 시작하여 새로운 접근 방식은 다음과 같습니다.

NumOfBombs (M) : (필요한 최소 폭격 수를 반환)

  1. 차수 n X m의 행렬 M이 주어집니다. M의 모든 요소가 0이면 0을 반환합니다.

  2. “점수”행렬 M을 계산하십시오.

    k 개의 개별 위치 P1, P2, … Pk (1 <= k <= n * m)를 M에서 가장 높은 점수를 가진 위치로 둡니다.

  3. 리턴 (1 + min (NumOfBombs (M1), NumOfBombs (M2), …, NumOfBombs (Mk)))

    여기서 M1, M2, …, Mk는 위치 P1, P2, …, Pk를 각각 폭격하면 결과 행렬입니다.

또한이 외에도 핵의 위치 순서를 원한다면 “min”의 결과를 추적해야합니다.