অগ্রণী সারি। নেট [বন্ধ]


216

আমি একটি অগ্রাধিকার সারি বা হিপ ডেটা কাঠামোর একটি। নেট প্রয়োগের সন্ধান করছি

অগ্রাধিকারের সারিগুলি এমন ডাটা স্ট্রাকচার যা সাধারণ বাছাইয়ের চেয়ে আরও নমনীয়তা সরবরাহ করে কারণ তারা নতুন উপাদানগুলিকে স্বেচ্ছাসেবী বিরতিতে একটি সিস্টেমে প্রবেশের অনুমতি দেয়। এ জাতীয় প্রতিটি আগমনের সবকিছুকে নতুন করে সাজানোর চেয়ে কোনও নতুন কাজকে অগ্রাধিকারের কাতারে সন্নিবেশ করা অনেক বেশি সাশ্রয়ী।

প্রাথমিক অগ্রাধিকার সারিতে তিনটি প্রাথমিক ক্রিয়াকলাপ সমর্থন করে:

  • সন্নিবেশ (কিউ, এক্স)। কী-কে দিয়ে একটি আইটেম এক্স দেওয়া, এটি অগ্রাধিকারের সারি Q এ সন্নিবেশ করান
  • এই-নূন্যতম (কিউ)। আইটেমটিতে একটি পয়েন্টার ফিরিয়ে দিন যার মূল মানটি অগ্রাধিকারের সারি Q এ থাকা অন্য কীগুলির চেয়ে ছোট Q
  • মুছে ফেলুন-নূন্যতম (কিউ)। অগ্রাধিকার সারির কিউ থেকে আইটেমটি সরিয়ে নিন Q এর কী সর্বনিম্ন

আমি ভুল জায়গায় না তাকালে ফ্রেমওয়ার্কে একটিও নেই। কেউ কি ভাল সম্পর্কে সচেতন, বা আমার নিজের রোল করা উচিত?


34
এফওয়াইআই আমি সহজেই ব্যবহারযোগ্য, অত্যন্ত অনুকূল সি # অগ্রাধিকার-সারি তৈরি করেছি, যা এখানে পাওয়া যাবে । এটি বিশেষত প্যাথফাইন্ডিং অ্যাপ্লিকেশনগুলির জন্য তৈরি করা হয়েছিল (এ * ইত্যাদি) তবে অন্য যে কোনও অ্যাপ্লিকেশনটির জন্যও এটি পুরোপুরি কাজ করা উচিত। আমি
এটার


স্প্রিং.নেটের জাভা সমান্তরাল এপিআই। নেট থেকে বন্দর করার প্রচেষ্টার অংশ হিসাবে নির্লজ্জভাবে প্রাইমারিটিকিউ চালু করুন । এটি সম্পূর্ণ জেনেরিক সমর্থন সহ একটি গাদা এবং সারি উভয়ই। বাইনারি এখানে ডাউনলোড করা যেতে পারে ।
কেনেথ জু

@ ব্লুরাজা-ড্যানিপ্লুঘুফুট আপনি কি একটি উত্তর যুক্ত করতে পারবেন?
মাফু

1
শুধু সংক্ষেপে। .NET- তে কোনও হ্যাপের ডেটা কাঠামো নেই, এখন নেট নেটওয়ার্কেও নেই। যদিও অ্যারে.এটি বড় সংখ্যার জন্য ব্যবহারকারীদের বাছাই করুন। অভ্যন্তরীণ বাস্তবায়ন বিদ্যমান।
আরটিয়াম

উত্তর:


44

আমি পাওয়ার সংগ্রহগুলিতেOrderedBag এবং OrderedSetক্লাসগুলি অগ্রাধিকারের সারি হিসাবে ব্যবহার করতে পছন্দ করি ।


60
অর্ডারব্যাগ / অর্ডারডেট প্রয়োজনের চেয়ে আরও বেশি কাজ করে, তারা গাদা করার পরিবর্তে একটি লাল-কালো গাছ ব্যবহার করে।
ড্যান বেরিনেদি

