python - 为调度程序使用堆
问题描述
在此处的 Python 官方文档中,提到了以下关于堆的内容:
这种排序的一个很好的特性是您可以在排序进行时有效地插入新项目,前提是插入的项目不比您提取的最后一个第 0 个元素“更好”。这在模拟环境中特别有用,其中树包含所有传入事件,“获胜”条件意味着最小的预定时间。当一个事件调度其他事件执行时,它们被调度到未来,因此它们可以很容易地进入堆
我只能想到以下简单的算法来实现使用堆的调度程序:
# Priority queue using heap
pq = []
# The first element in the tuple represents the time at which the task should run.
task1 = (1, Task(...))
task2 = (2, Task(...))
add_task(pq, task1)
add_task(pq, task2)
# Add a few more root-level tasks
while pq:
next_task = heapq.heappop()
next_task.perform()
for child_task in next_task.get_child_tasks():
# Add new child tasks if available
heapq.heappush(pq, child_task)
在这种情况下,排序甚至出现在哪里?
即使未来的子任务有“过去”的时间,这个算法仍然可以正常工作。
那么,为什么作者警告儿童事件只安排在未来?
这是什么意思:
您可以在排序进行时有效地插入新项目,前提是插入的项目不比您提取的最后一个第 0 个元素“更好”。
解决方案
堆用作优先级队列的数据结构,实际上最小堆的基本原理是您在顶部具有最低优先级(或者在最大堆中,顶部具有较高优先级)。因此,您始终可以提取最低或最高元素而无需搜索它。
您可以随时在排序期间插入新元素,尝试查看 heapSort 的工作原理。每次你需要建立你的堆,然后提取最大值并将其放在数组的末尾,在你减少 heap.length 1之后。如果你已经对一些数字进行了排序:[..., 13, 15, 16]
并且你插入一个更高的新数字提取的最后一个元素(13 = 0'th 元素)你会得到一个错误的解决方案,因为你会提取新的数字,但你不会把它放在正确的位置:[1, 2, 5, 7, 14, 13, 15, 16]
. 它将被放置在 13 之前,因为它交换了 heap.length 位置上的元素。这显然是错误的,因此您只能插入少于第 0 个元素的元素。
推荐阅读
- react-native - 解密,md5在本机反应中加密数据
- python - Line-to-line intersect with pygame's inverted y-axis
- dapper - 如何使用 Entity Framework Core 或 Dapper 批量更新表的列?
- angular - 在嵌套对象数组的情况下,如何在 Angular 组件中使用数据过滤?
- oracle - Spring boot JPA CrudRepository 用于不同的 oracle 模式
- python - 递归地在嵌套字典中循环浮点数
- karate - 如何使用来自功能的 JSON 响应数据集来构建多个新端点
- mysql - Docker Alpine:加载 MySQLdb 模块时出错
- excel - 如何通过 Excel VBA 更改 CATIA V5 中的渲染样式?
- python - 在 Python 中确定 Windows 上共享驱动器的网络路径