/// <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); }
/// <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; }
/// <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); }
/// <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(); } }