3
@ ডানবীরিন্দেই: যদি আপনার চলমান গণনা করা প্রয়োজন (পুরানো আইটেমগুলি মুছুন), গাদা কেবলমাত্র ন্যূনতম বা সর্বাধিক মুছে ফেলা সমর্থন করে
এসভিস্ট্যাক ২

69

আপনি সি 5 জেনেরিক সংগ্রহ লাইব্রেরি থেকে ইন্টারভালহ্যাপ পছন্দ করতে পারেন । ব্যবহারকারী গাইড উদ্ধৃত

ক্লাস জোড়ের অ্যারে হিসাবে সঞ্চিত একটি ইন্টারভাল হিপ ব্যবহার করে IntervalHeap<T>ইন্টারফেস প্রয়োগ IPriorityQueue<T>করে। ফাইন্ডমিন এবং ফাইন্ডম্যাক্স অপারেশনগুলি এবং সূচকের গেট-অ্যাকসেসর, সময় নেবে O (1)। মুছে ফেলুন, মুছে ফেলুন, মুছে ফেলা এবং আপডেট অপারেশনগুলি এবং সূচকের সেট-অ্যাকসেসর, সময় নেবে O (লগ এন)। একটি সাধারণ অগ্রাধিকার সারির বিপরীতে, একটি বিরতি গাদা একই দক্ষতার সাথে ন্যূনতম এবং সর্বাধিক অপারেশন উভয়ই সরবরাহ করে।

এপিআই যথেষ্ট সহজ

> var heap = new C5.IntervalHeap<int>();
> heap.Add(10);
> heap.Add(5);
> heap.FindMin();
5

নুগেট https://www.nuget.org/packages/C5 বা গিটহাব https://github.com/sestoft/C5/ থেকে ইনস্টল করুন


3
এটি দেখতে খুব শক্ত লাইব্রেরি বলে মনে হচ্ছে এবং এটি 1400 ইউনিট পরীক্ষার সাথে আসে।
ইসিসি-ড্যান

2
আমি এটি ব্যবহার করার চেষ্টা করেছি তবে এর মারাত্মক ত্রুটি রয়েছে। ইন্টারভালহ্যাপের মধ্যে অগ্রাধিকারের অন্তর্নির্মিত ধারণা নেই এবং আপনাকে আইকোম্যাপারেবল বা আইসিএমপ্যাপার প্রয়োগ করতে বাধ্য করে এটি একটি সাজানো সংগ্রহকে "অগ্রাধিকার" নয়। আরও খারাপ কিছু পূর্ববর্তী প্রবেশের অগ্রাধিকার আপডেট করার সরাসরি উপায় নেই !!!
মরতেজা খোসরভি

52

.NET গাদাতে আমার চেষ্টা এখানে

public abstract class Heap<T> : IEnumerable<T>
{
    private const int InitialCapacity = 0;
    private const int GrowFactor = 2;
    private const int MinGrow = 1;

    private int _capacity = InitialCapacity;
    private T[] _heap = new T[InitialCapacity];
    private int _tail = 0;

    public int Count { get { return _tail; } }
    public int Capacity { get { return _capacity; } }

    protected Comparer<T> Comparer { get; private set; }
    protected abstract bool Dominates(T x, T y);

    protected Heap() : this(Comparer<T>.Default)
    {
    }

    protected Heap(Comparer<T> comparer) : this(Enumerable.Empty<T>(), comparer)
    {
    }

    protected Heap(IEnumerable<T> collection)
        : this(collection, Comparer<T>.Default)
    {
    }

    protected Heap(IEnumerable<T> collection, Comparer<T> comparer)
    {
        if (collection == null) throw new ArgumentNullException("collection");
        if (comparer == null) throw new ArgumentNullException("comparer");

        Comparer = comparer;

        foreach (var item in collection)
        {
            if (Count == Capacity)
                Grow();

            _heap[_tail++] = item;
        }

        for (int i = Parent(_tail - 1); i >= 0; i--)
            BubbleDown(i);
    }

    public void Add(T item)
    {
        if (Count == Capacity)
            Grow();

        _heap[_tail++] = item;
        BubbleUp(_tail - 1);
    }

    private void BubbleUp(int i)
    {
        if (i == 0 || Dominates(_heap[Parent(i)], _heap[i])) 
            return; //correct domination (or root)

        Swap(i, Parent(i));
        BubbleUp(Parent(i));
    }

