And here's another interesting algorithm/structure: Randomized Slide to Front
deadalnix via Digitalmars-d
digitalmars-d at puremagic.com
Mon Nov 30 13:55:46 PST 2015
On Monday, 30 November 2015 at 21:33:31 UTC, Andrei Alexandrescu
wrote:
> Now that we got talking about searching in arrays, allow me to
> also share an idea I've had a short while ago.
>
> (Again, we're in the "I'd prefer to use an array if at all
> possible" mindset. So let's see how we can help searching an
> array with as little work as possible.)
>
> One well-known search strategy is "Bring to front" (described
> by Knuth in TAoCP). A BtF-organized linear data structure is
> searched with the classic linear algorithm. The difference is
> what happens after the search: whenever the search is
> successful, the found element is brought to the front of the
> structure. If we're looking most often for a handful of
> elements, in time these will be near the front of the searched
> structure.
>
> For a linked list, bringing an element to the front is O(1)
> (just rewire the pointers). For an array, things are not so
> pleasant - rotating the found element to the front of the array
> is O(n).
>
> So let's see how we can implement a successful BtF for arrays.
>
> The first idea is to just swap the found element with the first
> element of the array. That's O(1) but has many disadvantages -
> if you search e.g. for two elements, they'll compete for the
> front of the array and they'll go back and forth without making
> progress.
>
> Another idea is to just swap the found element with the one
> just before it. The logic is, each successful find will shift
> the element closer to the front, in a bubble sort manner. In
> time, the frequently searched elements will slowly creep toward
> the front. The resulting performance is not appealing - you
> need O(n) searches to bring a given element to the front, for a
> total of O(n * n) steps spent in the n searches. Meh.
>
> So let's improve on that: whenever an element is found in
> position k, pick a random number i in the range 0, 1, 2, ..., k
> inclusive. Then swap the array elements at indexes i and k.
> This is the Randomized Slide to Front strategy.
>
> With RStF, worst case search time remains O(n), as is the
> unsuccessful search. However, frequently searched elements
> migrate quickly to the front - it only takes O(log n) searches
> to bring a given value at the front of the array.
>
> Insertion and removal are both a sweet O(1), owing to the light
> structuring: to insert just append the element (and perhaps
> swap it in a random position of the array to prime searching
> for it). Removal by position simply swaps the last element into
> the position to be removed and then reduces the size of the
> array.
>
> So the RStF is suitable in all cases where BtF would be
> recommended, but allows an array layout without considerable
> penalty.
>
> Related work: Theodoulos Garefalakis' Master's thesis "A Family
> of Randomized Algorithms for List Accessing" describes Markov
> Move to Front, which brings the searched element to front
> according to a Markov chain schedule; and also Randomized Move
> to Front, which decides whether a found element is brought to
> front depending on a random choice. These approaches are
> similar in that they both use randomization, but different
> because neither has good complexity on array storage.
>
>
> Andrei
What is the advantage compared to let's say a ringbuffer ? On
find you can put the element to the front, and swap the old
element with the new element ?
I guess randomizing would avoid hitting pathological cases too
often, but would converge more slowly ?
More information about the Digitalmars-d
mailing list