【问题标题】:How to work arround a pool of priority queues? And is this the best option here?如何解决优先队列池?这是最好的选择吗?
【发布时间】:2012-05-02 16:44:58
【问题描述】:

这是how to represent priorities的一个后续问题
答案引导我将设计基于Priority Queue ADT

我的问题是我无法弄清楚如何建模这个问题(我了解PQ 的工作原理)。
所以使用我原来的(简单的例子)假设我有PersonAPersonB ...PersonY(表示为类)喜欢各种菜肴PizzasSpaggetiSteak等。
我想找到一种方法来指定应该根据Preference 向人们提供哪道菜(这可能是一个额外的课程,因为在开始问题线程的答案中也建议了朋友)。
我不确定这应该如何建模。我的第一个想法是为每道菜创建一个PriorityQueuePizzaPQSpaggetiPQ 等),将每个队列 all 放入 Persons 并开始从每个队列中移除顶部(作为对这道菜有最大偏好的人)并将Person 从其他队列中删除。此过程按顺序遍历所有队列。
现在虽然在概念上它似乎是正确的(但这不是最好的方法,因为我认为由于过程本身会出现差异),我不认为我走在正确的轨道上,因为

  1. 从其他队列中移除是线性操作(我说的是remove(Object),其中Object 已经被服务Pizza 并且不应再出现在其他队列中)并且会花费 O(N*k) 其中k 是队列的数量(这在我看来 在第一个中添加了很多优先级队列的使用 地点)
  2. 在我看来,我需要一些抽象来处理 “池” 优先队列,我不确定是否真的有这样的数据 结构,我不知道。

我想这个问题可以概括为如何分配作业或如何操作多个队列(也许?)
必须有针对此类问题的标准设计方法。
非常欢迎任何意见

@Thomas 回答后更新:
问题稍微复杂一点。
除了偏好之外,还可能存在其他(一个人的)属性。
例如。 PersonAPersonB 都更喜欢牛排而不是其他任何菜肴。但是PersonA 有高胆固醇,PersonB 是一名运动员。以某种方式考虑到这些属性,那么PersonB 应该得到牛排。也许PersonA 最终可能会得到其他结果。
这就是我最初想到PQs的菜的原因

【问题讨论】:

  • 当您提到:“在每个队列中加入所有人员”时,您的意思是每个人都会在每个队列中吗?如果是这样,为什么,它的用例是什么?为什么不只将人们添加到他们感兴趣的菜品队列中?
  • @Brady:好点子。我要提到更糟糕的情况,即所有人都对所有菜肴感兴趣,但对每种菜肴的偏好不同

标签: java algorithm oop design-patterns data-structures


【解决方案1】:

这个应用程序是否可以在多线程环境中执行?如果是这样,我有一些想法可以提供帮助。

  1. 创建一个调度线程,其任务是获取一个 Person 对象并将其分配给 PQ。假设一个人应该只在 1 个 PQ 上,这有助于解决您从上述其他 PQ 中删除人的问题。这会将 Person 应放置在何处的逻辑(和 CPU 处理时间)从代码的 PQ 执行部分移开,从而使 PQ 更具凝聚力并降低其与 Person 的耦合。如果一个人可能在多个 PQ 上,或者您想将他们从一个 PQ 移动到另一个 PQ 等,这应该在调度程序代码中执行。

  2. 如果 PQ 多于可用线程,则为 PQ 创建一个线程池,否则只需为每个 PQ 创建一个线程。这样您就不必担心如何迭代 PQ 和可能的 PQ 饥饿。每个线程处理 PQ 和 Person 对象的代码都是相同的。

即使您不使用多线程模型,我也会考虑让 Person 对象从 PQ 知道的 PQitem 对象继承,因此 PQ 不必知道有关 Person 对象的任何信息,可能是这样的: (对不起 c++,但我想你明白了)

class PQitem
{
public:
    virtual void execute() = 0;
    virtual void getPriority() = 0;
private:
    // PQ specific stuff here
};

class Person : public PQitem
{
public:
    void execute() { /* logic executed when taken off the PQ */ }
    void getPriority() { /* logic used to determine where to place this Person */ }
};

【讨论】:

    【解决方案2】:

    这里是java优先队列的链接:http://docs.oracle.com/javase/7/docs/api/

    定义优先级的关键是定义一个比较不同菜肴的比较器。可能您只有 1 个比较器或每个人都有一个比较器来定义他们的偏好。

    【讨论】:

      【解决方案3】:

      把逻辑倒过来怎么样?

      • 将所有菜肴放入地图中
      • 遍历所有人
        • 遍历此人的菜品优先队列
        • 检查这道菜是否还在地图中
        • 如果这道菜在地图上,请将其移除并结束循环

      这样,您将获得一份菜肴地图和一份人员列表以及他们的优先队列(或地图人员->队列)。

      然后迭代将是O(n * m),其中n 是人数,m 是一个人的菜优先队列的长度。

      如果您稍后在菜谱中添加计数器,例如您有 5 个可用的比萨饼,您需要更改的只是在计数器达到 0 时从地图中删除该菜品(当然,在上菜时增加计数器 :))。

      您仍然需要处理以下问题:

      • 谁会开始接受服务?
      • 如果某个人的优先队列中的所有菜肴都不再出现在地图中,会发生什么情况?

      解决这些问题的一种方法可能是从优先排队时间最短的人开始,因为他们更有可能得不到任何菜。这仍然不能解决整个问题(如果两个人只想要披萨而周围只有一个披萨怎么办?)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-02
        • 1970-01-01
        • 1970-01-01
        • 2020-08-19
        • 1970-01-01
        • 2012-02-18
        • 2012-05-07
        • 1970-01-01
        相关资源
        最近更新 更多