    public T GetMin()
    {
        if (Count == 0) throw new InvalidOperationException("Heap is empty");
        return _heap[0];
    }

    public T ExtractDominating()
    {
        if (Count == 0) throw new InvalidOperationException("Heap is empty");
        T ret = _heap[0];
        _tail--;
        Swap(_tail, 0);
        BubbleDown(0);
        return ret;
    }

    private void BubbleDown(int i)
    {
        int dominatingNode = Dominating(i);
        if (dominatingNode == i) return;
        Swap(i, dominatingNode);
        BubbleDown(dominatingNode);
    }

    private int Dominating(int i)
    {
        int dominatingNode = i;
        dominatingNode = GetDominating(YoungChild(i), dominatingNode);
        dominatingNode = GetDominating(OldChild(i), dominatingNode);

        return dominatingNode;
    }

    private int GetDominating(int newNode, int dominatingNode)
    {
        if (newNode < _tail && !Dominates(_heap[dominatingNode], _heap[newNode]))
            return newNode;
        else
            return dominatingNode;
    }

    private void Swap(int i, int j)
    {
        T tmp = _heap[i];
        _heap[i] = _heap[j];
        _heap[j] = tmp;
    }

    private static int Parent(int i)
    {
        return (i + 1)/2 - 1;
    }

    private static int YoungChild(int i)
    {
        return (i + 1)*2 - 1;
    }

    private static int OldChild(int i)
    {
        return YoungChild(i) + 1;
    }

