9

Potrzebuję struktury danych w formie tablicy z najszybszą możliwą aktualizacją funkcjonalną. Widziałem kilka różnych implementacji elastycznych tablic, które zapewniają mi tę właściwość (Braun, listy dostępu losowego), ale zastanawiam się, czy istnieje implementacja, która jest specjalnie zoptymalizowana pod kątem przypadku, gdy nie jesteśmy zainteresowani dołączaniem lub wstawianiem - tylko aktualizacje.Jaka jest najskuteczniejsza implementacja tablic z aktualizacjami funkcjonalnymi?

+3

Z pewnością mapa jakiegoś rodzaju? –

+0

@ DominicBou-Samra niezmienna mapa? czy nie byłoby to nawet droższe od macierzy? –

+0

Dominika, mapy, Braun i RAL są oparte na drzewach. Chciałbym sprawdzić, czy istnieje jakieś sprytne połączenie z imperatywną macierzą (która nie jest zmutowana), która może pokonać strukturę danych opartą na czystym drzewie. – rgrinberg

Odpowiedz

13

Jean-Cristophe Filliâtre ma a very nice implementation z trwałych tablic, który jest opisany w the paper połączonych na tej samej stronie (która dotyczy trwałego union-find, którego trwałe składowe są głównym składnikiem). Kod jest dostępny bezpośrednio pod numerem there.

Chodzi o to, że „ostatnia wersja” tablicy jest reprezentowany jako zwykłej tablicy, z O(1) dostępu i operacji aktualizacji, a poprzednie wersje są reprezentowane tej ostatniej wersji, a także lista różnic. Jeśli spróbujesz uzyskać dostęp do poprzedniej wersji struktury, tablica zostanie "ponownie utworzona", aby zastosować listę różnic i ponownie zaprezentować efektywną reprezentację.

To oczywiście nie będzie O (1) pod wszystkimi przepływami pracy (jeśli będziesz mieć stały dostęp do i modyfikować niepowiązane wersje struktury, często będziesz płacić za ponowne wyliczanie kosztów), ale dla wspólnego przepływu pracy głównie z jedną wersją, i od czasu do czasu wracając do starszej wersji, która ponownie staje się "ostatnią wersją" i otrzymuje aktualizacje, jest to bardzo wydajne. Bardzo przyjemne wykorzystanie zmienności ukrytej pod czysto obserwacyjnym interfejsem.

2

Jakiego języka używasz? W Haskell można używać mutable arrays z monadą państwową, aw Merkurymu można używać tablic zmiennych, przewijając stan IO. Ocaml ma również moduł tablicowy, który niestety nie zachowuje referencyjnej przezroczystości, jeśli tego właśnie szukasz.

+1

Używam OCaml. Zaznaczyłem to pytanie jako Haskell, aby wykorzystać wiedzę społeczności o tych rzeczach. Btw, nie jestem pewien, w jaki sposób STArray rozwiąże mój problem z używaniem aktualizacji tablicy przy jednoczesnym zachowaniu skuteczności starej kopii. – rgrinberg

+1

Tablice OCaml są zmienne, nie mają trwałości. Stały dostęp czasowy z aktualizacjami i wytrwałością wydaje się dość trudny, jeśli nie niemożliwy. Tak więc mapa jest prawdopodobnie tym, czego potrzebujesz (zgodnie z sugestią powyżej). –

+0

Istnieje wiele różnych implementacji opartych na mapach, szukam najlepszego dla mojego przypadku użycia. Na przykład zrównoważony BST byłoby okropne dla tego wniosku. Chociaż wydajność asymptotyczna jest taka sama. – rgrinberg

4

Mam bardzo dobre doświadczenia z repa (nice demo). Bardzo dobra wydajność, automatyczny równoległość, wielowymiarowy, polimorficzny. Zalecane, aby spróbować.

1

Potrzebowałem również funkcjonalnych tablic i filcu na to pytanie SO kilka dni temu. Nie byłem usatysfakcjonowany rozwiązaniem zaproponowanym przez Gasche, ponieważ tworzenie nowej macierzy jest kosztowną operacją i muszę często uzyskiwać dostęp do starszych wersji macierzy (mam zamiar użyć tego do implementacji alfa/beta AI odtwarzanej w tablicy).

(Kiedy mówię, kosztowne, myślę, że jest to O (n * h), gdzie h jest wielkością historii, ponieważ w najgorszym przypadku tylko jedna komórka była aktualizowana wielokrotnie i jest potrzebna do przejrzenia całej listy aktualizacji dla każdego komórka.Oczekuję również, większość komórek nie jest aktualizowana, gdy trzeba do przekierowania tablicy).

Dlatego proponuję inne podejście, może uda mi się uzyskać tutaj informacje zwrotne. Moim pomysłem jest przechowywanie tablicy jak w B-Tree, z tym że, ponieważ nie jest zmienna, mogę łatwo uzyskać dostęp i zaktualizować dowolną wartość przez indeks.

Napisałem mały wstęp do repozytorium projektu: https://github.com/shepard8/ocaml-ptarray. Kolejność jest wybierana tak, aby uzyskać nawet głębokość i porządek drzewa, dzięki czemu mogę uzyskać niezłe komplikacje w zależności od kolejności operacji get/set, czyli O (k^2).

Przy k = 10 mogę zapisać do 10^10 wartości. W rzeczywistości moje tablice nie powinny zawierać więcej niż 200 wartości, ale ma to na celu pokazanie, jak trwałe jest moje rozwiązanie.

Każda rada powitana!

Powiązane problemy