Mam kilka obiektów o priorytecie, które są typu złożonego i są tylko częściowo uporządkowane . Muszę wybierać obiekty w kolejności tego priorytetu (tzn. Za każdym razem uzyskiwać minimalny przedmiot). Ale zamiast arbitralnie realizować zamówienie, wolałbym, aby kolejka była stabilna w takim sensie, że jeśli jest więcej niż jeden minimalny element, powinna zwracać najstarszą jako pierwszą.
Czy istnieje struktura danych sterty, która działałaby przy częściowym uporządkowaniu? Czy modyfikacja zwykłej kolejki priorytetowej do pracy z nią? Częstym wyborem algorytmu, którego potrzebuję, jest prosta sterta binarna lub 4-arytowa, ale to nie działa z częściowym uporządkowaniem.
Wartości priorytetów obsługują:
- Częściowe zamawianie za pomocą operacji . Jest to częściowe uporządkowanie, więc możliwe jest, że a \ preccurlyeq b jest fałszywe, a b \ preccurlyeq a również jest fałszywe. W takim przypadku piszę \ not \ lesseqgtr b .
- Znalezienie infima (glb) i suprema (lub). jest maksymalnym takim, że . Obliczenie minimum wartości zajmuje czas . Istnieje minimum (i supremum) każdego zestawu.
- Można zdefiniować rozszerzenie liniowe dla częściowego uporządkowania. Użycie go w kolejce priorytetowej jest łatwym rozwiązaniem, ponieważ algorytm działa w ten sposób. Ale kolejność wpływa na wydajność, a kolejność wstawiania wygląda najlepiej, aby unikać najgorszych przypadków.
Dodatkowo algorytm, w którym chcę tego używać, musi znać minimum wszystkich priorytetów w kolejce.
Priorytety mają pewne znaczenie w świecie rzeczywistym, ale mogą ulec zmianie, więc nie można polegać na innych właściwościach, które mogą mieć.
Uwaga: Kupy binarne nie działają przy częściowym uporządkowaniu. Załóżmy stertę binarną z , i , gdzie i i . Są one ustawione w tej kolejności, więc
a (0)
/ \
b (1) c (2)
teraz d jest wstawione. Następna wolna pozycja to 3, lewe dziecko , więc otrzymujemy
a (0)
/ \
b (1) c (2)
/
d (3)
Jeśli (co implikuje z przechodniości, ale nic nie mówi o i ) i , to nie zostanie zamienione na , ponieważ to nie jest mniej. Ale tak naprawdę jest mniej niż , ale nie jest z nim porównywany, więc teraz główny niezmiennik sterty nie ma miejsca; góra nie jest minimalna.d ≼ c d b d ⋚ ̸ b d b A
Podejrzewam, że las hałd w stylu dwumianowej hałdy mógłby zostać wykorzystany. Zasadniczo ważne jest, aby zawsze porównywać nowe wartości z rootem i łączyć tylko porównywalne elementy. Spowodowałoby to, że drzewa w lesie miałyby losowy rozmiar, a tym samym złożoność zależałaby od liczby wzajemnie nieporównywalnych zbiorów w hałdzie. Podejrzewam, że złożoności nie da się naprawić (musimy porównywać, aż trafimy na porównywalny element) Mogłem coś przeoczyć, więc zostawiam to otwarte.
Uwaga: Kolejność jest częściowa i chociaż istnieją sposoby na zdefiniowanie rozszerzeń liniowych, dodanie znacznika czasu i użycie go jako kryterium wtórnego nie jest jednym z nich. Załóżmy, że przypisaliśmy znacznik czasu dla każdego i zdefiniowaliśmy kolejność jako i lub ( i . następnie załóżmy, że posiada odrębną , , tak, że i , a następnie i , ale , więc relacja nie jest przechodnia i dlatego w ogóle nie jest porządkiem. Ten rodzaj rozszerzenia działa tylko w przypadku słabych zamówień, ale nie częściowych.
Edycja: Zdałem sobie sprawę, że nie tylko jest najmniej zdefiniowany zestaw, ale tak naprawdę muszę być w stanie efektywnie uzyskać minimum elementów znajdujących się w kolejce. Zastanawiam się więc, czy dodanie specjalnych węzłów zawierających infima poddrzewa do jakiejś wspólnej struktury stosu byłoby pomocne.
źródło
Odpowiedzi:
Chociaż dokładny problem postawiony w pierwotnym pytaniu wydaje się być trudny (i chciałbym być zainteresowany rozwiązaniem tego problemu, szczególnie części dotyczącej znalezienia infima). Chciałem tylko zauważyć, że jeśli częściowo uporządkowany zestaw rzeczywiście składa się z wektorów korzystających z zamówienia produktu i jeśli wystarczy mieć gwarancję, że kolejka priorytetowa zwróci wartości w kolejności „zgodnej” z kolejnością częściową ( to znaczy, mniejsze elementy są zawsze zwracane przed większymi elementami), wtedy istnieje dość łatwy sposób, aby to zrobić.
Chodzi przede wszystkim o uporządkowanie topologiczne częściowo uporządkowanego zestawu. Oznacza to całkowite zamówienie „ ” takie, że . W przypadku wektorów korzystających z zamówienia produktu jest to dość proste: wystarczy użyć porządku leksykograficznego „ ”, gdzie pierwszy „komponent” jest sumą wszystkich komponentów użytych do zamówienia produktu (pozostałe komponenty są zasadniczo dowolne, abyś mógł trzymać się słabej kolejności). Możemy wtedy zobaczyć, że i a ≤ b≤T ≤ S a < ba≤b⟹a≤Tb ≤S a = b
źródło
Co jest złego w kompletowaniu częściowego zamówienia?
Jeśli wolisz „najpierw najstarsze”, Twoje zamówienie jest faktycznie ukończone; „nieporównywalne” przedmioty są porównywalne pod względem wieku.
Dodaj znacznik czasu (lub dowolną monotonnie rosnącą liczbę całkowitą) do każdego elementu i użyj go, jeśli „rzeczywiste” porównanie jest niemożliwe.
źródło
EDYCJA: wydaje się to interesującym problemem i miałem na ten temat trochę badań. Proponuję przeczytać następujące informacje:
Proponuję przeczytać ten artykuł: Daskalakis, Constantinos i in. „Sortowanie i selekcja w zestawach”. SIAM Journal on Computing 40.3 (2011): 597-622.
Autorzy przedstawiają tutaj strukturę danych o nazwie ChainMerge, która akceptuje poset i rozkład łańcucha poset na łańcuchy. Rozmiar struktury danych wynosi . Autorzy przedstawiają algorytm znajdowania minimów działających w gdzie jest górną granicą szerokości zbioru. .. Myślałem, że może to interesujące.q O ( n q) O ( w n ) w
Uwaga: usunąłem poprzednią naiwną odpowiedź. Kliknij edytuj, aby go zobaczyć.
źródło
Moje użycie terminologii może być nieprawidłowe. Edytuj moją odpowiedź bezpośrednio, aby naprawić znalezione problemy.
Najpierw na wejściach należy wykryć zestawy nieporównywalne ze sobą.
Na przykład może być 5 obiektów
a, b, c, d, e
, ale ich częściowe uporządkowanie tworzy dwa niepowiązane wykresy:a ≤ b ≤ c
d ≤ e
{a, b, c}
jest nieporównywalny z żadnym z nich{d, e}
.Te wzajemnie nieporównywalne zestawy należy najpierw wykryć, zanim obiekty będą mogły zostać zapisane w odpowiedniej strukturze danych. Można to zrobić za pomocą algorytmu wyszukiwania Unii
W celu zwiększenia wydajności wstawienie nowego obiektu musi mieć skuteczny sposób na znalezienie „listy istniejących obiektów, które są porównywalne z tym nowym obiektem”.
Teraz w ramach każdego podzbioru (odpowiednio
{a, b, c}
i{d, e}
) minima powinny być dobrze zdefiniowane. (Dla każdego podzestawu może istnieć jeden lub więcej minimów, z powodu częściowego uporządkowania.)Widzę to jako ukierunkowany wykres acykliczny . Próba zmieszczenia go w kupę wydaje się katastrofalna.
Aby wyodrębnić minima z tej złożonej struktury danych, następnym krokiem jest pobranie listy wszystkich minimów ze wszystkich podzbiorów, wybranie tej z najwcześniejszym znacznikiem czasu oraz usunięcie i zwrócenie tego obiektu.
źródło
Projekt, nad którym pracuję, wiąże się z podobnym problemem (nawiasem mówiąc, używam także częściowej kolejności wektorów). Mieliśmy już kwadratowy algorytm czasowy do sortowania losowo uporządkowanej listy i opracowałem algorytm wstawiania, obserwując jego zachowanie, gdy tylko jeden obiekt był niesprawny. Nie wiemy, czy jest to najszybsza możliwa implementacja.
Oto pseudokod.
źródło
Zwykłym zachowaniem sterty jest dołączanie nowej wartości z tyłu, a następnie przesiewanie w górę, gdy porównuje ona wartość większą niż jej rodzic.
Jeśli napiszesz porównanie, które zwraca to samo dla rodzica, a dziecko nie jest porównywalnym przypadkiem, ponieważ dla rodzica jest większy niż dziecko , przesiewanie w górę powinno nadal kończyć się w odpowiednim momencie.
Czy to liczy się jako wystarczająco stabilne zamówienie dla twoich celów?
Aby to wyjaśnić, weź przykład z komentarza: a> b , a c nie jest porównywalne z a lub b :
więc wynik zależy od kolejności wstawiania - wydaje się, że pasuje do tego, o co prosisz, ale nie jestem pewien, czy naprawdę tego chcesz. Jeśli nie, czy mógłbyś pokazać wynik, który miałeś nadzieję zobaczyć?
OK, więc z twojego komentarza (i edycji pytania) chcesz, aby „porównywalne” elementy przeskoczyły „nieporównywalne” i znaleźć właściwe miejsce pod zamówieniem, jeśli takie istnieje. Zapytałem o to, ponieważ nie byłem pewien, jak interpretować
(d i b są nieporównywalne parami w twojej edycji, ale nie chcesz ich w kolejności, w której zostały wstawione).
Moje następne pytanie dotyczyłoby związku między elementami „porównywalnymi” i „nieporównywalnymi”, ale widzę, że ujawniłeś teraz, że są wektorami w kolejności produktów (nie było jasne, czy niektóre elementy były parami - nieporównywalne ze wszystkim , jak NaN, czy co).
Jeśli więc wezmę twój nowy przykład i przypiszę wartości wektorowe, czy to prawda, że jest to przykład, w którym b nie jest porównywalny z niczym innym:
i powinno posortować to:
?
źródło