    private void Grow()
    {
        int newCapacity = _capacity*GrowFactor + MinGrow;
        var newHeap = new T[newCapacity];
        Array.Copy(_heap, newHeap, _capacity);
        _heap = newHeap;
        _capacity = newCapacity;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return _heap.Take(Count).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

public class MaxHeap<T> : Heap<T>
{
    public MaxHeap()
        : this(Comparer<T>.Default)
    {
    }

    public MaxHeap(Comparer<T> comparer)
        : base(comparer)
    {
    }

    public MaxHeap(IEnumerable<T> collection, Comparer<T> comparer)
        : base(collection, comparer)
    {
    }

    public MaxHeap(IEnumerable<T> collection) : base(collection)
    {
    }

    protected override bool Dominates(T x, T y)
    {
        return Comparer.Compare(x, y) >= 0;
    }
}

public class MinHeap<T> : Heap<T>
{
    public MinHeap()
        : this(Comparer<T>.Default)
    {
    }

    public MinHeap(Comparer<T> comparer)
        : base(comparer)
    {
    }

    public MinHeap(IEnumerable<T> collection) : base(collection)
    {
    }

    public MinHeap(IEnumerable<T> collection, Comparer<T> comparer)
        : base(collection, comparer)
    {
    }

    protected override bool Dominates(T x, T y)
    {
        return Comparer.Compare(x, y) <= 0;
    }
}

কিছু পরীক্ষা:

[TestClass]
public class HeapTests
{
    [TestMethod]
    public void TestHeapBySorting()
    {
        var minHeap = new MinHeap<int>(new[] {9, 8, 4, 1, 6, 2, 7, 4, 1, 2});
        AssertHeapSort(minHeap, minHeap.OrderBy(i => i).ToArray());

        minHeap = new MinHeap<int> { 7, 5, 1, 6, 3, 2, 4, 1, 2, 1, 3, 4, 7 };
        AssertHeapSort(minHeap, minHeap.OrderBy(i => i).ToArray());

        var maxHeap = new MaxHeap<int>(new[] {1, 5, 3, 2, 7, 56, 3, 1, 23, 5, 2, 1});
        AssertHeapSort(maxHeap, maxHeap.OrderBy(d => -d).ToArray());

        maxHeap = new MaxHeap<int> {2, 6, 1, 3, 56, 1, 4, 7, 8, 23, 4, 5, 7, 34, 1, 4};
        AssertHeapSort(maxHeap, maxHeap.OrderBy(d => -d).ToArray());
    }

    private static void AssertHeapSort(Heap<int> heap, IEnumerable<int> expected)
    {
        var sorted = new List<int>();
        while (heap.Count > 0)
            sorted.Add(heap.ExtractDominating());

        Assert.IsTrue(sorted.SequenceEqual(expected));
    }
}

2
আমি এক্সট্রাক্টডমিনেটিংয়ের স্তূপের মানটি সাফ করার পরামর্শ দিচ্ছি, সুতরাং এটি প্রয়োজনীয় রেফারেন্সযুক্ত বস্তুটিকে ধরে রাখে না (সম্ভাব্য মেমরি ফাঁস)। মান ধরণের জন্য এটি অবশ্যই উদ্বেগের নয়।
ওয়াউট 3'15

5
ভাল লাগছে তবে আপনি কি এগুলি থেকে আইটেমগুলি সরাতে পারবেন না? এটি অগ্রাধিকারের সারির জন্য গুরুত্বপূর্ণ অপারেশন।
টম লারক্যায়েবল

দেখে মনে হচ্ছে অন্তর্নিহিত অবজেক্টটি একটি অ্যারে। এটি কি বাইনারি গাছ হিসাবে ভাল হবে না?
গ্রুনিয়ন শাফটো

1
@ ওহাদশনিডার খুব দুর্দান্ত, আমি কেবল মিনি মিনিটের গাদা খুঁজছিলাম এবং আপনি যা জেনেরিক এবং ন্যূনতম বা সর্বাধিক হিপ তৈরি করেছেন তা করার চেষ্টা করছিলাম! মহান কাজ
গিলাদ

1
@ গিলাদ IEqualityComparer<T>যথেষ্ট হবে না, কারণ এটি আপনাকে কেবল দুটি আইটেম সমান কিনা তা আপনাকে জানাতে পারে, তবে তাদের (যেগুলি ছোট / বৃহত্তর) এর মধ্যে সম্পর্ক সম্পর্কে আপনার জানতে হবে। এটি সত্য যে আমি IComparer<T>যদিও এটি ব্যবহার করতে পারতাম ...
ওহাদ স্নাইডার

23

এখানে আমি কেবল একটি লিখেছি, সম্ভবত এটি অপ্টিমাইজড নয় (কেবল একটি সাজানো অভিধান ব্যবহার করে) তবে বুঝতে সহজ। আপনি বিভিন্ন ধরণের অবজেক্টগুলি সন্নিবেশ করতে পারেন, তাই জেনেরিক সারি নেই।

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;

namespace PrioQueue
{
    public class PrioQueue
    {
        int total_size;
        SortedDictionary<int, Queue> storage;

        public PrioQueue ()
        {
            this.storage = new SortedDictionary<int, Queue> ();
            this.total_size = 0;
        }

        public bool IsEmpty ()
        {
            return (total_size == 0);
        }

        public object Dequeue ()
        {
            if (IsEmpty ()) {
                throw new Exception ("Please check that priorityQueue is not empty before dequeing");
            } else
                foreach (Queue q in storage.Values) {
                    // we use a sorted dictionary
                    if (q.Count > 0) {
                        total_size--;
                        return q.Dequeue ();
                    }
                }

                Debug.Assert(false,"not supposed to reach here. problem with changing total_size");

                return null; // not supposed to reach here.
        }

        // same as above, except for peek.

        public object Peek ()
        {
            if (IsEmpty ())
                throw new Exception ("Please check that priorityQueue is not empty before peeking");
            else
                foreach (Queue q in storage.Values) {
                    if (q.Count > 0)
                        return q.Peek ();
                }

                Debug.Assert(false,"not supposed to reach here. problem with changing total_size");

                return null; // not supposed to reach here.
        }

        public object Dequeue (int prio)
        {
            total_size--;
            return storage[prio].Dequeue ();
        }

        public void Enqueue (object item, int prio)
        {
            if (!storage.ContainsKey (prio)) {
                storage.Add (prio, new Queue ());
              }
            storage[prio].Enqueue (item);
            total_size++;

        }
    }
}

এটি একই অগ্রাধিকার সহ একাধিক এন্ট্রি অনুমতি দেয় না?
লেটস্যাট লঞ্চ

2
এটা করে. আপনি যখন এনকুই পদ্ধতিটি চালু করবেন, এটি আইটেমটিকে অগ্রাধিকারের কাতারে যুক্ত করবে। (
এনকুই

5
"এটি আসলে কম্পিউটার বিজ্ঞানের অর্থের মধ্যে একটি অগ্রাধিকারের সারি নয়" বলতে কী বোঝায়? এটি সম্পর্কে কী আপনি বিশ্বাস করেন যে এটি কোনও অগ্রাধিকারের সারি নয়?
মার্ক বাইয়ার্স

14
জেনেরিক ব্যবহার না করার জন্য -1।
cdiggins

2
হিপ / অগ্রাধিকারের কিউয়ের সবচেয়ে বড় সুবিধা হ'ল ন্যূনতম / সর্বাধিক উত্তোলনের ও (1) জটিলতা, অর্থাত পিক অপারেশন। এবং এখানে এটির জন্য গণক সেটআপ, লুপ, ইত্যাদি জড়িত কেন !? এছাড়াও, "এনকুই" অপারেশনটি ও (লগএন) না হয়ে ওঠার চেয়ে - হিপটির আরও একটি মূল বৈশিষ্ট্য, "কন্টেন্টসকি" এর কারণে একটি ও (লংএন) সোয়াইপ রয়েছে, সারি প্রবেশদ্বার যুক্ত করার জন্য দ্বিতীয় (আবার ও (লংএন)) রয়েছে (যদি প্রয়োজন হয়), তৃতীয়টি আসলে কুই (স্টোরেজ [প্রিও] লাইন) পুনরুদ্ধার করতে হবে এবং অবশেষে সেই সারিটিতে একটি রৈখিক যুক্ত হবে। কোর অ্যালগরিদম বাস্তবায়নের আলোকে এটি সত্যই উন্মাদ।
Jonan Georgiev

10

আমি জুলিয়ান বাক্নালকে তার ব্লগে এখানে পেয়েছি - http://www.boyet.com/Articles/PriorityQueueCSharp3.html

আমরা এটিকে কিছুটা সংশোধন করেছি যাতে কাতারে নিম্ন-অগ্রাধিকারের আইটেমগুলি শেষ পর্যন্ত শীর্ষে "বুদ্বুদ-আপ" হয়ে যায়, যাতে তারা অনাহারে ভোগেন না।


9

নেট জন্য মাইক্রোসফ্ট সংগ্রহে উল্লিখিত হিসাবে , মাইক্রোসফট .NET ফ্রেমওয়ার্কের মধ্যে 2 অভ্যন্তরীণ অগ্রাধিকারকুই ক্লাস লিখেছেন (এবং অনলাইনে ভাগ করেছেন) । তাদের কোড চেষ্টা করে দেখুন।

সম্পাদনা: @ ম্যাথুসাম-মিউটের মন্তব্য হিসাবে, মাইক্রোসফ্টের অভ্যন্তরীণ অগ্রাধিকারের একটি ক্লাসে একটি বাগ রয়েছে (এসও সম্প্রদায় অবশ্যই এর জন্য সংশোধন করেছে) মাইক্রোসফ্টের অভ্যন্তরীণ অগ্রাধিকারের কিউ <টি>?


10
: একটি বাগ এখানে বাস্তবায়নের এক পাওয়া যায়নি stackoverflow.com/questions/44221454/...
MathuSum Mut

ওহ! আমি দেখতে পাচ্ছি যে PriorityQueue<T>মাইক্রোসফ্টের ভাগ করা উত্সে এই সমস্ত শ্রেণি internalঅ্যাক্সেস সুনির্দিষ্ট হিসাবে চিহ্নিত করা হয়েছে । সুতরাং এগুলি কেবল কাঠামোর অভ্যন্তরীণ কার্যকারিতা দ্বারা ব্যবহৃত হয়। এগুলি কেবলমাত্র windowsbase.dll# সি প্রকল্পে উল্লেখ করে সাধারণ ব্যবহারের জন্য উপলব্ধ নয় । একমাত্র উপায় হ'ল ভাগ করা উত্সটি কোনও শ্রেণিবদ্ধ ফাইলের মধ্যেই প্রকল্পে অনুলিপি করা।
আরবিটি


7
class PriorityQueue<T>
{
    IComparer<T> comparer;
    T[] heap;
    public int Count { get; private set; }
    public PriorityQueue() : this(null) { }
    public PriorityQueue(int capacity) : this(capacity, null) { }
    public PriorityQueue(IComparer<T> comparer) : this(16, comparer) { }
    public PriorityQueue(int capacity, IComparer<T> comparer)
    {
        this.comparer = (comparer == null) ? Comparer<T>.Default : comparer;
        this.heap = new T[capacity];
    }
    public void push(T v)
    {
        if (Count >= heap.Length) Array.Resize(ref heap, Count * 2);
        heap[Count] = v;
        SiftUp(Count++);
    }
    public T pop()
    {
        var v = top();
        heap[0] = heap[--Count];
        if (Count > 0) SiftDown(0);
        return v;
    }
    public T top()
    {
        if (Count > 0) return heap[0];
        throw new InvalidOperationException("优先队列为空");
    }
    void SiftUp(int n)
    {
        var v = heap[n];
        for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2];
        heap[n] = v;
    }
    void SiftDown(int n)
    {
        var v = heap[n];
        for (var n2 = n * 2; n2 < Count; n = n2, n2 *= 2)
        {
            if (n2 + 1 < Count && comparer.Compare(heap[n2 + 1], heap[n2]) > 0) n2++;
            if (comparer.Compare(v, heap[n2]) >= 0) break;
            heap[n] = heap[n2];
        }
        heap[n] = v;
    }
}

সহজ।


13
কখনও কখনও আমি for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2];

1
@ ডাস্টিনব্রেকেই ব্যক্তিগত স্টাইল :)
শিমু দং

