2012-02-15 11 views
5

Poszukuję sposobu sprawdzenia kolekcji prostokątów (Java TreeSet) - implementowanej przez "porównywalną" klasę Java przy użyciu google guavas Range dla zakresu x i y - dla skrzyżowań i otworów. Wiem, że opcją może być używanie drzewek kd, ale nie mam pojęcia jak zbudować takie drzewo-kd (dla prostokątów powinno to być 4d, czyż nie?) I jak rozwiązać problem (skrzyżowanie , dziury).jak sprawdzić kolekcję prostokątów na dziury i przejścia?

sortowanie priorytetuje oś x na osi Y.

EDIT: (starają się przekształcić problem): przypadek użycie jest tworzenie dowolnych tabel (składające się z 2 lub 3 bloki prostokąty „cel”, „pre kolumnę”, „dane”). muszę zagwarantować, że w każdym bloku nie ma przecięć ani dziur (tj. dostarczonych przez nieprawidłowy html lub inne źródła danych tabel) (poza tym bloki muszą pasować do siebie). Obecnie (właśnie wpadłem na pomysł) staram się zapisać w tablicy 2d, które pozycje (x, y) są zajęte. na końcu wszystkie pozycje muszą być zajęte dokładnie raz.

+0

Czy to praca domowa? –

+0

Zalecam, aby rozwiązać problem, będąc tak szczegółowe, jak to tylko możliwe. Jeśli nie możesz podać problemu, rozwiązanie jest bardzo trudne do zauważenia. –

+0

są krawędziami prostokątów równoległych do osi X/Y lub czy mogą być w dowolnej orientacji? – PeskyGnat

Odpowiedz

6

Istnieje wiele metod rozwiązywania tego typu problemów, z których każdy ma inne zalety i wady. Oto niektóre z nich:

Prostokąt Pair Przecięcie + Area Suma

Spójrz na każdej pary prostokątów - jeśli dwa prostokąty przecinają, występuje nakładanie. Dodaj obszary prostokąta i sprawdź, czy suma pasuje do obszaru roboczego - jeśli obszary się nie zgadzają, istnieje luka.

Malowanie

To podejście wspomniałeś: tworzenie 2D tablicę, która ma wymiary płótna. Następnie należy powtórzyć prostokąty i "pomalować" je w tablicy.

Jedną z optymalizacji tego podejścia jest kompresja współrzędnych. Załóżmy, że masz prostokąty [(10,20), (15,25)] i [(7,3), (15, 25)]. Możesz przyjrzeć się różnym współrzędnym x (7, 10, 15) i przyporządkować je do (0, 1, 2) i odrębnych współrzędnych y (3, 20, 25) i przyporządkować je do (0, 1, 2). Następnie pozostawiasz prostokąty [(1, 1), (2, 2)] i [(0,0), (2,2)], więc do malowania potrzebujesz tylko tablicy 3x3, zamiast 26x26 szyk.

Sweep Linia Algorytm

Sweep linii od lewej do prawej, zatrzymując się w miejscach „ciekawych” oraz śledzenie, które obszary są zajęte.

2D Zakres Drzewa

Struktura danych, które mogą skutecznie wykonywać zapytania nad zakresami prostokąta.

Który wybrać?

To zależy od liczby posiadanych prostokątów, ich rozmieszczenia w regionie, szybkości działania algorytmu, stopnia złożoności, z jaką chcesz się zmierzyć itd. Pierwsze dwa algorytmy, o których wspomniałem, to: znacznie prostsze niż te dwa ostatnie, więc polecam zacząć tam.

Więcej informacji

Jeśli chcesz dowiedzieć się więcej na temat tych algorytmów, spróbuj wyszukać „unii prostokąt” online. Najbardziej wydajnym rozwiązaniem jest algorytm linii przeciągnięcia.

Oto kilka odniesień na algorytmie linii przemiatania:

  1. What is an Efficient algorithm to find Area of Overlapping Rectangles
  2. http://compgeom.cs.uiuc.edu/~jeffe/open/klee.html
  3. J. L. Bentley, Algorytmy dla problemów prostokąt Klee. niepublikowane notatki, Computer Science Department, Carnegie Mellon University, 1977

referencyjny 3. jest zwykle podawana jako oryginalnego źródła algorytmu linii omiatania dla unii prostokąt, ale muszę przyznać, że faktycznie nie znaleźć papier online, być może dlatego, że jest "Niepublikowane" ...

+0

Czy mógłbyś podać odniesienie do książki lub inetlink, która opisuje tego rodzaju problem i jego rozwiązania - sprawiłeś, że jestem ciekawy. W moim specjalnym przypadku nie mam do czynienia z wieloma prostokątami (około 100), ale nie mogę się oprzeć, aby wypróbować lepszy/najlepszy algorytm, o ile wiem, że są lepsze algorytmy – dermoritz

+1

Dodałem "Więcej informacji" Sekcja do mojej odpowiedzi - mam nadzieję, że to pomaga. Baw się dobrze, poznawszy algorytmy. :) –

+1

@Igor jest tuż. Bentley napisał wiele klasycznych i przełomowych artykułów w tej dziedzinie. Jego prace były dla mnie nieocenione. Nie ograniczaj do minimum faktu, że twoja uwaga dotyczy ortogonalnych granic. To wielka sprawa, ponieważ w tej dziedzinie wykonano wiele pracy. Podejście linii przeciągnięcia jest dość łatwe do zrealizowania dla tego problemu, wystarczy wybrać oś i wyświetlić ortogonalny brzeg do tej osi, a linia zdarzenia na tej osi oznaczałaby początek lub koniec prostokąta. Zobacz rozdział 8 Geometrii obliczeniowej: Wprowadzenie autorstwa: Preparata i Shamos. – babernathy

Powiązane problemy