Du kannst doch einfach, ist nicht schön, ich weiß, ein std::set nehmen und für decreaseKey einfach das Element entfernen und mit neuem Wert einfügen.
Da std::priority_queue nichts anderes sein kann, als ein std::vector mit eingeschränkter Funktion, der auf sich selbst std::make_heap loshetzt, macht es in der Tat vielleicht eher Sinn, das ganze mithilfe eines std::vector zu realisieren.
Das ganze will ich für meinen Wegfindungsalgorithmus verwenden - da ist es von Vorteil einen zusammenhängenden Datentyp zu Grunde zu legen. Bisher habe ich mit
std::set gearbeitet und das ganze läuft ziemlich suboptimal.
Ich werde meine bisherige und meine neue Implementierung zum Schluss mal "gegeneinander" laufen lassen
Ansonsten musst du das Rad wohl wirklich "neu erfinden".
Ich hab inzwischen ein paar Sachen implementiert und hoble noch an der Laufzeit. Damit ich
decrease anwenden kann, brauche ich
Random Access auf meine Knoten. Wenn ich Random Access habe, lässt sich auch
contains() gut implementieren.
Da ich für meine Anwendung 2D-Koordinaten (unsigned int) auf einer begrenzten Map (d.h.
max_width und
max_height) verwende, kann ich prinzipiell über eine bijektive Abbildung (Koordinaten auf den Index, innerhalb der Queue) bauen mit
|
C-/C++-Quelltext
|
1
|
std::size_t index = pos.x + map_size.x * pos.y;
|
sofern alle Positionen stehts innerhalb der MapBounds liegen. Da bijektiv, sollte dieses "Hashing" effektiv kollisionsfrei ablaufen - vorausgesetzt ich habe ein Array zur Speicherung der Abbildungen ("Inhaltsverzeichnis"
) der Art..
|
C-/C++-Quelltext
|
1
|
std::vector<int> pos_to_index; // -1 = not existing
|
mit Größe
map_size.x * map_size.y, so dass ich mit
pos_to_index[hash(pos)] auf den Index innerhalb der eigentlichen
std::vector<Pos> heap zugreifen kann.
Das ganze funktioniert - führt aber dazu, dass ich bei insert, decrease und extract jeweils Buch führen muss... Und im Moment macht mir mein extract (genauer: "heapify" nach dem Enfernen) Sorgen .. aber das wird