3
তবে অবশ্যই অন্যের কাছে পাঠযোগ্য নয়। কোড লিখন বিবেচনা করুন যা বিকাশকারীর মাথার উপরে ভাসমান কোনও প্রশ্ন চিহ্ন ছেড়ে যায় না।
আলজাইমার

3

জাভা সংগ্রহের ফ্রেমওয়ার্কে জাভা প্রয়োগের (java.util.PriorityQueue) গায়ে জাভা থেকে সি # অনুবাদক ব্যবহার করুন, বা আরও বুদ্ধিমানভাবে অ্যালগরিদম এবং কোর কোডটি ব্যবহার করুন এবং এটি আপনার নিজের তৈরির একটি সি # শ্রেণিতে প্লাগ করুন যা সি # সংগ্রহের কাঠামোর সাথে মেনে চলে ক্যু, বা কমপক্ষে সংগ্রহের জন্য এপিআই।


এটি কাজ করে, তবে দুর্ভাগ্যক্রমে IKVM জাভা জেনেরিকগুলি সমর্থন করে না, সুতরাং আপনি ধরণের সুরক্ষা হারাবেন।
যান্ত্রিক শামুক

8
"জাভা জেনেরিক্স" বলে কোনও জিনিস নেই যখন আপনি সংকলিত জাভা বাইটকোড নিয়ে কাজ করছেন। আইকেভিএম এটি সমর্থন করতে পারে না।
চিহ্নিত করুন

