繁体   English   中英

创建一个最小优先级队列,其中包含C ++中的不同类型的事件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM