Lec 7 Implementasi Disjoint Set

   Making a “good” maze

   Disjoint Set Union/Find ADT

   Up-trees

   Maze revisited

  Represent maze environment as graph {V,E}  collection of rooms: V

   connections between rooms (initially all closed):

E

  Construct a maze:  collection of rooms: V = V

   designated rooms in, iV, and out, oV

   collection of connections to knock down: E E such that a unique path connects any two rooms

   So far, some walls have been knocked down while others remain.

   Now, we consider the wall between A and B.

  A 

  Should we knock it down?  no, if A and B are otherwise connected

  B  yes, if A and B are not otherwise connected While edges remain in E

  Remove a random edge e = (u, v) from E

  If u and v have not yet been connected

  e to E

  • add

  u and v as connected

  • mark
An equivalence relation R has three properties: refexive: for any x, xRx is true symmetric: for any x and y, xRy implies yRx transitive: for any x, y, and z, xRy and yRz implies xRz

Connection between rooms is an equivalence relation (call it C)

For any rooms a, b, c a C a (A room connects to itself!) If a C b, then b C a If a C b and b C c, then a C c

  Other equivalence relations? Union/Find ADT operations union find( 4 )

  {1,4,8} {6} fnd

  create

  8

  {7}

  {2,3,6} destroy

  {5,9,10}

  {2,3} union(

2 ,

6 )

  Disjoint set equivalence property: every element of a DS U/F structure belongs to exactly one set Dynamic equivalence property: the set of an element can change after execution of a union

  Given a set U = {a 1 , a 2 , … , a n } Maintain a partition of U, a set of subsets of U {S 1 , S 2 , … , S k } such that: -

  • - each pair of subsets S i and S j are disjoint: together, the subsets cover U:
    • - The S i

       are mutually exclusive and collectively exhaustive Union(a, b) creates a new subset which is the union of a’s subset and b’s subset

      

    NOTE: outside agent decides when/what to union - ADT is just the

    bookkeeper

      Find(a) returns a unique name for a’s subset NOTE: set names are arbitrary! We only care that:

       k i i S U 1

          j i S S

      3

      10

      a b c

      Construct the maze on the right

      2

      1

      6 Initial state (set names underlined):

      4

      7

      d e f

      {a}{b}{c}{d}{e}{f}{g}{h}{i}

      11

      9

      8 Maze constructor (outside agent) traverses edges in random order

      12

      5 and decides whether to union

      g h i

      {a}{b}{c}{d}{e}{f}{g}{h}

      3

      10

      a b c

      {i}

      2

      1

      6 find(b)  b find(e)  e

      4

      7

      d e f

      find(b)  find(e) so: add

      1 to E

      11

      9

      8 union(b, e)

      12

      5

      g h i

      {a}{b,e}{c}{d}{f}{g}{h} {i}

      Order of edges in blue

      

    Finding the representative member of a set

    is somewhat like the opposite of finding whether a given item exists in a set.

      So, instead of using trees with pointers from each node to its children; let’s use trees with a pointer from each node to its parent.

       Each subset is an up- tree with its root as its representative member

      a c h

      

      g

      All members of a given set are nodes in that set’s up-tree

      f i d b

       Hash table maps input data to the node associated with that

      e

      data Up-trees are not necessarily binary! find( f ) find( e )

      a b c

      10

      a c g h

      d e f

      7

    f i

      d b

      11

      9

      8 g h i

      12 e

      Just traverse to the root! union( a,c )

      a b c

      10 a c g h d e f

      f i d b

      11

      9

      8 g h i

      12

      e

      Just hang one root from the other! runtime: a b c

      3

      10

      2

      1

      6 d e f

      4

      7

      11

      9

      8

      union( b , e )

      g h i

      12

      5

      a b c d e f g h i a b c d f g h i a b c

      3

      10

      2

      6 d e f

      4

      7

      11

      9

      8

      union( a , d )

      g h i

      12

      5 a b c d f g h i

      e a b c f g h i a b c

      3

      10

      6 d e f

      4

      7

      11

      9

      8

      union( a , b )

      g h i

      12

      5 a b c f g h i

      d e a c f g h i b d a b c

      10

      6 d e f

      4

      7

      11

      9

      8

      find( d ) = find( e )

      g h i

      12

      5 No union!

      a c f g h i b d

      e a b c

      10

      6 d e f

      7

      11

      9

      8

      union( h , i )

      g h i

      12

      5

      a c f g h i a c f g h b d i b d a b c

      10

      6 d e f

      7

      11

      9

      8

      union( c , f )

      g h i

      12

      a c f g h a c g h b d b d f i i a b c

      10 d e f

      7

      find( e )

      11

      9

      8

      find( f ) union( a , c )

      g h i

      12 a c g h

      c g h b d f a f i i b d e a d b e c f g h i

      11

      10

      9

      8

      12

      f g h a b c i d f g h a b

      c

      i d find( f ) find( i ) union( c , h ) find( e ) = find( h ) and find( b ) = find( c ) So, no unions for either of these.

      a d b e c f g h i

      11

      10

      9

      12

      f g h a b

      c

      i d a b c d e f

      find( d )

      11

      find( g )

      g h i

      union( c , g )

      12 c g

      g c a f h a f h b d i b d i find( g ) = find( h ) So, no union.

      And, we’re done!

      a d b e c f g h i

      12

      f g h a b c i d

      a d b e c f g h i

      Ooh… scary!

       A forest of up-trees can easily be

      a c g h stored in an array.

       Also, if the node

      b d f i

      names are integers or characters, we can use a very

      e

      simple, perfect Nifty storage trick! hash.

      0 (a) 1 (b) 2 (c) 3 (d) 4 (e) 5 (f) 6 (g) 7 (h) 8 (i)

      up-index: -1 -1

      1 2 -1 -1

      7

      typedef ID int;

      ID union(ID x, ID y) {

      ID find(Object x) { assert(up[x] == -1); assert(hTable.contains(x)); assert(up[y] == -1);

       ID xID = hTable[x]; up[y] = x; while(up[xID] != -1) { } xID = up[xID]; } return xID; } runtime: O(depth) or … runtime: O(1)

       Simple ADT, simple data structure, simple code

      

    Complex complexity analysis, but extremely useful

    result: essentially, constant time!

       Lots of potential applications Object-property collections Index partitions: e.g. parts inspection To say nothing of maze construction

      In some applications, it may make sense to have meaningful (non-arbitrary) set names