3

AlgoKit

আমি নামক একটি ওপেন সোর্স লাইব্রেরি লিখেছিলেন AlgoKit উপলব্ধ মাধ্যমে NuGet । এতে রয়েছে:

  • অন্তর্নিহিত ডি-আরি হিপস (অ্যারেহ্যাপ),
  • দ্বিপদী স্তূপ ,
  • গাদা পেয়ারিং

কোডটি ব্যাপকভাবে পরীক্ষা করা হয়েছে। আমি অবশ্যই চেষ্টা করে দেখুন।

উদাহরণ

var comparer = Comparer<int>.Default;
var heap = new PairingHeap<int, string>(comparer);

heap.Add(3, "your");
heap.Add(5, "of");
heap.Add(7, "disturbing.");
heap.Add(2, "find");
heap.Add(1, "I");
heap.Add(6, "faith");
heap.Add(4, "lack");

while (!heap.IsEmpty)
    Console.WriteLine(heap.Pop().Value);

কেন এই তিনটি গাদা?

বাস্তবায়নের সর্বোত্তম পছন্দটি দৃ strongly়ভাবে ইনপুট-নির্ভর - যেমন লারকিন, সেন, এবং টারজান অগ্রাধিকারের সারিগুলির ব্যাক-টু- বেসিক্স অনুশীলনমূলক গবেষণায় দেখায় , আরএক্সিভি: 1403.0252v1 [সিএসডিডি] । তারা অন্তর্নিহিত ডি-অ্যারি হ্যাপস, জুটিিং হ্যাপস, ফিবোনাচি হিপস, দ্বিপদী হ্যাপস, স্পষ্টত ডি-অ্যারি হ্যাপস, র‌্যাঙ্ক-জুড়ির গাদা, ভূমিকম্পের হিপস, লঙ্ঘনের হিপস, র‌্যাঙ্ক-রিল্যাক্সড দুর্বল হিপস এবং কঠোরভাবে ফিবোনাচি হ্যাপ পরীক্ষা করেছে।

