日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

《Python Cookbook 3rd》笔记(1.5):实现一个优先级队列

發布時間:2023/12/13 python 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《Python Cookbook 3rd》笔记(1.5):实现一个优先级队列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

實現一個優先級隊列

問題

怎樣實現一個按優先級排序的隊列?并且在這個隊列上面每次pop操作總是返回優先級最高的那個元素。

解法

下面的類利用 heapq 模塊實現了一個簡單的優先級隊列:

import heapqclass PriorityQueue:def __init__(self):self._queue = []self._index = 0def push(self, item, priority):heapq.heappush(self._queue, (-priority, self._index, item))self._index += 1def pop(self):return heapq.heappop(self._queue)[-1]

下面是它的使用方式:

>>> class Item: ... def __init__(self, name): ... self.name = name ... def __repr__(self): ... return 'Item({!r})'.format(self.name) ... >>> q = PriorityQueue() >>> q.push(Item('foo'), 1) >>> q.push(Item('bar'), 5) >>> q.push(Item('spam'), 4) >>> q.push(Item('grok'), 1) >>> q.pop() Item('bar') >>> q.pop() Item('spam') >>> q.pop() Item('foo') >>> q.pop() Item('grok') >>>

仔細觀察可以發現,第一個pop()操作返回優先級最高的元素。另外注意到如果兩個有著相同優先級的元素(foo和grok),pop操作按照它們被插入到隊列的順序返回的。

討論

函數heapq.heappush()和
heapq.heappop()分別在隊列queue上插入和刪除第一個元素,并且隊列queue保證第一個元素擁有最小優先級。heappop()函數總是返回“最小的”的元素,這就是保證隊列pop操作返回正確元素的關鍵。另外,由于push和pop操作時間復雜度為O(logN),其中N是堆的大小,因此就算是N很大的時候它們運行速度也依舊很快。

在上面代碼中,隊列包含了一個(-priority, index, item)的元組。優先級為負數的目的是使得元素按照優先級從高到低排序。這個跟普通的按優先級從低到高排序的堆排序恰巧相反。

index變量的作用是保證同等優先級元素的正確排序。通過保存一個不斷增加的index下標變量,可以確保元素按照它們插入的順序排序。而且,index變量也在相同優先級元素比較的時候起到重要作用。

為了闡明這些,先假定 Item 實例是不支持排序的:

>>> a = Item('foo') >>> b = Item('bar') >>> a < b Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: Item() < Item() >>>

如果你使用元組(priority, item),只要兩個元素的優先級不同就能比較。但是如果兩個元素優先級一樣的話,那么比較操作就會跟之前一樣出錯:

>>> a = (1, Item('foo')) >>> b = (5, Item('bar')) >>> a < b True >>> c = (1, Item('grok')) >>> a < c Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unorderable types: Item() < Item() >>>

通過引入另外的 index 變量組成三元組(priority, index, item),就能很好的避免上面的錯誤,因為不可能有兩個元素有相同的index值。Python在做元組比較時候,如果前面的比較以及可以確定結果了,后面的比較操作就不會發生了:

>>> a = (1, 0, Item('foo')) >>> b = (5, 1, Item('bar')) >>> c = (1, 2, Item('grok')) >>> a < b True >>> a < c True >>>

如果你想在多個線程中使用同一個隊列,那么你需要增加適當的鎖和信號量機制。

heapq 模塊的官方文檔有更詳細的例子程序以及對于堆理論及其實現的詳細說明。

總結

以上是生活随笔為你收集整理的《Python Cookbook 3rd》笔记(1.5):实现一个优先级队列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。