5

Definiowanie elementu jako posiadające:Ustalanie minimalnej wartości maksymalnej klastra?

  • unikatowy identyfikator
  • wartość
  • czas tworzenia
  • delecja czas

Mam strumieni dwa wejścia - jedno, co mnie informuje kiedy element jest tworzony, taki, który informuje mnie, kiedy przedmiot zostanie usunięty. Zadzwoń do przedmiotu, który został utworzony, ale nie zniszczony "żywy".

mogę śledzić maksymalną wartość wszystkich żywych elementów wykorzystujących sterty:

whenCreated(item): 
    i = heap.size 
    heap-up(item, heap.size) 
    heap.size = heap.size + 1 
    max-value = heap[0] 

whenDeleted(item): 
    ktem = heap[heap.size - 1] 
    heap.size = heap.size - 1 
    heap-up(ktem, index[item.id]) 
    heap-down(ktem, index[ktem.id]) 
    max-value = heap[0] 

heap-up(item, i): 
    while (i > 0): 
    j = floor((i-1)/2) 
    jtem = heap[j] 
    if (jtem.value > item.value): 
     break while 
    index[jtem.id] = i 
    heap[i] = heap[i] 
    i = j 
    index[item.id] = i 
    heap[i] = item 

heap-down(item, i): 
    while (2*i + 1 < heap.size): 
    if (2*i + 1 == heap.size or heap[2*i+1].value > heap[2*i+2].value): 
     j = 2*i + 1 
    else 
     j = 2*i + 2   
    jtem = heap[j] 
    if (jtem.value < item.value): 
     break while 
    index[jtem.id] = i 
    heap[i] = heap[i] 
    i = j   
    index[item.id] = i 
    heap[i] = item 

Jeśli mam n przedmioty, a następnie dodanie lub usunięcie weźmie O(log n) czasu.

Teraz załóżmy elementy skupione są takie, że biorąc pod uwagę dwa elementy, a i b, |a.value - b.value| < deltaa i b są w tym samym klastrze.

Na przykład, jeśli mamy wartości (1, 2, 3, 4, 7, 8, 11, 13, 14, 15, 16) i delta = 2, to klastry są (1, 2, 3, 4), (7, 8), (11) i (13, 14, 15, 16).

Chciałbym śledzić minimalną wartość klastra, która zawiera maksymalną żywą wartość. Mogę to zrobić, odczytując wartości poza stertą, dopóki nie znajdę przerwy między wartościami większymi niż równe delta. Jednak zajmuje to godzinę O(n), co wydaje się raczej nieefektywne.

Czy istnieje algorytm O(log n) do śledzenia minimalnej wartości tego klastra?

+0

Czy klastry są przechodnie? Na przykład, jeśli delta wynosi 2, to 1, 2, 3, 4, 5 i 6 wszystko w tym samym klastrze? – templatetypedef

+0

Wątpię, czy możesz to zrobić tylko z obecną stertą. Wygląda na to, że potrzebujesz wydajnej, osobnej struktury danych. Rozłączny zestaw byłby dobry, chociaż twoje klastry mogą się scalać, a następnie rozdzielać, więc potrzebujesz czegoś, co pozwala na separację (która nie znajduje się w union-find), podobnie jak wyrafinowanie partycji. – davin

+0

Odpowiedź templatetypedef działa, choć wydaje się trudnym wdrożeniem. Jeśli nie spodziewasz się wielu przypadków granicznych, być może proste rozwiązanie 'O (n)' jest warte zachodu. Oznacza to, że rzadko zdarza się, że koniec klastra zmienia się często, to nie koniec świata. Możesz go nieco poprawić, przechodząc do BST i utrzymując pojedynczy wskaźnik, a następnie twoja operacja 'O (n)' nie występuje przy usuwaniu, tylko w insertach, a nawet wtedy, jeśli spodziewasz się małych klastrów względem 'n' nie powinno być zauważalne. – davin

Odpowiedz

0

Możesz użyć drzew binarnych (lub ich wariantów) zamiast stosów. Znalezienie wartości i minimalnej wartości znajduje się w O (logn). Skonstruuj osobne drzewa binarne dla każdego klastra.

