Author: simonetripodi
Date: Tue Jul 12 19:58:43 2011
New Revision: 1145744

URL: http://svn.apache.org/viewvc?rev=1145744&view=rev
Log:
added consolidate() implementation and rearranges tuff, FIB-HEAP-LINK is still 
a TODO

Modified:
    
commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/collections/FibonacciHeap.java

Modified: 
commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/collections/FibonacciHeap.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/collections/FibonacciHeap.java?rev=1145744&r1=1145743&r2=1145744&view=diff
==============================================================================
--- 
commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/collections/FibonacciHeap.java
 (original)
+++ 
commons/sandbox/graph/trunk/src/main/java/org/apache/commons/graph/collections/FibonacciHeap.java
 Tue Jul 12 19:58:43 2011
@@ -20,6 +20,8 @@ package org.apache.commons.graph.collect
  */
 
 import static java.lang.Math.sqrt;
+import static java.lang.Math.log;
+import static java.lang.Math.floor;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -38,7 +40,7 @@ public final class FibonacciHeap<E>
     implements Queue<E>
 {
 
-    private static final int PHI = (int) ( ( 1 + sqrt( 5 ) ) / 2 );
+    private static final double LOG_PHI = log( ( 1 + sqrt( 5 ) ) / 2 );
 
     /**
      * The comparator, or null if priority queue uses elements'
@@ -93,29 +95,7 @@ public final class FibonacciHeap<E>
         // left[x] <- x
         // right[x] <- x
         // mark[x] <- FALSE
-        FibonacciHeapNode<E> node = new FibonacciHeapNode<E>( e );
-
-        // if min[H] = NIL
-        if ( isEmpty() )
-        {
-            // then min[H] <- x
-            minimumNode = node;
-        }
-        else
-        {
-            // concatenate the root list containing x with root list H
-            minimumNode.getLeft().setRight( node );
-            node.setLeft( minimumNode.getLeft() );
-            node.setRight( minimumNode );
-            minimumNode.setLeft( node );
-
-            // if key[x] < key[min[H]]
-            if ( compare( e, minimumNode.getElement() ) < 0 )
-            {
-                // then min[H] <- x
-                minimumNode = node;
-            }
-        }
+        addNode( new FibonacciHeapNode<E>( e ) );
 
         // n[H] <- n[H] + 1
         size++;
@@ -324,27 +304,73 @@ public final class FibonacciHeap<E>
         return poll();
     }
 
+    /**
+     * Implements the {@code CONSOLIDATE(H)} function.
+     */
     private void consolidate()
     {
-        if ( minimumNode == null )
+        if ( isEmpty() )
         {
             return;
         }
 
-        List<FibonacciHeapNode<E>> nodeSequence = new 
ArrayList<FibonacciHeapNode<E>>();
+        // D( n[H] ) <= log_phi( n[H] )
+        // -> log_phi( n[H] ) = log( n[H] ) / log( phi )
+        // -> D( n[H] ) = log( n[H] ) / log( phi )
+        int arraySize = ( (int) floor( log( size ) / LOG_PHI ) ) + 1;
 
-        FibonacciHeapNode<E> pointer = minimumNode.getRight();
+        // A[i] <- NIL
+        List<FibonacciHeapNode<E>> nodeSequence = new 
ArrayList<FibonacciHeapNode<E>>(arraySize);
 
-        while ( pointer != minimumNode )
+        // for each node w in the root list of H
+        for ( FibonacciHeapNode<E> w = minimumNode.getRight(); w != 
minimumNode ; w = w.getRight() )
         {
-            int degree = pointer.getDegree();
+            // x <- w
+            FibonacciHeapNode<E> x = w;
+
+            // d <- degree[x]
+            int degree = x.getDegree();
+
+            // while A[d] != NIL
+            while ( nodeSequence.get( degree ) != null )
+            {
+                // do y <- A[d]
+                FibonacciHeapNode<E> y = nodeSequence.get( degree );
+
+                // if key[x] > key[y]
+                if ( compare( x, y ) > 0 )
+                {
+                    // exchange x <-> y
+                    FibonacciHeapNode<E> pointer = y;
+                    y = x;
+                    x = pointer;
+                }
+
+                // TODO FIB-HEAP-LINK(H,y,x)
+
+                // A[d] <- NIL
+                nodeSequence.set( degree, null );
 
-            
+                // d <- d + 1
+                degree++;
+            }
 
-            pointer = pointer.getRight();
+            // A[d] <- x
+            nodeSequence.set( degree, x );
         }
 
-        
+        // min[H] <- NIL
+        minimumNode = null;
+
+        // for i <- 0 to D(n[H])
+        for ( FibonacciHeapNode<E> pointer : nodeSequence )
+        {
+            // if A[i] != NIL
+            if ( pointer != null )
+            {
+                addNode( pointer );
+            }
+        }
     }
 
     /**
@@ -358,14 +384,39 @@ public final class FibonacciHeap<E>
         return trees + 2 * markedNodes;
     }
 
-    private int compare( E o1, E o2 )
+    private void addNode( FibonacciHeapNode<E> node )
+    {
+        // if min[H] = NIL
+        if ( isEmpty() )
+        {
+            // then min[H] <- x
+            minimumNode = node;
+        }
+        else
+        {
+            // concatenate the root list containing x with root list H
+            minimumNode.getLeft().setRight( node );
+            node.setLeft( minimumNode.getLeft() );
+            node.setRight( minimumNode );
+            minimumNode.setLeft( node );
+
+            // if key[x] < key[min[H]]
+            if ( compare( node, minimumNode ) < 0 )
+            {
+                // then min[H] <- x
+                minimumNode = node;
+            }
+        }
+    }
+
+    private int compare( FibonacciHeapNode<E> o1, FibonacciHeapNode<E> o2 )
     {
         if ( comparator != null )
         {
-            return comparator.compare( o1, o2 );
+            return comparator.compare( o1.getElement(), o2.getElement() );
         }
-        Comparable<? super E> o1Comparable = (Comparable<? super E>) o1;
-        return o1Comparable.compareTo( o2 );
+        Comparable<? super E> o1Comparable = (Comparable<? super E>) 
o1.getElement();
+        return o1Comparable.compareTo( o2.getElement() );
     }
 
 }


Reply via email to