Приоритетная очередь с динамическими приоритетами элементов
Мне нужно реализовать очередь приоритетов, где приоритет элемента в очереди может измениться, и очередь настраивается так, чтобы элементы всегда удалялись в правильном порядке. У меня есть некоторые идеи о том, как я мог бы реализовать это, но я уверен, что это довольно распространенная структура данных, поэтому я надеюсь, что смогу использовать реализацию кем-то умнее меня в качестве базы.
может ли кто-нибудь сказать мне имя этого типа очереди приоритетов, чтобы я знал, что искать или, еще лучше, указать мне к реализации?
5 ответов
Я бы предложил сначала попробовать подход head-in, чтобы обновить приоритет:
- удалить элемент из очереди
- повторно вставьте его с новым приоритетом
В C++ это можно сделать с помощью std::multi_map
, главное, что объект должен помнить, где он хранится в структуре, чтобы иметь возможность эффективно удалить самостоятельно. Для повторной вставки это сложно, так как вы не можете предположить, что знаете что-либо о приоритеты.
class Item;
typedef std::multi_map<int, Item*> priority_queue;
class Item
{
public:
void add(priority_queue& queue);
void remove();
int getPriority() const;
void setPriority(int priority);
std::string& accessData();
const std::string& getData() const;
private:
int mPriority;
std::string mData;
priority_queue* mQueue;
priority_queue::iterator mIterator;
};
void Item::add(priority_queue& queue)
{
mQueue = &queue;
mIterator = queue.insert(std::make_pair(mPriority,this));
}
void Item::remove()
{
mQueue.erase(mIterator);
mQueue = 0;
mIterator = priority_queue::iterator();
}
void Item::setPriority(int priority)
{
mPriority = priority;
if (mQueue)
{
priority_queue& queue = *mQueue;
this->remove();
this->add(queue);
}
}
очереди приоритетов, такие как это, обычно реализуются с использованием структуры данных двоичной кучи, как предложил кто-то другой, которая обычно представлена с помощью массива, но также может использовать двоичное дерево. На самом деле нетрудно увеличить или уменьшить приоритет элемента в куче. Если вы знаете, что изменяете приоритет многих элементов до того, как следующий элемент будет извлечен из очереди, вы можете временно отключить динамическое переупорядочение, вставьте все элементы в конце куча, а затем переупорядочить всю кучу(по стоимости O (n)) непосредственно перед тем, как элемент должен быть выскочил. Важно то, что в кучах стоит только O(n) поместить массив в порядок кучи, но o (n log n) отсортировать его.
Я успешно использовал этот подход в большом проекте с динамическими приоритетами.
вот моя реализация параметризованного реализация очереди приоритетов на языке программирования Curl.
стандартная двоичная куча поддерживает 5 операций (пример ниже предполагает максимальную кучу):
* find-max: return the maximum node of the heap
* delete-max: removing the root node of the heap
* increase-key: updating a key within the heap
* insert: adding a new key to the heap
* merge: joining two heaps to form a valid new heap containing all the elements of both.
Как вы можете видеть, в максимальной куче вы можете увеличить произвольный ключ. В куче min вы можете уменьшить произвольный ключ. Вы не можете изменить ключи в обе стороны, к сожалению, но это будет делать? Если вам нужно изменить ключи в обоих направлениях, вы можете подумать об использовании a мин-макс-кучи.
Google имеет ряд ответы для вас, включая реализацию один в Java.
тем не менее, это звучит как что-то, что было бы проблемой домашней работы, поэтому, если это так, я бы предложил сначала попытаться проработать идеи самостоятельно, а затем потенциально ссылаться на чужую реализацию, если вы застряли где-то и нуждаетесь в указателе в правильном направлении. Таким образом, вы с меньшей вероятностью будете "смещены" в сторону точного метода кодирования используется другим программистом и, скорее всего, поймет, почему каждый фрагмент кода включен и как он работает. Иногда может быть слишком заманчиво сделать перефразирующий эквивалент "копировать и вставлять".
Я ищу точно то же самое!
и вот некоторые из моих идей:
- поскольку приоритет элемента продолжает меняться, бессмысленно сортировать очередь перед извлечением элемента.
- Итак, мы должны забыть об использовании очереди приоритетов. И" частично " сортировать контейнер при получении товара.
и выберите один из следующих алгоритмов сортировки STL: раздел б. stable_partition С. nth_element д. partial_sort е. partial_sort_copy Ф. сортировать г. stable_sort
partition, stable_partition и nth_element-алгоритмы сортировки линейного времени, которые должны быть нашими 1-м выбором.
но, похоже, что в официальной библиотеке Java нет этих алгоритмов. В результате я предложу вам использовать java.утиль.Коллекции.макс / мин, чтобы сделать то, что вы хотите.