예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FibonacciQueue{TVertex,TDistance}"/> class.
        /// </summary>
        /// <param name="capacity">Number of values.</param>
        /// <param name="values">Set of vertices (null if <paramref name="capacity"/> is 0).</param>
        /// <param name="distanceFunc">Function that compute the distance for a given vertex.</param>
        /// <param name="distanceComparison">Comparer of distances.</param>
        public FibonacciQueue(
            int capacity,
            [CanBeNull, ItemNotNull] IEnumerable <TVertex> values,
            [NotNull] Func <TVertex, TDistance> distanceFunc,
            [NotNull] Comparison <TDistance> distanceComparison)
        {
            if (capacity < 0)
            {
                throw new ArgumentException("Must be positive.", nameof(capacity));
            }

            _distanceFunc = distanceFunc ?? throw new ArgumentNullException(nameof(distanceFunc));
            _cells        = new Dictionary <TVertex, FibonacciHeapCell <TDistance, TVertex> >(capacity);

            if (capacity > 0 && values != null)
            {
                foreach (TVertex vertex in values)
                {
                    _cells.Add(
                        vertex,
                        new FibonacciHeapCell <TDistance, TVertex>
                    {
                        Priority = _distanceFunc(vertex),
                        Value    = vertex,
                        Removed  = true
                    }
                        );
                }
            }

            _heap = new FibonacciHeap <TDistance, TVertex>(HeapDirection.Increasing, distanceComparison);
        }
예제 #2
0
        /// <summary>
        /// Merges the given <paramref name="heap"/> into this heap.
        /// </summary>
        /// <param name="heap">Heap to merge.</param>
        /// <exception cref="Exception">If the heap is not in the same direction.</exception>
        public void Merge([NotNull] FibonacciHeap <TPriority, TValue> heap)
        {
            if (heap is null)
            {
                throw new ArgumentNullException(nameof(heap));
            }
            if (heap.Direction != Direction)
            {
                throw new InvalidOperationException("Heaps must go in the same direction when merging.");
            }
            if (heap.IsEmpty)
            {
                return;
            }

            bool isEmpty = IsEmpty;

            _cells.MergeLists(heap._cells);
            if (isEmpty || PriorityComparison(heap.Top.Priority, Top.Priority) * _directionMultiplier < 0)
            {
                Top = heap.Top;
            }

            Count += heap.Count;
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FibonacciQueue{TVertex,TDistance}"/> class.
        /// </summary>
        /// <param name="values">Dictionary of vertices associates to their distance.</param>
        /// <param name="distanceComparison">Comparer of distances.</param>
        public FibonacciQueue(
            [NotNull] Dictionary <TVertex, TDistance> values,
            [NotNull] Comparison <TDistance> distanceComparison)
        {
            if (values is null)
            {
                throw new ArgumentNullException(nameof(values));
            }
            if (distanceComparison is null)
            {
                throw new ArgumentNullException(nameof(distanceComparison));
            }

            _distanceFunc = AlgorithmExtensions.GetIndexer(values);
            _cells        = new Dictionary <TVertex, FibonacciHeapCell <TDistance, TVertex> >(values.Count);

            foreach (KeyValuePair <TVertex, TDistance> pair in values)
            {
                _cells.Add(
                    pair.Key,
                    new FibonacciHeapCell <TDistance, TVertex>
                {
                    Priority = pair.Value,
                    Value    = pair.Key,
                    Removed  = true
                }
                    );
            }

            _heap = new FibonacciHeap <TDistance, TVertex>(HeapDirection.Increasing, distanceComparison);
        }
예제 #4
0
        /// <inheritdoc />
        public IEnumerator <KeyValuePair <TPriority, TValue> > GetEnumerator()
        {
            var tempHeap   = new FibonacciHeap <TPriority, TValue>(Direction, PriorityComparison);
            var cellsStack = new Stack <FibonacciHeapCell <TPriority, TValue> >();

            _cells.ForEach(x => cellsStack.Push(x));
            while (cellsStack.Count > 0)
            {
                FibonacciHeapCell <TPriority, TValue> topCell = cellsStack.Peek();
                tempHeap.Enqueue(topCell.Priority, topCell.Value);
                cellsStack.Pop();
                topCell.Children?.ForEach(x => cellsStack.Push(x));
            }

            while (!tempHeap.IsEmpty)
            {
                yield return(tempHeap.Top.ToKeyValuePair());

                tempHeap.Dequeue();
            }
        }