Beispiel #1
0
        private FCNode FindNodeFromPointerRange(FCNode dataNode, int targetDimension)
        {
            /**
             * Find and search a range of indices for the FCNode with the target data value
             * at the target dimension.
             *
             * Finding range:
             *  DataNode comes from targetDimension - 1 . DataNode contains pointers to
             *  FCNodes from the augmented list of the next dimension (TargetDimension).
             *  The search range is between the locations of DataNode.prev and
             *  DataNode.next in the augmented list in the TargetDimension. */

            int    targetData = dataNode.GetData();
            FCNode prevNode   = dataNode.GetPrevPointer();
            FCNode nextNode   = dataNode.GetNextPointer();

            // Find range
            int lowRange, highRange;
            int targetDimIndex = targetDimension - 1;

            if (prevNode == null)
            {
                lowRange = 0;
            }
            else
            {
                lowRange = prevNode.GetPreviouslyAugmentedIndex();
            }

            if (nextNode == null)
            {
                highRange = NodeMatrixPrime[targetDimIndex].Length;
            }
            else
            {
                highRange = nextNode.GetPreviouslyAugmentedIndex();
            }

            IEnumerable <int> range = Enumerable.Range(lowRange, highRange - lowRange);

            // Search range
            bool found = false;

            foreach (int j in range)
            {
                dataNode = NodeMatrixPrime[targetDimIndex][j];

                if (TargetNodeCheck(dataNode, targetData, targetDimension))
                {
                    found = true;
                    break;
                }
            }

            if (!(found))
            {
                throw new Exception("Can't find node with data " + targetData +
                                    " in dimension: " + targetDimension +
                                    " during fractional cascading search");
            }
            return(dataNode);
        }
Beispiel #2
0
        private FCNode[] BuildListPrime(FCNode[] FCNodeList1, FCNode[] FCNodeList2,
                                        int unitFracDen)
        {
            /**
             * Combine all elements from fcNodeListOne and a fraction of the values from
             * fcNodeListTwo to a new list of FCNode.
             *
             * fcNodeListOne and fcNodeListTwo must be ordered according to their data
             *
             * Note: FCNodeList1 = list(i-1)'
             *    FCNodeList2 = list(i)    */

            // Nested function to handle pointer assignment
            FCNode lastPromotedNode = null;    FCNode lastNotPromotedNode = null;

            void SetPointers(FCNode currentNode)
            {
                // Assign prev and next pointers to closest non-promoted nodes
                if (currentNode.IsPromoted())
                {
                    lastPromotedNode = currentNode;
                    currentNode.SetPrevPointer(lastNotPromotedNode);
                    if (lastNotPromotedNode != null)
                    {
                        if (lastNotPromotedNode.GetNextPointer() == null)
                        {
                            lastNotPromotedNode.SetNextPointer(currentNode);
                        }
                    }
                }
                else        // Assign prev and next pointers to closest promoted nodes
                {
                    lastNotPromotedNode = currentNode;
                    currentNode.SetPrevPointer(lastPromotedNode);
                    if (lastPromotedNode != null)
                    {
                        if (lastPromotedNode.GetNextPointer() == null)
                        {
                            lastPromotedNode.SetNextPointer(currentNode);
                        }
                    }
                }

                currentNode.SetPrime();
            }

            // Instantiate promoted list
            int numPromotedNodes =
                (int)(Math.Ceiling(FCNodeList2.Length / (double)unitFracDen));

            FCNode[] FCNodeListPrime = new FCNode[n + numPromotedNodes];

            // Populate w/ every 2nd elem in FCNodeList2 to be merged into FCNodeListPrime
            FCNode[] nodesToPromote = new FCNode[numPromotedNodes];

            int c = 0; // index counter for nodesToPromote
            int d = 0; // index counter for FCNodeList1
            int j = 0; // index counter for FCNodeListPrime

            for (int i = 0; i < FCNodeList2.Length; i += unitFracDen)
            {
                // It is essential that nodes be copied from here because this is the only
                // state at which we can easily both store their locations in their
                // previous lists and flag them as promoted.
                nodesToPromote[c++] =
                    FCNodeList2[i].MakeCopy(setPromoted: true, prevAugmentedIndex: i);
            }

            // Perform Fractional Cascading transformation
            // -> Merge elements from nodesToPromote and FCNodeList1 into FCNodeListPrime
            // -> For each node, point to the previous and next foreign nodes
            // --> ie. prev and next nodes not present in initial list of given nod
            c = 0;
            while (c < nodesToPromote.Length && d < FCNodeList1.Length)
            {
                if (FCNodeList1[d].GetData() < nodesToPromote[c].GetData())
                {
                    FCNodeListPrime[j] = FCNodeList1[d++].MakeCopy();
                }
                else
                {
                    FCNodeListPrime[j] = nodesToPromote[c++];
                }

                SetPointers(FCNodeListPrime[j]);
                j++;
            }

            // Add leftover values to augmented list:
            while (c < nodesToPromote.Length)
            {
                FCNodeListPrime[j] = nodesToPromote[c++];
                SetPointers(FCNodeListPrime[j]);
                j++;
            }
            while (d < n)
            {
                FCNodeListPrime[j] = FCNodeList1[d++].MakeCopy();
                SetPointers(FCNodeListPrime[j]);
                j++;
            }

            return(FCNodeListPrime);
        }
Beispiel #3
0
        public Dictionary <int, int> FractionalCascadingSearch(int data)
        {
            /**
             * Perform binary search to find data in first dimension. Then iteratively use
             * the previous and/or next pointers to search the (tiny) range of the next
             * dimension given by the prev and next node pointers    */
            BinarySearchNodes bsn = new BinarySearchNodes();

            // Return dictionary w/ key=dimension, pair=location in dimension
            Dictionary <int, int> locationsOfData = new Dictionary <int, int>();

            // Other variables we'll need
            FCNode dataNode = null;
            int    dataIndex;
            int    currentDim = 1;

            // Find data in first dimension
            dataIndex = bsn.BinarySearch(NodeMatrixPrime[0], data, 0);
            dataNode  = NodeMatrixPrime[0][dataIndex];

            // Ensure that dataNode is in the correct dimension - if not check neighbors
            if (dataNode.GetDim() != currentDim)
            {
                FCNode next = dataNode.GetNextPointer();
                FCNode prev = dataNode.GetPrevPointer();
                if (TargetNodeCheck(next, data, currentDim))
                {
                    dataNode = next;
                }
                else if (TargetNodeCheck(prev, data, currentDim))
                {
                    dataNode = prev;
                }
                else
                {
                    string errorMsg = "Cannot locate data in augmented list 1'\n" +
                                      $"DataNode: {dataNode}\nIndex neighbor left:\t" +
                                      NodeMatrixPrime[0][dataIndex - 1] +
                                      "\nIndex neighbor right:\t" +
                                      NodeMatrixPrime[0][dataIndex + 1] +
                                      $"\nNextNode: {next}nPrevNode: {prev}";
                    throw new Exception(errorMsg);
                }
            }

            if (k < nLimit) // This takes up too much memory
            // Assign first dimension location in return dictionary
            {
                locationsOfData[currentDim] = dataNode.GetAttr(1);
            }

            for (int i = 1; i < NodeMatrixPrime.Length; i++)
            {
                // Walk through promoted node pointers, starting with the list 2' until
                // list (k)'
                currentDim++;
                dataNode = FindNodeFromPointerRange(dataNode, currentDim);
                if (k < nLimit)
                {
                    locationsOfData[currentDim] = dataNode.GetAttr(1);
                }
            }

            return(locationsOfData);
        }