Fractional Cascading Fractional Cascading I: A Data Structuring Technique Fractional Cascading II:...

Post on 12-Jan-2016

236 views 0 download

Transcript of Fractional Cascading Fractional Cascading I: A Data Structuring Technique Fractional Cascading II:...

Fractional Cascading

•Fractional Cascading I: A Data Structuring Technique•Fractional Cascading II: Applications

[Chazaelle & Guibas 1986]•Dynamic Fractional Cascading [Mellhorn & Naher 1990]

Elik Etzion January 2002

AgendaPreviewFormal problem definition & Final resultsExample ApplicationIntersecting a polygonal path with a line

Data structure & Algorithm descriptionTime & Space complexity analysisDynamization

PreviewThe problem: Iterative search in sorted listsExamples:

Look up a word in different dictionariesGeometric retrieval problems

The solution: Fractional Cascading Correlate the lists in a way that every search uses the results of the previous search

Formal DefinitionU – an ordered setG = (V,E) – Catalog Graph

undirectedfor each v V C(v) U catalog of vFor each e E R(e) = [ l(e) , r(e) ] range of elocally bounded degree d v V and k U there are at most d edges e = (v,w)

with k R(e)[2,7]

[22,50]

[20,27]

Degree = 4Locally bounded degree = 2[5,15]

Formal Definition - operations

