コードを作成するにはさまざまな方法があります。たとえば、あなたはrich comparison operator methodsの一部を実装することで、あなたのアイテムが注文可能にする(そしておそらく、残りを実装するためにfunctools.total_ordering
を使用)できます。
@functools.total_ordering
class multiNode:
def __init__(self, keyValue):
self.__key = keyValue
def setKey(self, keyValue):
self.__key = keyValue
def getKey(self):
return self.__key
def __eq__(self, other):
if not isinstance(other, multiNode):
return NotImplemented
return self.__key == other.__key
def __lt__(self, other):
if not isinstance(other, multiNode):
return NotImplemented
return self.__key < other.__key
これはあなたのコードの作業を行いますが、あなたをreheapifyすることは非常に効率的ではないかもしれませんキュー内にノードを変更するたびに、特にキューに多数のノードがある場合は、キューに格納されます。キューエントリを削除したりヒーププロパティに違反することなくキューエントリを無効にできるように、キューの周りに余分なロジックを書く方が良いでしょう。その後、更新する必要があるアイテムがある場合は、古いエントリを無効にして、新しい優先度の新しいアイテムを追加します。
ディクショナリを使用してノードインスタンスから[pritority, node]
リストにマップする、すばやく実装された実装です。ノードの優先度が更新されると、辞書がチェックされ、リストの一部のnode
がNone
に設定されます。無効なエントリは、ノードをキューの前面からポップするときに無視されます。
queue = []
queue_register = {}
def add_to_queue(node)
item = [node.getKey(), node]
queue.heappush(queue, item)
queue_register[node] = item
def update_key_in_queue(node, new_key):
queue_register[node][1] = None # invalidate old item
node.setKey(new_key)
add_to_queue(node)
def pop_from_queue():
node = None
while node is None:
_, node = heapq.heappop(queue) # keep popping items until we find one that's valid
del queue_register[node] # clean up our bookkeeping record
return node
これをテストして、プログラムの実際のキューの使用が速いかどうかを確認することができます。 (あなたがあなたの質問にについて尋ねていたものとは無関係な)自分のmultiNode
クラスについて
数最終ノート:
あなたは非常にPython的ではないクラスでやっているものがいくつかあります。まず、Pythonの最も一般的な命名規則では、クラスにはCapitalizedNames
、それ以外のすべての変数(すべての種類、関数、モジュールの変数)にはlower_case_names_with_underscores
が使用されています。
__key
の二重先頭アンダースコアを使用する別の問題。二重先頭の(そして末尾ではない)不要コードは、Pythonの名前マングリングシステムを呼び出します。これは、変数をプライベートにする方法として意図されているように思えるかもしれませんが、実際にはそうではありません。プロキシオブジェクト(他のオブジェクトの属性を模倣する)やmixinクラス(未知の属性を持つ他の型に継承されるかもしれない)の属性を設定しているときなど、 )。クラス外のコードが、multiNode
クラスの変更された属性__key
に実際にアクセスしたい場合は、_multiNode__key
を使用しても変更できます。何かがであることを暗示するために、をプライベート属性とするには、単一のアンダースコア_key
を使用してください。
それで私の最終的な問題は、key
はおそらく私的ではないはずです。 getX
とsetX
メソッドを使用してプライベートインスタンス変数を変更するのは、非常にPythonicではありません。属性がクラスのパブリックAPIの一部であることを文書化し、他のコードがそのAPIに直接アクセスできるようにすることは、はるかに一般的です。後でアトリビュートが参照または変更されたときに何か面白くする必要があると判断した場合は、property
記述子を使用して、属性アクセスをgetterおよびsetter関数の呼び出しに自動的に変換できます。後で属性APIの実装を変更する方法はないため、他のプログラミング言語は通常、パブリック属性ではなくゲッターとセッターで始まります。だからとにかく、あなたのクラスの__init__
をself.key = keyValue
に設定し、setKey
とgetKey
を完全に取り除くようにしましょう!
現在、あなたが書いたことに間違いがありますか? –
タイプは提供されたコードでは解決できません。 'heapq.heapify(queue)'は型エラーを出し、実行しません。私は型が注文可能であるかのように動作するソリューションを探しています – LBaelish
あなたのクラスを注文可能にしない理由がありますか? 'def __lt __(self、other):自己を返します.__ key
Blckknght