অ্যালগোকিটে তিন ধরণের হ্যাপ রয়েছে যা পরীক্ষিতদের মধ্যে সবচেয়ে কার্যকর বলে মনে হয়েছিল।

পছন্দের ইঙ্গিত

তুলনামূলকভাবে অল্প সংখ্যক উপাদানগুলির জন্য, আপনি সম্ভবত অন্তর্ভুক্ত হিপস, বিশেষত চতুর্ভুজ হিপস (অন্তর্ভুক্ত 4-অ্যারি) ব্যবহার করতে আগ্রহী হবেন। বৃহত্তর হ্যাপ আকারে অপারেটিংয়ের ক্ষেত্রে, দ্বিপদী হিপস এবং জোড়া জোড়গুলির মতো মোড়ক কাঠামোগুলি আরও ভাল সম্পাদন করা উচিত।



1

আমার সম্প্রতি একই সমস্যা হয়েছিল এবং এর জন্য একটি নিউগেট প্যাকেজ তৈরি শেষ করেছি ।

এটি একটি স্ট্যান্ডার্ড হ্যাপ-ভিত্তিক অগ্রাধিকার সারি প্রয়োগ করে। এটিতে ছাত্রলীগের সংগ্রহগুলির সমস্ত সাধারণ চমত্কার বৈশিষ্ট্যও রয়েছে: ICollection<T>এবং IReadOnlyCollection<T>বাস্তবায়ন, কাস্টম IComparer<T>সহায়তা, প্রাথমিক ক্ষমতা নির্দিষ্ট করার ক্ষমতা এবং ডিবাগের DebuggerTypeProxyসাহায্যে সংগ্রহটি কাজ করা আরও সহজ করার জন্য একটি ।

প্যাকেজের একটি ইনলাইন সংস্করণ রয়েছে যা কেবলমাত্র আপনার প্রকল্পে একটি একক .cs ফাইল ইনস্টল করে (যদি আপনি বাহ্যিকভাবে দৃশ্যমান নির্ভরতা গ্রহণ করতে চান তবে দরকারী)।

আরও তথ্য গিথুব পৃষ্ঠায় পাওয়া যায় ।


1

একটি সাধারণ সর্বোচ্চ গাদা বাস্তবায়ন He

https://github.com/bharathkumarms/AlgorithmsMadeEasy/blob/master/AlgorithmsMadeEasy/MaxHeap.cs

using System;
using System.Collections.Generic;
using System.Linq;

namespace AlgorithmsMadeEasy
{
    class MaxHeap
    {
        private static int capacity = 10;
        private int size = 0;
        int[] items = new int[capacity];

        private int getLeftChildIndex(int parentIndex) { return 2 * parentIndex + 1; }
        private int getRightChildIndex(int parentIndex) { return 2 * parentIndex + 2; }
        private int getParentIndex(int childIndex) { return (childIndex - 1) / 2; }

        private int getLeftChild(int parentIndex) { return this.items[getLeftChildIndex(parentIndex)]; }
        private int getRightChild(int parentIndex) { return this.items[getRightChildIndex(parentIndex)]; }
        private int getParent(int childIndex) { return this.items[getParentIndex(childIndex)]; }

