【问题标题】:Go multi level priority queue去多级优先队列
【发布时间】:2022-01-07 04:52:36
【问题描述】:

在 Go 中,container/heap 包可以用作 PriorityQueue -- https://pkg.go.dev/container/heap#example-package-PriorityQueue

是否有任何用于多级优先级队列的 Go 包?如果没有,如何自己写?

“多级优先级队列”是我的意思:

  • 任务1:遍历学生的所有分数,找出分数最高的前N名学生。这是典型的 PriorityQueue。
  • 任务2:遍历不同课程学生的所有分数,得到前N门课程的前N高分(假设课程数大于N)。这就是我说的“多级优先级队列”

样本结果可以是

course A: 99 98 98 
course B: 92 90 88
course C: 91 89 87

注意事项,

  1. course D:90 89 88 的前 3 名最高分不在前 3 名课程中。

  2. 在某些情况下,学生的分数可能不足以填满所有前 N 个最高分。例如:

    course E: 85 82
    course F: 83
    course G: 82 80 78
    
  3. 进一步的要求,在现实中,

    • 数据来自于解析超复杂超大的 XML 文件,因此我需要单程遍历 XML 文件,这就是我需要优先级队列的原因。
    • XML文件其实是SQL Server Trace文件,里面包含成百上千条SQL命令(SQL命令就是课程,持续时间就是课程分数),这是我需要优先队列的第二个原因——只跟踪排名靠前的。

【问题讨论】:

  • 什么定义了“前 N 门课程”?
  • 课程按他们获得的最高分排名/排序,然后获得其中的前 N ​​个

标签: algorithm go multidimensional-array priority-queue


【解决方案1】:

您不需要任何奇异的队列结构来解决它。您甚至根本不需要优先级队列,尽管这是执行 select-k 操作的简单方法。 (如果您不需要将输出相对于彼此进行排序,而只是按一些顺序排列在前 N 位,则使用快速选择之类的选择算法会更有效。)

对于任务 2,您只需遍历所有分数,为每门课程建立最高分数。完成此操作后,您会找到前 N 门课程。完成此操作后,再次遍历所有标记,将这些课程的标记过滤到单独的容器中。然后只需在每个选项中执行一个 select-k。

如果您使用优先队列,则此方法的运行时间为O(m + N^2 log N)(其中m 是标记总数),如果您使用高效选择算法,则为O(m + N^2)。后一个时间限制是解决问题的最佳时间,因为需要检查 O(m) 输入并生成 O(N^2) 输出。

【讨论】:

  • 感谢 Sneftel 的回答。我忘了强调一件事(现在我已经更新了OP)- “实际上,数据来自解析一个超级复杂和超级大的XML文件,因此我需要将XML文件放在一个通过,这就是我需要优先级队列的原因。” 另外,对于 select-k 操作,根据您的建议,我在 pkg.go.dev/github.com/wangjohn/quickselect 找到了一个快速选择的 Go 选择算法,它是第三方包,而容器/heap 包是原生包,开箱即用。
  • 总而言之,数据是流式的,如果你能给出一个单通的解决方案,请保留这个好答案并给出另一个解决方案。谢谢。
  • 在线(流式传输)解决方案是为 所有 课程保留单独的优先级队列(最大大小为 N),然后选择前 N 个课程。没有办法使用小于O(c*N) 的额外大小。
  • 感谢您提供所有这些替代解决方案。我需要优先级队列的第二个原因是 “XML 文件实际上是 SQL Server Trace 文件,其中包含数百甚至数千条 SQL 命令”——即我只想跟踪顶级而不是全部。
  • 如果您只是预先解析 XML 文件,那么“数千条 SQL 命令”的存储是微不足道的。不要让问题变得比你必须做的更难。
猜你喜欢
  • 2011-12-20
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 2013-02-13
  • 1970-01-01
  • 2012-02-22
相关资源
最近更新 更多