【问题标题】:Search algorithm (with a sort algorithm already implemented)搜索算法(已经实现了排序算法)
【发布时间】:2011-02-22 11:10:07
【问题描述】:

我正在做一个 Java 应用程序,但我面临一些与性能有关的疑问。

我有一个 PriorityQueue,它保证我删除的元素是具有更高优先级的元素。该 PriorityQueue 具有类 Event 的实例(实现 Comparable 接口)。每个事件都与一个实体相关联。

优先级队列的大小可能很大,而且我必须经常删除与实体关联的事件。

现在我使用迭代器来运行所有的优先队列。但是我发现它很重,我想知道是否有更好的替代方法来搜索和删除与实体“xpto”相关的事件。

有什么建议吗?

谢谢!

【问题讨论】:

    标签: java algorithm search sorting


    【解决方案1】:

    有几个选项:

    1. 能否使用单独的队列 每个实体?所以当你得到一个 “xpto”的事件,您将其放入 XptoPriorityQueue?这将减少 每个队列的大小,但可以 也导致一些其他的管理 问题。
    2. 您是否正在删除事件 处理它们的特定实体 早点?如果是这样,那么您应该简单地 给这些实体更高的 优先级并将它们撞到顶部 队列。
    3. 您是否正在删除事件 让特定实体删除它们 从队列中忽略它们?如果 所以他们要么永远不会得到 进入队列或应该得到一个较低的 优先级。

    【讨论】:

    • 感谢您的建议!它的第三个选项。此应用程序与演化编程有关。我有 3 种事件:繁殖、变异和死亡。这三种事件随机添加到优先级队列中(优先级由事件的时间定义)。但是,当发生死亡事件时,必须删除优先级队列中所有优先级较低的事件。在我的情况下,防止在死亡事件之前添加其他事件并不是那么简单,我认为......
    • 必须将它们从队列中删除,还是不应该对其进行处理???如果您从队列中拉出一个“已死”的事件,只需将其丢弃并获取下一个。当然,这假设有一种方法可以检查任何给定事件是否已死亡。
    • 必须删除事件。否则,priorityqueue 将是巨大的,会产生“内存不足”的风险,并且从 PriorityQueue 添加或轮询事件将花费更多时间。
    • 你可以做的是保留少量的额外状态(对于“死亡实体”)并密切关注优先队列的大小。当从队列中获取死亡实体的事件时,忽略它并让他下一个。如果队列达到预定义的限制(或者如果您获得足够数量的现已死亡的实体),则扫描整个优先级队列并删除与死亡实体相关的所有事件。
    【解决方案2】:

    由于remove 是线性时间运算,因此您将获得 O(N*N) 的性能。

    如果您将PriorityQueue 子类化并创建一个结合了迭代器和remove 方法的新方法(也许命名为removeIf),那么您可以将其减少到O(N log(N))。

    【讨论】:

      【解决方案3】:

      我建议你创建一个由 PriorityQueue 和 Set 组成的类,操作如下:

      • 要添加元素,请将其从 Set 中移除,如果不存在,请将其添加到 PriorityQueue。
      • 要移除元素,请将其添加到 Set。
      • 要使元素出列,请从 PriorityQueue 中出列元素,直到未出列的元素不存在于 Set 中。从 Set 中移除所有未排队的元素。

      【讨论】:

        【解决方案4】:

        几个想法:

        1. 使用按实体键排序的treap 实现您的优先级队列。如果键是随机分布的,那么您应该能够在 O(log n) 时间内删除元素。
        2. 维护一个单独的实体到队列中当前事件的映射。无需立即从队列中删除事件,只需在 Event 对象上翻转一点,指示当它到达队列的前端时应该忽略它。

        【讨论】:

          【解决方案5】:

          听起来您需要实现一个增强的优先级队列。特别是,您需要 O(logN) 删除时间。您可以通过保留两个数据结构来做到这一点,一个事件数组,基本上是 binary heap 存储您的优先级队列,以及一个从事件到该事件在数组中的偏移量的 HashMap(或者可能从实体到偏移量列表该数组中的事件数)。

          然后您可以像处理优先级队列一样执行正常的堆操作,您只需在每次移动事件时更新哈希映射映射。要删除一个事件,请在哈希表中查找该事件的索引,并从该索引开始对堆执行删除操作。

          【讨论】:

            猜你喜欢
            • 2012-04-26
            • 2018-12-04
            • 1970-01-01
            • 1970-01-01
            • 2017-01-06
            • 2016-12-20
            • 1970-01-01
            • 1970-01-01
            • 2014-08-30
            相关资源
            最近更新 更多