여러 사각형을 더 적은 수의 사각형으로 "치유"하는 알고리즘?


14

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

모양과 색상이 다른 사각형의 격자가 있고 동일한 레이아웃의 색상을 나타내는 사각형의 수를 줄이고 싶습니다 (합리적으로 최적에 가깝고 최적은 필요하지 않습니다).

위의 이미지는 매우 단순화 된 경우이며 사각형 사이의 공백은 시각화를위한 것입니다. 실제로 실제로 압축되어 있습니다.

이 작업을 수행하는 데 도움이되는 접근 방식 또는 알고리즘 이름 (Google에 만족)은 무엇입니까?


3
이 직사각형의 출처에 대해 조금 말씀해 주시겠습니까? 기본 그리드와 (거의) 정렬하거나 일반적인 빌딩 블록 또는 가장 작은 "원자"사각형을 공유하는 경향이 있습니까? 회전 할 수 있습니까? 이것은 가장 일반적인 경우에 매우 까다로울 수있는 일종의 문제처럼 보이지만 특정 시나리오에서 일부 제약이나 공통점을 이용할 수 있으면 훨씬 쉬워 질 수 있습니다.
DMGregory

바둑판과 같은 기본 사각형 격자가 있으며 각 사각형은 기본 사각형과 경계를 공유합니다. 즉, 정수를 사용하여 모든 사각형의 위 / 아래 / 왼쪽 / 오른쪽을 설명 할 수 있습니다. 따라서 90 도로 나눌 수없는 각도로 회전 할 수 없습니다. 또한 NxM 그리드는 사각형으로 완전히 채워져 있습니다. 그리드 위치는 없습니다.
xaxxon

위의 예와 같이 (색상 관점에서) 사례를 피하려고하지만 1x1 사각형의 톤으로 구성되어 있으며 많은 공간을 처리 할 수있을 때 각각을 처리하고 있습니다. 더 적은 통화.
xaxxon

"어딘가에서 시작하여 한 번에 한 차원에서 더 큰 사각형을 계속 시도해보십시오 (예 : 세로). 경계선에 닿을 때까지 다른 차원 (수평)을 늘리십시오. 그런 다음 가로로 먼저 시도하십시오. 그런 다음 정사각형 만 시도해보십시오 (대각선으로 커짐). 위의 세 가지 가능성 중 가장 큰 것을 선택하는 것이 올바른 방법인지 확실하지 않습니다.
xaxxon

끝에 직사각형 수가 더 적 으면 기존 직사각형을 분할해도 되나요? 아니면 알고리즘 만 병합해야합니까? 또한 총계가 유일한 기준입니까, 아니면 긴 스키니 슬라이 버보다 큰 사각형을 선호합니까, 작은 직사각형보다 큰 사각형을 선호합니까?
DMGregory

답변:


15

먼저 소스 사각형을 기본 그리드의 셀로 변환하여 입력을보다 균일하게 만들 수 있습니다. (효과적으로 문제를 래스터 화)

이를 통해 소스 사각형으로 직접 작업 할 때 명확하지 않을 수있는 최적화를 찾을 수 있습니다. 특히 여러 소스 사각형을 분할하여 서로 다르게 조합하는 경우 특히 그렇습니다.

사각형을 격자 셀로 변환하고 다시 변환하는 예

다음으로 깊이 우선 검색 또는 플러드 필링 알고리즘을 사용하여 동일한 색상의 연결된 영역을 찾을 수 있습니다. 연결된 각 영역 ( polyomino )을 개별적으로 고려할 수 있습니다 . 다른 영역에 대한 작업은이 영역에 영향을 줄 필요가 없습니다.

효과적으로 우리는이 polyomino를 사각형으로 해체하는 방법을 찾고 싶습니다 (불행히도 내가 찾을 수있는 대부분의 문헌은 반대 문제입니다.

하나의 간단한 방법은 인접한 사각형의 가로 런을 길고 마른 사각형으로 결합하는 것입니다. 그런 다음 위의 행과 비교하여 각 런 / 로우를 완료하거나 각 셀을 현재 런에 추가 할 때 런 시작과 끝이 일치하면 결합 할 수 있습니다.

폴리오 미노를 수평 런으로 분해 한 다음 수직으로 병합

나는이 방법이 얼마나 최적에 가까운 지 아직 모른다. 아직 고려하지 않은 행이 지금까지 본 행과 다른 분할을 제안하면 약간의 문제가 발생할 수 있습니다.

위의 방법으로 4를 구한 3 각형 솔루션의 사례 예

런 / 직사각형이 위와 아래의 런으로 정확하게 덮여 있는지 감지 한 다음,이를 분할하고 병합하면이 특정한 경우가 해결되지만 문제가 얼마나 일반적인지 살펴 보지 않았습니다.

또한 우리가 polyomino의 둘레를 걷는 방법을 살펴 보았고 오목한 구석이 생길 때마다 잘라 냈지만이 접근법은 더 오류가 발생하기 쉽습니다. 최적의 결과를 얻으려면 두 개의 오목한 모서리를 연결하는 우선 순위 컷을 필요로하는 것처럼 보이며, 중공이 포함 된 모양에는 특별한 처리가 필요하므로 행 스캔 방법에는 단순 이점이있는 것 같습니다.

내가보고있는 또 다른 방법은 맨 윗줄에서 찾은 첫 번째 실행을 수행하고 가능한 한 확장하는 것입니다. 그런 다음 남은 것의 맨 윗줄에서 첫 번째 실행을 수행하십시오. 이것은 반전 된 T 모양에서 넘어 지므로 최적도 아닙니다.

동적 프로그래밍을 사용하여 최적의 분할을 찾는 방법이 있다고 생각하지만 아직 찾지 못했습니다.


멋진 답변 감사합니다! 이 솔루션은 몇 가지 다른 방향으로 실행할 수있을만큼 충분히 빠르며 가로-> 오른쪽, 가로-오른쪽-> 왼쪽, 그리고 세로 방향으로 가장 적합한 것을 선택하십시오.
xaxxon

2
문제는 모든 스위프 방향에서 알고리즘을 잘못 인도 할 모양을 만들 수 있다는 것입니다. 그것들은 실제 사용에 나타나지 않을 수도 있지만 여전히 버그가 있습니다. 아직 간단한 수정이 있다고 생각합니다 ... 실행 중에 오목한 모서리가 있는지 여부에 관계없이 각 실행에 주목하는 것과 같습니다. 그런 다음 후속 런이 정확히 그런 지점에서 끝나면 위의 런을 수직으로 분할하여 뒤로 추적합니다. 그래도 자세한 내용을 정리하지 않았습니다.
DMGregory

1
또한 왜 홍수 채우기 단계가 필요한지 잘 모르겠습니다. 그리드 포지 티노에서 길고 마른 직사각형으로 갈 때 그리드의 전체 행 또는 열을 걸어서 1xN 직사각형을 만들 수 있습니다. polyomino를 알 필요가 없습니다. 맞습니까?
xaxxon

당신의 말이 맞습니다. 홍수 채우기는 필요한 단계가 아닙니다. 후속 단계에서 한 번에 하나의 색상 영역에만 초점을 맞추는 것을 정당화하기 위해 포함했지만 여러 행의 색상 영역에 행 스캔 방법을 쉽게 적용 할 수 있습니다. 경계 기반 방법은 한 번에 한 모양의 경계에서 작동해야합니다.
DMGregory
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.