맵을 형성하는 알려진 유한 크기의 타일 그리드가 있습니다. 지도 안의 타일 중 일부는 지역으로 알려진 세트에 배치됩니다. 이 영토는 연결되어 있지만 그 모양에 대해서는 알려진 바가 없습니다. 대부분의 경우 상당히 규칙적인 얼룩이 될 수 있지만 한 방향으로 매우 길어질 수 있으며 구멍이 생길 수도 있습니다. 나는 영토의 (외부) 국경을 찾는 데 관심이 있습니다.
즉, 나는 영토에 있지 않고 영토의 타일 중 하나에 닿는 모든 타일 목록을 원합니다. 이것을 찾는 효율적인 방법은 무엇입니까?
여분의 어려움을 겪기 위해 내 타일이 헥스 인 경우가 발생하지만 큰 차이는 없지만 각 타일에는 여전히 정수 x 및 y 좌표로 레이블이 지정되어 있으며 타일이 있으면 이웃을 쉽게 찾을 수 있습니다. 아래는 몇 가지 예입니다. 검은 색은 영토이고 파란색은 찾고 싶은 경계입니다. 이것은 그 자체로는 어려운 문제가 아닙니다. 의사 파이썬에서이를위한 간단한 알고리즘은 다음과 같습니다.
def find_border_of_territory(territory):
border = []
for tile in territory:
for neighbor in tile.neighbors():
if neighbor not in territory and neighbor not in border:
border.add(neighbor)
그러나 이것은 느리고 더 나은 것을 원합니다. 나는 영토에 O (n) 루프가 있고 모든 이웃에 대한 다른 루프 (짧은 루프이지만 여전히)가 있고 두 개의 목록을 통해 멤버십을 확인해야합니다. 하나는 크기가 n입니다. 그것은 O (n ^ 2)의 끔찍한 스케일링을 제공합니다. 국경과 영토에 대한 목록 대신 세트를 사용하여 O (n)으로 줄일 수 있으므로 멤버쉽을 빠르게 확인할 수 있지만 여전히 좋지 않습니다. 영토는 크지 만 단순한 영역 대 라인 스케일링으로 인해 테두리가 작은 경우가 많이있을 것으로 예상합니다. 예를 들어 영토의 반지름이 5의 16 진수 인 경우 크기는 91이지만 테두리의 크기는 36입니다.
누구든지 더 나은 것을 제안 할 수 있습니까?
편집하다:
아래 질문에 답하십시오. 영토의 크기는 약 20에서 100 정도입니다. 영역을 구성하는 타일 세트는 객체의 속성이며 모든 경계 타일 세트가 필요한이 객체입니다.
처음에 영역은 블록으로 생성 된 다음 대부분 타일을 하나씩 얻습니다. 이 경우 가장 빠른 방법은 테두리 세트를 유지하고 얻은 타일에서만 업데이트하는 것입니다. 때때로 영토에 큰 변화가 일어날 수 있으므로 완전히 재 계산해야합니다.
나는 단순한 경계 찾기 알고리즘을 수행하는 것이 최선의 해결책이라고 생각합니다. 이것이 야기하는 추가적인 복잡성은 경계가 필요할 때마다 다시 계산되도록하는 것입니다. 현재 프레임 워크 에서이 작업을 안정적으로 수행 할 수 있다고 확신합니다.
타이밍에 관해서는, 현재 코드에는 영토의 모든 타일을 확인 해야하는 루틴이 있습니다. 모든 차례가 아니라 창조와 때로는 그 이후에 있습니다. 전체 테스트의 아주 작은 부분이지만 테스트 코드에 대한 실행 시간의 50 % 이상이 걸립니다. 그러므로 나는 반복을 최소화하기를 원했다. 그러나 테스트 코드는 프로그램을 정상적으로 실행하는 것보다 훨씬 더 많은 객체를 생성하므로 자연스럽게 관련이 없을 수도 있습니다.