QueryInput : k U , G` = (V`,E`) connected sub-tree of G , e E` k R(e)Outputfor each v V` x C(v) such that x is the successor of k in C(v)

Deletiongiven a key k C(v) and its position in C(v), delete k from C(v)

Insertiongiven a key kU and its successor in C(v), insert k into C(v)

Results

n |V| ,

Space: O(N + |E|) Time:

Vv

vCN |)(|

Query Insert / Delete

Trivial nlogN 1

Static/Semi-

Dynamic

log(N + |E|) + n 1

Dynamic log(N + |E|) + nloglog (N + |E|)

nloglog (N + |E|)amortized

Example application

ProblemInput: Polygonal path P, Arbitrary query line lOutput: intersections of P & l

Solution complexityTrivial space: O(n)

time: O(n)Using FC space: O(nlogn)

time: O((k+1)log[n/(k+1)])

k – number of intersections reported

Example application - Solution

Observation: a straight line l intersects a polygonal path P if and only if l intersects the convex hull CH(p) of P

Notation: F(p) & S(p) – first & second half path of P

Preprocessing:

CH[F(P)]CH[S(P)]

CH[P]

Example application - Algorithm

Intersect( P , l ) {

if |P| = 1 then compute P l directly

else if l doesn’t intersect CH(p) then exitelse{

Intersect ( F(p) , l )Intersect ( S(p) , l )

}}

Example application - Algorithm

Convex hull intersection algorithm:Find the 2 slopes of l in the slope sequence of CH

FC view:Catalog graph: pre-processed CH binary treeCatalogs: slope sequence of the the CHsThe query key: 2 slopes of l

Example application - Complexity

SpaceO(nlogn) - each edge participates in at most logn CHs

Time (static)O(logn + size of sub tree actually visited)O((k+1)log[n/(k+1)])

Data Structure – Illustration

w

v

20 23 48 62 70 80 87 91

20 34 90 95 99

[l,r] l bridge r bridge

y’

x’ x

y

B(x,y)

A(w)

A(v)

- non proper- proper

y.count

x.count

99

75

Data Structure - Definitions

For each node vA(v) C(v) – augmented catalogimplemented as a doubly linked list of recordsC(v) contains proper elementsA(v) – C(v) contains non-proper elements

Record members:key, next, prev, kind

special n.p members:target – node of G incident to vpointer – pointer to a np element in A(x.target) (the other end of the bridge)count – number of elements until the previous bridgein_S – is in a non- balanced block

Bridges & Blocks

(x,y)- a bridge between nodes v & wx A(v) – C(v)y A(w) – C(w)x.pointer = y y.pointer = x x.target = w y.target = vx.key = y.keyx.kind = y.kind = non-proper

Every edge e(v,w) has at list 2 bridgesx.key=y.key = l(e) , x.key = y.key = r(e) Block B(x,y) A(v) A(w)the elements between (x,y) bridge and its neighbor bridge between v & w|B(x,y)| = x.count + y.count

FCQuery

FCQuery (G, G’, k ) (V1, V2 .. Vn) = order of nodes in G’aug_succ = BinarySearch( A(V1), k )successor[1] = FindProper(A(V1), aug_succ)for i = 2 .. n

aug_succ = FCSearch(Vi, k, succssesor[i-1])

successor[i] = FindProper(A(Vi), aug_succ)return successor[1..n]

FCSearch & FindProper

FCSearch ( w, k, x ) x’ = xwhile x’.target != w do x1 = x’.nexty = x’.pointerWhile y.pred.key k do y= y.predreturn y

FindProper in the static caseimplemented in O(1) time using a pointer

from each non-proper element to its proper successor

Block Size

Tradeoff Small blocks increase space complexity but decrease time complexityLarge blocks increase time complexity but decrease space complexity

Block InvariantThere are tow constants a, b with a b such that for all blocks B(x,y) holds: |B(x,y)| b |B(x,y)| a or B(x,y) is the only block between A(x.target) and A(y.target)

Block Lemma

Let

da

vAS

vCN

Vv

Vv

3

|)(|

|)(|

Then |S| 3N+12|E|

Proof …

Complexity Analysis (static)

Space Linear in the size of the catalog graph according to the Block LemmaTime

FindProper O( 1 )

FCSearchO( 1 ) block size is constant

BinarySearch O ( log(|A(V1)|) ) = O ( log(N + |E|) )

FCQuery – O (log(N + |E|) + n )

Dynamization

ChallengesFindProper can’t be implemented simply by using a pointer from each non-proper element to its proper successorInsertions & Deletions violate the Block Invariant

SolutionData Structure based onVan Emde Boas Priority QueueBlock rebalancing

Union- Split DS

FindProperInput: a pointer to some item xOutput: a pointer to a proper item y such that all the items between x & y are non-proper ( y is the proper successor of x)

ADDInput: a pointer to some item xEffect: adds a non-proper item immediately before x

EraseInput: a pointer to a non-proper item xDelete x

Union Input: a pointer to a non-proper item xEffect: change the mark of x to proper

SplitInput: a pointer to a proper item xEffect: change the mark of x to non-proper

Insert – Illustrationy0 y

B(y,z)

A(v)

A(w)

y’

z

A(u)

z’

B(y’,z’)

x

Insert AlgorithmInsert (x , y0)

ADD( x , y0 )if x.kind = proper then UNION(x)insert x into the doubly linked list before y0

y = y0 , A = do b times

w = y.targetif ( y.kind = non-proper and wA and x.key R(v,w) )A = A {w} y.count++z = y.pointerif ( y.In_S = false and y.count + z.count > b)S = S {B(y,z)}y.In_s = true , z.In_S = truey = y.next

Delete AlgorithmDelete (x)

if x.kind = proper then SPLIT(x)DELETE(x)remove x from the doubly linked y = x.next , A = do b times

w = y.targetif ( y.kind = non-proper and wA and x.key R(v,w) )

A = A {w} y.count--z = y.pointerif ( y.In_S = false and y.count + z.count < a and

B(z,y) isn’t the only block between v and w )S = S {B(y,z)}y.In_s = true , z.In_S = true

y = y.next

Balance AlgorithmFor each block B(x,y) S do

l = compute the size of B(x,y) by running to the previous parallel bridge [ O(l) ]

if ( l > b)divide B(x,y) into 3l/b + 1 parts by inserting 2* 3l/b non-proper elements [6l/b O(INSERT) ]

else if ( l < a )concatenate B(x,y) with its right neighbor block B(x’,y’)

by deleting the (x,y) bridge [O(ERASE)]

check if B(x’,y’) S by scanning b elements until reaching the (x’,y’) bridge and checking x’.In_s flag [O(b)]

// if not reached then B(x’,y’) S if B(x’,y’) S

x’.count += x.count , y’.count += y.count if (x’.count > b) S = S {B(x’,y’)}

else S = S – B(x,y)

Complexity Analysis (Dynamic)

Union – Split DS for n elements complexitySpace: o (n)Time : FIND, Union & split: O(loglogn) worst case

ADD, Erase: O(loglogn) amortized ADD/ ERASE in semi-dynamic: O(1)

FC complexitySpace: Remains Linear in the size of the catalog graph because the block invariant is kept by rebalancingTime:FindProper: O( log log(N + |E|) )FCSearch: O( 1 ) BinarySearch O ( log(N + |E|) )FCQuery – O (log(N + |E|) + n log log(N + |E|) )Insert/Delete - O( log log(N + |E|) ) or O (1) or semi-dynamicBalance – O ( log(N + |E|) ) amortized (complex proof)