        private bool hasLeftChild(int parentIndex) { return getLeftChildIndex(parentIndex) < size; }
        private bool hasRightChild(int parentIndex) { return getRightChildIndex(parentIndex) < size; }
        private bool hasParent(int childIndex) { return getLeftChildIndex(childIndex) > 0; }

        private void swap(int indexOne, int indexTwo)
        {
            int temp = this.items[indexOne];
            this.items[indexOne] = this.items[indexTwo];
            this.items[indexTwo] = temp;
        }

        private void hasEnoughCapacity()
        {
            if (this.size == capacity)
            {
                Array.Resize(ref this.items,capacity*2);
                capacity *= 2;
            }
        }

        public void Add(int item)
        {
            this.hasEnoughCapacity();
            this.items[size] = item;
            this.size++;
            heapifyUp();
        }

        public int Remove()
        {
            int item = this.items[0];
            this.items[0] = this.items[size-1];
            this.items[this.size - 1] = 0;
            size--;
            heapifyDown();
            return item;
        }

        private void heapifyUp()
        {
            int index = this.size - 1;
            while (hasParent(index) && this.items[index] > getParent(index))
            {
                swap(index, getParentIndex(index));
                index = getParentIndex(index);
            }
        }

        private void heapifyDown()
        {
            int index = 0;
            while (hasLeftChild(index))
            {
                int bigChildIndex = getLeftChildIndex(index);
                if (hasRightChild(index) && getLeftChild(index) < getRightChild(index))
                {
                    bigChildIndex = getRightChildIndex(index);
                }

                if (this.items[bigChildIndex] < this.items[index])
                {
                    break;
                }
                else
                {
                    swap(bigChildIndex,index);
                    index = bigChildIndex;
                }
            }
        }
    }
}

/*
Calling Code:
    MaxHeap mh = new MaxHeap();
    mh.Add(10);
    mh.Add(5);
    mh.Add(2);
    mh.Add(1);
    mh.Add(50);
    int maxVal  = mh.Remove();
    int newMaxVal = mh.Remove();
*/

-3

একটি নিম্নলিখিত বাস্তবায়ন PriorityQueueব্যবহারসমূহ SortedSetসিস্টেম লাইব্রেরি থেকে।

using System;
using System.Collections.Generic;

namespace CDiggins
{
    interface IPriorityQueue<T, K> where K : IComparable<K>
    {
        bool Empty { get; }
        void Enqueue(T x, K key);
        void Dequeue();
        T Top { get; }
    }

    class PriorityQueue<T, K> : IPriorityQueue<T, K> where K : IComparable<K>
    {
        SortedSet<Tuple<T, K>> set;

        class Comparer : IComparer<Tuple<T, K>> {
            public int Compare(Tuple<T, K> x, Tuple<T, K> y) {
                return x.Item2.CompareTo(y.Item2);
            }
        }

        PriorityQueue() { set = new SortedSet<Tuple<T, K>>(new Comparer()); }
        public bool Empty { get { return set.Count == 0;  } }
        public void Enqueue(T x, K key) { set.Add(Tuple.Create(x, key)); }
        public void Dequeue() { set.Remove(set.Max); }
        public T Top { get { return set.Max.Item1; } }
    }
}

6
সাজানোসেট.এড যোগ করুন ব্যর্থ হবে (এবং মিথ্যা প্রত্যাবর্তন করবে) যদি আপনি ইতিমধ্যে যে আইটেমটি যুক্ত করার চেষ্টা করছেন তেমন একই "অগ্রাধিকার" সহ সেটে কোনও আইটেম ইতিমধ্যে রয়েছে। সুতরাং ... যদি A.Compare (B) == 0 এবং A ইতিমধ্যে তালিকায় থাকে তবে আপনার অগ্রাধিকার কুইউ.এনকু ফাংশনটি নিঃশব্দে ব্যর্থ হবে।
জোসেফ

কি ব্যাখ্যা করতে মন T xএবং K key? আমি অনুমান করছি এটি সদৃশকে অনুমতি দেওয়ার জন্য একটি কৌশল T xএবং আমার একটি অনন্য কী (যেমন ইউআইডি) তৈরি করতে হবে?
থারিক নগ্রোহোতোমো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.