Was ist die beste standard-Daten-Struktur zu bauen, ein Graph?
zuerst ich bin Anfänger in c++ und ich bin selbst lernen, also bitte ganz einfach Antworten ...
brauche ich um das Programm einen Graphen, die Knoten enthält jeder Knoten-id und eine Liste von Kanten, jede Kante hat, die andere Knoten-id und die Entfernung
was ich Suche ist was soll ich zum erstellen dieser Grafik wenn man bedenkt, dass ich verwenden möchte, dijkstra-Algorithmus, um die kürzesten Weg bilden einem Punkt zum anderen ... so Suche Leistung sollte das wichtigste denke ich !!
gesucht hab ich viel, und ich bin so verwirrt jetzt
vielen Dank im Voraus für die Hilfe
- Start mit stackoverflow.com/questions/471432/...
- vielen Dank für die nützlichen link 🙂 @Mark Lösegeld
Du musst angemeldet sein, um einen Kommentar abzugeben.
Definieren Sie eine
Edge
Struktur wieUnd ein Diagramm erstellen, wie
Dann Zugriff auf alle Kanten kommt aus der vertex -
u
Sie so etwas schreibenKönnen Sie dynamisch hinzufügen neuer Kanten, zum Beispiel eine Kante vom vertex 3. bis 7. mit einem Gewicht von 8:
etc.
Für ungerichtete Graphen sollte man nicht vergessen, hinzuzufügen, die symmetrischen Rand, natürlich.
Sollte dies ok.
Bearbeiten
Die Wahl der base Container (
std::vector
,std::list
,std::map
) ist abhängig vom Anwendungsfall, z.B. was machst du mit den Graphen oft: hinzufügen/entfernen von vertices/edges, einfach durchqueren. Sobald Sie Ihr Diagramm erstellt, entwederstd::list
oderstd::vector
ist gleich gut für den Dijkstra,std::vector
ein bisschen schneller durch sequentielle Zugriffsmuster der Entspannung Bühne.std::vector<>
,std::unordered_map<>
, undstd::unordered_set<>
. Alle anderen Container sind besser als von einem der drei in jedem Fall verwenden, Sie müssen nur richtig eingesetzt werden.Wenn wir Bedenken, dass jede node-id als index. Wir ziehen können eine nxn-matrix der Kanten wie folgt.
Dies kann Ihnen helfen, ziehen die Grafik mit Ecken und Kanten.
Also ein 2D-array ist eine gute Darstellung der matrix.
Ich persönlich würde verwenden eine
std::map<Node*, std::set<Node*> >
. Dies ist sehr nützlich, weil jedes mal, wenn Sie auf einem Knoten können Sie schnell herausfinden, welche Knoten, die Knoten verbunden ist. Es ist auch wirklich einfach zu Iteration über alle Knoten, die, wenn Sie benötigen. Wenn Sie brauchen, um GEWICHTE auf den Kanten, die Sie nutzen könntenstd::map<Node*, std::set< std::pair<int, Node*> > >
. Dies gibt eine wesentlich bessere performance als die Verwendung von Vektoren, insbesondere für große Graphen.std::vector<>
übertrifftstd::map<>
jederzeitstd::vector<>
übertrifftstd::set<>
wenn Sie nicht brauchen, zu bestellen. Beidestd::map<>
undstd::set<>
verlassen Sie sich auf Bäumen intern, und haben somit viel höhere Zuweisung overhead beim breiter Streuung der Daten zu.std::vector<>
verwendet einen zusammenhängenden array intern, und ist somit 1. Speicher effizient, 2. cache-effiziente 3-Allokation effiziente, 4. prefetching freundlich. Wirklich,std::map<>
undstd::set
werden nicht ein Teil der optimizer toolbox.std::map<>
undstd::set<>
würde gewinnen, weil der untere exponentielle Zugriffszeit. Ich wäre offen zu sehen-benchmarks, die beweisen, mich falsch aber.std::vector<>
ist ein single-pointer-dereference-Bedienung auf der Maschinen-Ebene, während die beidenstd::map<>
undstd::set<>
müssen durch einen Baum, was bedeutet, dasslog(n)
- Zeiger-Dereferenzierung Operationen. Besonders für große Daten-sets, wo die Bäume sind tief. Sie können nicht schlagen die Leistung von einer Byte-array im Speicher.