[英]Create a Min Priority Queue contain different types of event in C++
class Event
{
// Overloading the comparison operators
friend bool operator < (const Event& e1, const Event& e2);
friend bool operator == (const Event& e1, const Event& e2);
public:
Event() {};
enum EvtType {arrival_1, arrival_2, arrival_3, arrival_4, arrival_5, arrival_6};
Event(EvtType type, double etime):
_type(type), _etime(etime) {}
EvtType get_Type()
{
return _type;
}
double get_time()
{
return _etime;
}
protected:
EvtType _type;
double _etime;
};
bool operator < (const Event& e1, const Event& e2)
{
return e2._etime < e1._etime;
}
bool operator == (const Event& e1, const Event& e2)
{
if(e1._etime != e2._etime)return false;
if(e1._type == (Event::arrival_2 && Event::arrival_3 && Event::arrival_4 && Event::arrival_5 && Event::arrival_6)) return true;
return false;
}
priority_queue <Event> FEL;
我创建了一个名为“ Event”的类,其中包含几种类型的事件和发生时间。 此后,我想创建一个优先级队列“ FEL”来包含这些事件及其时间。 但是,一般而言,优先级队列始终对事件库中的所有最大值进行排序。
如何基于最小值对这些事件进行排序,以便在我调用FEL.top()时,将以最短的时间获取事件。
我试图通过使用布尔运算符来解决此问题。 但这仍然有问题。 任何人请帮助解决此问题将不胜感激。
非常感谢你
std::priority_queue
容器适配器是最大队列构造。 它使用“较少”比较器以始终将最大项目放在首位的方式对排队的项目进行排序。 因此,如果您想首先拥有最小的物品,则需要一个比较器,该比较器的作用与您最初看似自然的相反。
一个简单的例子,假设你有一个矢量int
值,你希望他们优先从最大到最小 。 这是std::priority_queue<int>
的自然默认操作操作。 它使用std::less<int>
来确定项目的顺序(先后,后继),并根据这些结果确保最大的项目首先出现在队列中。 考虑以下示例,该示例创建两个int
队列,一个使用std::less<int>
,另一个使用std::greater<int>
进行比较:
#include <iostream>
#include <algorithm>
#include <queue>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<> dist(1,10);
std::priority_queue<int, std::vector<int>, std::less<int>> q1;
std::priority_queue<int, std::vector<int>, std::greater<int>> q2;
for (int i=0; i<20; ++i)
{
int value = dist(rng);
q1.push(value);
q2.push(value);
}
std::cout << "q1: ";
for (; !q1.empty(); q1.pop())
std::cout << q1.top() << ' ';
std::cout << '\n';
std::cout << "q2: ";
for (; !q2.empty(); q2.pop())
std::cout << q2.top() << ' ';
std::cout << '\n';
}
输出 (可变)
q1: 10 10 8 8 8 7 6 6 5 5 5 4 4 4 3 3 3 2 1 1
q2: 1 1 2 3 3 3 4 4 4 5 5 5 6 6 7 8 8 8 10 10
如您所见,在确定排序时,使用“更大”比较器作为较少操作的队列将提供您想要的结果。 我们只需要将这种东西放入您的队列及其Event
类型中即可
您需要一个与默认顺序相反的比较器:
#include <iostream>
#include <algorithm>
#include <queue>
class Event
{
public:
enum EvtType { arrival_1, arrival_2, arrival_3, arrival_4, arrival_5, arrival_6 };
Event(EvtType type = arrival_1, double etime = 0.0)
: _type(type)
, _etime(etime)
{}
EvtType get_Type() const { return _type; };
double get_Time() const { return _etime; }
protected:
EvtType _type;
double _etime;
};
struct EventLess
{
bool operator()(const Event& lhs, const Event& rhs) const
{
return (lhs.get_Time() > rhs.get_Time());
}
};
int main()
{
std::priority_queue<Event, std::vector<Event>, EventLess> q;
q.push(Event(Event::arrival_1, 3.0));
q.push(Event(Event::arrival_2, 2.0));
q.push(Event(Event::arrival_3, 1.0));
q.push(Event(Event::arrival_1, 1.0));
q.push(Event(Event::arrival_2, 2.0));
q.push(Event(Event::arrival_3, 3.0));
while (!q.empty())
{
const Event& e = q.top();
std::cout << e.get_Type() << ' ' << e.get_Time() << '\n';
q.pop();
}
}
输出量
2 1
0 1
1 2
1 2
0 3
2 3
请注意,时间值(第二个)从最小到最大顺序排列。 这是因为我们的比较器EventLess
表示“时间EventLess
项目比时间较小的项目“少”,并且队列自然会将这些项目推入队列,而不是将其提升到顶部。 使得这项工作简单的是:
struct EventLess
{
bool operator()(const Event& lhs, const Event& rhs) const
{
return (lhs.get_Time() > rhs.get_Time());
}
};
在这里,我们告诉调用者(队列适配器)给定两个元素,时间值较大的元素应该比时间值较小的元素“更少”。 然后,队列将商品从大到小排序。
我认为您了解自定义比较的必要性。 我只是不认为您了解std::priority_queue
工作方式。 这是最大队列。 您只需要说服它,您对max
的定义就会有所不同。
您不能仅基于显示的代码首先创建std::priority_queue<Event>
。 Event
未实现std::priority_queue<Event>
所需的<
运算符。
您已经定义了<
运算符,但是未将其包含在显示的代码中,或者您必须已经将可选的比较器类传递给现有的std::priority_queue
,该类为所有Event
指定严格的弱排序。
在任何一种情况下,只需更改适当的比较函数即可按所需顺序比较Event
。
您可以向std::priority_queue
提供自定义比较器类型参数。 但是在此之前,让我们为您的Event
类定义operator >
:
bool Event::operator>(Event const& other) {
return _etime > other._etime;
}
您还可以按照与其他运算符相同的方式定义它。 现在,您的队列类型变为:
std::priority_queue<Event, std::vector<Event>, std::greater<Event>> FEL;
这样可以将时间戳为_etime
最低的Event
对象放在顶部。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.