Algorithm 具有动态项目优先级的优先级队列
我需要实现一个优先级队列,其中队列中某个项目的优先级可以更改,并且队列会自行调整,以便始终以正确的顺序删除项目。我对如何实现这一点有一些想法,但我确信这是一种非常常见的数据结构,因此我希望我可以使用比我更聪明的人的实现作为基础 有谁能告诉我这种优先级队列的名称,让我知道要搜索什么,或者更好的是,给我指一个实现吗?给您,包括的一个实现Algorithm 具有动态项目优先级的优先级队列,algorithm,heap,priority-queue,Algorithm,Heap,Priority Queue,我需要实现一个优先级队列,其中队列中某个项目的优先级可以更改,并且队列会自行调整,以便始终以正确的顺序删除项目。我对如何实现这一点有一些想法,但我确信这是一种非常常见的数据结构,因此我希望我可以使用比我更聪明的人的实现作为基础 有谁能告诉我这种优先级队列的名称,让我知道要搜索什么,或者更好的是,给我指一个实现吗?给您,包括的一个实现 然而,这听起来像是一个家庭作业问题,因此如果是这样,我建议你先尝试自己完成这些想法,如果你在某个地方陷入困境,需要一个指向正确方向的指针,那么可能会参考其他人的实现
然而,这听起来像是一个家庭作业问题,因此如果是这样,我建议你先尝试自己完成这些想法,如果你在某个地方陷入困境,需要一个指向正确方向的指针,那么可能会参考其他人的实现。这样,您就不太可能“偏袒”其他程序员使用的精确编码方法,而更可能理解为什么包含每段代码以及它是如何工作的。有时,执行“复制和粘贴”的等效解释可能有点太诱人了。标准二进制堆支持5个操作(下面的示例假设最大堆):
如您所见,在max堆中,您可以增加任意密钥。在最小堆中,可以减少任意密钥。不幸的是,您不能双向更改密钥,但这样可以吗?如果您需要双向更改密钥,那么您可能需要考虑使用a。我建议您首先尝试头部插入法,以更新优先级:
- 从队列中删除该项目
- 用新的优先级重新插入它
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);
}
}
类项目;
typedef std::多映射优先级队列;
类项目
{
公众:
无效添加(优先级队列和队列);
无效删除();
int getPriority()常量;
无效设置优先级(int优先级);
std::string&accessData();
常量std::string&getData()常量;
私人:
国际优先权;
std::字符串mData;
优先级队列*mQueue;
优先级队列::迭代器斜接器;
};
无效项::添加(优先级队列和队列)
{
mQueue=&queue;
mIterator=queue.insert(std::make_pair(mPriority,this));
}
无效项::删除()
{
mQueue.erase(斜接器);
mQueue=0;
mIterator=priority_queue::iterator();
}
无效项::设置优先级(整数优先级)
{
优先权=优先权;
if(mQueue)
{
优先级队列&queue=*mQueue;
此->删除();
此->添加(队列);
}
}
我正在寻找完全相同的东西
以下是我的一些想法:
但是,官方Java库中似乎没有提供这些算法。因此,我建议您使用java.util.Collections.max/min来做您想做的事情。像其他人建议的那样,这样的优先级队列通常使用二进制堆数据结构来实现,通常使用数组表示,但也可以使用二叉树。实际上,增加或减少堆中元素的优先级并不难。如果知道要在从队列中弹出下一个元素之前更改许多元素的优先级,可以暂时关闭动态重新排序,在堆的末尾插入所有元素,然后在需要弹出元素之前重新排序整个堆(代价是O(n))。关于堆的重要一点是,将数组放入堆顺序只需O(n),而排序只需O(n logn) 我在一个具有动态优先级的大型项目中成功地使用了这种方法
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);
}
}
下面是我的一个参数化模型的实现 谢谢Dav,但这是一个标准优先级队列。如果我向队列中添加了一个项目,并且它的优先级发生了更改(在队列之外),那么队列的顺序可能不正确。换句话说,标准优先级队列仅在将项目添加到队列时对其进行排序,而不是稍后。我需要实现一个队列,随着其项目优先级的更新而更新。另外,这不是一个家庭作业问题,我需要把它作为一些模拟软件的一部分来实现。我对如何实现它有一些想法,但想看看是否有更好的方法。可以在这种情况下,我建议寻找Dijkstra算法的示例实现,该算法(如果以最有效的形式实现)需要一个可重排序的优先级队列,因此可能会有您想要的。请参阅并感谢Matthieu,我曾想过使用这种方法,但由于更新频率太高,无法满足我的需要。我最终使用了一个实现,该实现包括一个字典,将项映射到队列中的索引,然后在队列上有一个方法UpdatePosition(Item Item),该方法查找项索引,然后将其冒泡到新位置。然后,队列会有一个项目注册所针对的事件,以便在优先级发生变化时通知队列。这似乎很有效。如果您首先需要搜索希望增加的元素,我不知道二进制堆如何有效地支持增加密钥。由于堆中没有排序,因此查找元素需要线性时间。您必须有一个引用