Myśląc o jednym problemie, zdałem sobie sprawę, że muszę stworzyć wydajny algorytm rozwiązujący następujące zadanie:
Problem: otrzymujemy dwuwymiarowe kwadratowe pudełko o boku którego boki są równoległe do osi. Możemy spojrzeć na to z góry. Istnieją jednak również segmenty poziome. Każdy segment ma całkowitą współrzędną ( ) i współrzędne ( ) i łączy punkty i (spójrz na zdjęcie poniżej).
Chcielibyśmy wiedzieć, dla każdego segmentu jednostki na górze pudełka, jak głęboko możemy spojrzeć w środku w pionie, jeśli przejrzymy ten segment.
Przykład: biorąc pod uwagę i segmentów zlokalizowanych jak na poniższym obrazku, wynikiem jest . Zobacz, jak głębokie światło może dostać się do pudełka.m = 7 ( 5 , 5 , 5 , 3 , 8 , 3 , 7 , 8 , 7 )
Na szczęście dla nas zarówno , jak i m są dość małe i możemy wykonywać obliczenia offline.m
Najłatwiejszym algorytmem rozwiązującym ten problem jest brute-force: dla każdego segmentu przejdź przez całą tablicę i zaktualizuj ją w razie potrzeby. Daje nam jednak niezbyt imponujące .
Dużym ulepszeniem jest użycie drzewa segmentów, które jest w stanie zmaksymalizować wartości segmentu podczas zapytania i odczytać wartości końcowe. Nie będę tego dalej opisywał, ale widzimy, że złożoność czasu wynosi .
Wymyśliłem jednak szybszy algorytm:
Zarys:
Posortuj segmenty w malejącej kolejności współrzędnej (czas liniowy przy użyciu odmiany sortowania zliczającego). Teraz pamiętać, że jeśli szerokości jednostek, niskoprofilowy segment został objęty żadnym segmencie przed, nie po segment może związany wiązki światła przechodzącego przez ten szerokości jednostek, niskoprofilowy segmencie już. Następnie zrobimy przeciągnięcie linii od góry do dołu pudełka.x x
Teraz wprowadzimy kilka definicji: -jednostka segmentowa jest urojonym poziomym segmentem na przemiataniu, którego współrzędnymi są liczby całkowite i których długość wynosi 1. Każdy segment podczas procesu zamiatania może być albo nieoznaczony (to znaczy wiązka światła wychodząca z góra pudełka może dosięgnąć tego segmentu) lub oznaczona (odwrotna wielkość liter). Rozważ segment unit z , zawsze niezaznaczone. również zestawy . Każdy zestaw będzie zawierał całą sekwencję następujących po sobie segmentów jednostek (jeśli istnieją) z następującymi nieoznaczonymix x x 1 = n x 2 = n + 1 S 0 = { 0 } , S 1 = { 1 } , … , S n = { n } x człon.
Potrzebujemy struktury danych, która byłaby w stanie działać skutecznie na tych segmentach i zestawach. Użyjemy struktury find-union rozszerzonej o pole zawierające maksymalny indeks segmentu -jednostek (indeks segmentu nieoznaczonego ).
Teraz możemy efektywnie obsługiwać segmenty. Powiedzmy, że rozważamy teraz ty segment w kolejności (nazwij go „zapytaniem”), który zaczyna się od a kończy na . Musimy znaleźć wszystkie nieoznakowane segmenty unit, które są zawarte w segmencie (są to dokładnie te segmenty, na których wiązka światła kończy swoją drogę). Wykonamy następujące czynności: po pierwsze, znajdziemy pierwszy nieoznaczony segment w zapytaniu ( Znajdź reprezentanta zestawu, w którym znajduje się i uzyskaj maksymalny indeks tego zestawu, który z definicji jest segmentem nieoznaczonym ). Następnie ten indeksx 1 x 2 x i x 1 x y x x + 1 x ≥ x 2 znajduje się w zapytaniu, dodaj go do wyniku (wynikiem dla tego segmentu jest ) i zaznacz ten indeks ( zestawy Unii zawierające i ). Następnie powtarzaj tę procedurę, aż znajdziemy wszystkie nieoznakowane segmenty, czyli następne zapytanie Find daje nam indeks .
Zauważ, że każda operacja szukania unii zostanie wykonana tylko w dwóch przypadkach: albo zaczniemy rozważać segment (co może się zdarzyć razy), albo właśnie oznaczyliśmy segment jednostki (może się to zdarzyć razy). Zatem ogólna złożoność wynosi ( jest odwrotną funkcją Ackermanna ). Jeśli coś nie jest jasne, mogę rozwinąć więcej na ten temat. Może będę mógł dodać trochę zdjęć, jeśli będę miał trochę czasu.
Teraz dotarłem do „ściany”. Nie mogę wymyślić algorytmu liniowego, choć wydaje się, że powinien istnieć jeden. Mam więc dwa pytania:
- Czy istnieje algorytm czasu liniowego (to znaczy ) rozwiązujący problem widoczności segmentu poziomego?
- Jeśli nie, to jaki jest dowód na to, że problemem z widocznością jest ?