Nie jestem pewien, w jaki sposób odbywa się tworzenie klastrów (można utworzyć wiele klastrów, które spełniają warunek delty, o którym wspomniałeś, dlaczego wybrałeś to konkretne grupowanie?). Można również rozważyć posiadanie jednego gigantycznego drzewa wyszukiwania binarnego do przechowywania wszystkich wartości i oznaczenia niektórych węzłów jako "głowic klastra" (tj. Elementy w drzewie podrzędnym zawierające ten węzeł to klaster). W ten sposób powinieneś łatwo tworzyć i usuwać nowe klastry.

+0

Nie jestem pewien, czy widzę, jak to pomaga, gdy bierzesz pod uwagę klaster. W jaki sposób można skutecznie określić, czy dwa węzły znajdują się w tym samym klastrze? – templatetypedef

+0

Co się stanie, jeśli konieczne będzie połączenie dwóch klastrów? Lub podzielić klastra na dwie części? – templatetypedef

+0

@templatetypedef Utwórz osobne drzewo dla każdego klastra. – ElKamina

4

Uważam, że można to zrobić za pomocą zbalansowanego drzewka binarnego drzewa rozłupującego, aby zagwarantować czas amortyzacji O (log n) dla każdej operacji.

Załóżmy, że nie robiliśmy klastrów. W takim przypadku można po prostu przechowywać wszystkie elementy w zbalansowanym drzewie wyszukiwania binarnego, aby uzyskać wstawienie, usunięcie i wyszukiwanie-min O (log n). Ale w przypadku klastrów to się zmienia. Moja sugestia dotyczy utrzymywania BST klastrów posortowanych według zakresu wartości przechowywanych w klastrze, gdzie każdy klaster jest reprezentowany jako drzewo odtwarzania węzłów, które zawiera.

Aby wstawić element do struktury danych, wykonaj wyszukiwanie w BST dla poprzednika i następcy danego elementu. Jeśli węzeł nie należy do żadnego z tych klastrów, utwórz pojedyncze drzewo splay z tego węzła i wstaw je do BST.Jeśli znajduje się dokładnie w jednym z dwóch znalezionych klasterek, wstaw go do tego klastra. Jeśli jest on zawarty w obu klastrach, usuń oba klastry z BST, scal je razem w jeden klaster, wstaw nowy węzeł do tego klastra, a następnie ponownie umieść klaster w BST. Czas wyszukiwania we wszystkich przypadkach w O (log n), aby znaleźć dwa klastry, a następnie O (log n), zamortyzował czas, aby wstawić do klastra. Scalanie dwóch drzew iglastych jest tu naprawdę szybkie; ponieważ klastry nie były wcześniej scalane, jedno drzewo zawiera wartości, które są ściśle większe niż wszystkie wartości w drugim drzewie, więc scalanie może być wykonane w O (log n) amortyzowanym czasie przez wycofanie wskaźników. Koszt usunięcia dwóch drzew i ich ponownego dodania to również O (log n).

Aby znaleźć minimalną wartość maksymalnego klastra, znajdź maksymalny klaster w BST w czasie O (log n), a następnie znajdź minimalny element klastra znaleziony w amortyzowanym czasie O (log n).

Aby usunąć element, znajdź klaster zawierający go w czasie O (log n). Jeśli znajduje się we własnym klastrze, usuń go z drzewa. Jeśli nie, usuń element z klastra, w którym się znajduje, a następnie znajdź jego poprzednika i następcę w tym klastrze. Jeśli są w delcie siebie, to klaster jest nadal w porządku, a my skończymy. W przeciwnym razie klaster musi zostać podzielony. W czasie amortyzacji O (log n), podziel klaster na skupienie węzłów mniejszych lub równych poprzednikowi i większy lub równy następcy, a następnie ponownie wstaw oba klastry do drzewa.

W sumie daje to O (log n) amortyzację dla każdej operacji.

Mam nadzieję, że to pomoże!

+0

Popatrzę na drzewa gry, dzięki! – rampion

Powiązane problemy