Binärer Baum
Übersicht

![]() |
DAKBetreff: Binärer Baum |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hier wurde letztens erwähnt, dass man da vielleicht was Schnelleres als eine Liste verwenden könnte, da ist mir aufgefallen, dass BMax als Datenstrukturen eigentlich nur eine doppeltverlinkte LinkedList und eine einzige Map unterstützt.
Beide davon eignen sich z.B. für Prioritätswarteschlangen wenig, also habe ich mal so als Übung einen Binären Baum mit Implementierung als Array geschrieben. Das Ganze schaut so aus: BlitzMax: [AUSKLAPPEN] Type TBANode Will man das Testen habe ich hierzu diesen Code geschrieben: BlitzMax: [AUSKLAPPEN] Local Tree:TBinaryArrayTree = TBinaryArrayTree.CreateDefault() Jetzt die große Frage: Wozu braucht man sowas? Die Antwort: Für den Anwender ist dieser Tree sowas Ähnliches wie eine automatisch und effizient selbst sortierende Liste. Mittels Tree.insert(value,key) kann man neue Werte reinschreiben, die dann automatisch an der richtigen Stelle im Tree abgelegt werden. Mit Tree.getMin() kriegt man den Value mit dem niedrigsten Key zurück. Tree.extractMin() tut das Gleiche, nur nimmt es den niedrigsten Wert dann raus. Damit kann man den Tree von unten her abarbeiten. Tree.remove(i) nimmt den i-ten Wert aus dem Tree heraus. Achtung: dieses i ist dabei nicht sortiert! Tree.decreaseKey(i) setzt den Key des i-ten Werts herunter und sortiert den Tree neu. Dabei ist i auch nicht sortiert. Vielleicht kann ja wer was damit machen. |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Edit: Habe einen fehler. Steht unten dran!
Schaut nett aus, aber ich mag das slizen des arrays nicht so. Wäre es nicht sinnvoller exponentiell zu slicen? BlitzMax: [AUSKLAPPEN] Function CreateDefault:TBinaryArrayTree() Macht in meinen augen mehr sinn: Wer wirklich eine solche liste verwenden will, will leistung. Als beispiel: AStar wegfindung. Regelmäßig nach 50 elementen slizen nervt da doch einfach nur ![]() Anyways, gute arbeit. Ich werds mir mal klauben wenn ich darf ![]() EDIT: Ich habe grade aus jux nen astar damit geschrieben *grins* Bzw ich habe den pseudo code dafür zusammengebastelt. Testen geht allerdings nicht, ich kriege einen fehler: Code: [AUSKLAPPEN] Unhandled Exception:Attempt to access field or method of Null object
in der Zeile: BlitzMax: [AUSKLAPPEN] While (location>0 And array[location].key<array[parent(location)].key) in der methode "decreaseKey". Einfügen tue ich ein eigenes Objekt (TAStarNode) mit einem beliegen wert, den wegkosten entsprechend. Egal obs mit hohen oder niedriegen werten ist ![]() Das ganze mit einem if und einem assert zeigt: BlitzMax: [AUSKLAPPEN] Method decreaseKey(location:Int, newkey:Int) Assert wird ausgelöst, weil array[parent(location)] = null ist. Der Location print findet NIEMALS statt, dh direkt beim (2ten?) durchlauf kommt der fehler. Mein erstellen: (new TAStar.Create(....) -> Hier kommt es nicht zu einem fehler. Dist ist die manhatten dist zum ziel, g - Sprich mein Key - entspricht ebenfalls diesem wert.) BlitzMax: [AUSKLAPPEN]
Erst beim ersten durchlauf meines astar algos kommt es zu einem fehler: BlitzMax: [AUSKLAPPEN] 'garnicht vorhanden? Dies ist der fall, wenn ein punkt weder in der offen-liste noch in der geschlossen-liste ist. Anzumerken sei auch, das ich direkt das erste eingefügte objekt wieder entferne. Sprich: Astar wird erstellt: Ich erstelle den binary tree und füge den ersten wegpunkt ein. Astar update entfernt nun den ersten (weil mit niedrigsten kosten) wegpunkt aus deinem tree und prüft die nachbarschaft. Ist ein punkt nicht vorhanden, wird er eingefügt und der fehler tritt auf. Weiteres: Ja ich schreibe viel *grins* Aber ich hab spasseshalber mal die methode remove überarbeitet: BlitzMax: [AUSKLAPPEN] Method remove:TBANode(i:Int) hinzugekommen ist fill:-1. Ob es richtig ist, kann ich nicht sagen. Ich fands nur seltsam, das beim einfügen fill:+1 gemacht wird, bei remove hingegen kein :-1. Beim durchlaufen lassen sind eingie elemente in die liste gekommen. Ein erster fehler trat denn erst wieder bei meinem krams auf ![]() Mach was draus, vielleicht warst du nur müde? ![]() |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Entschuldigt, dieser doppelpost ist sogar absicht.
Ich bitte die Mod's, meine beiden beiträge nicht zu mergen. Vielmehr den oberen zu löschen, wenn DAK ihn gelesen und den Fehler (wenns denn einer war) überarbeitet hat. Dies hier soll nur die pure geilheit seines codes beweisen ![]() scheinbar habe ich das Astar nun doch irgendwie hingekriegt, lag wirklich nur an dem fehler. Um zu beweisen, wie schnell DAK's tree funktioniert, habe ich hier mal den astar, basierend auf eben jenem tree für euch. Ob der Algo nun 100% korrekt umgesetzt ist, weiß ich nicht. Grundlegend sollte aber der AStar gedanke umgesetzt sein. als key nehme ich immer wie potentziellen wegkosten, arbeiten tue ich immer mit extractmin() um die geschwindigkeit zu erhalten. BlitzMax: [AUSKLAPPEN] SuperStrict Das ergebniss lässt sich sehen: Im Debug teilweise max. 100ms suchzeit. Nodebug war 3-4 ms das höchste was ich hatte! Saubere arbeit, DAK *verneig*, ich bin froh, das du dir die mühe gemacht hast *daumen hoch* |
||
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hey, cool, ich hätt eigentlich echt nicht erwartet, dass sich jemand für meinen Code interessieren wird, geschweige denn etwas daraus machen würde! Danke für das Lob^^
Der A* ist aber auch sehr schön gemacht. Ich habs echt versucht, aber länger als 10ms im Nodebug is es nicht geworden. Zum Slicen: Ist natürlich schöner so, wie du's gelöst hast, hast du recht. Die Quelle von der ich mir die Struktur des BinaryArrayTrees geholt hab (Wiki-Pseudocode ![]() Du hast auch recht mit dem Remove, da hab ich das Fill-:1 auch glatt vergessen. Danke! Ich frage mich, ob es sinnvoll wäre, beim Remove auch "herunterzuslicen", wenn das Array zu wenig gefüllt ist. Bin mir nicht sicher, ob das dann aber wieder zu viel Zeit braucht. Ich mein, selbst die JavaVM gibt RAM, den sie mal hat, nicht mehr her. Den DecreaseKey-Bug werde ich mir anschauen, wenn ich etwas mehr Zeit habe (oder hast du den schon gelöst, bei deinem A*-Programm?). Dann werde ich deine Änderungen auch in den ersten Post einfügen, wenn das ok ist für dich. Falls Interesse besteht, könnte ich auch noch ein paar andere schön schnelle Datenstrukturen zusammenschreiben. |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo DAK!
Du, ich habe leider soviel ahnung von solchen trees wie .. naja einfach garkeine. Im groben weiß ich, was stattfindet. Im AStar ding hab ich einfach mal nach gutdünken das -1 eingefügt. Mehr nicht. Dh einzige änderungen bei mir: Defaultgröße ist 64, das slicen findet per shl 1 statt. Beim remove wird fill wieder runtergezählt. Habe versucht, das ganze zu verstehen, aber hab bisher lediglich rausgefunden, das fill die anzahl der objekte angibt, von daher schien es mir logisch, das runtergezählt werden müsste. Das ist dein baby, das musst du fixen ![]() Einen bug in DecreaseKey konnte ich nicht finden - was meinst du damit? Ich würde mich über weitere Listen freuen. Je mehr unterschiedliche umsetzungen ich testen kann, desto besser. Aber leider habe ich nie eine gute liste schreiben können, bin dafür wohl zu doof *grins* Mein jetziges problem ist zb, das ich einen haufen linien gegeneinander vergleichen muss - per line intersect. Eine liste, welche nach koordinaten sortiert ist und trotzdem dynamischer wie ein array, wäre zb praktisch ![]() Ps: Die schnelligkeit des AStar kommt och nur wegen deinem BinaryTree, sei dir dessen bewusst ![]() ![]() |
||
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
PhillipK hat Folgendes geschrieben: EDIT: Ich habe grade aus jux nen astar damit geschrieben *grins* Bzw ich habe den pseudo code dafür zusammengebastelt. Testen geht allerdings nicht, ich kriege einen fehler: Code: [AUSKLAPPEN] Unhandled Exception:Attempt to access field or method of Null object
in der Zeile: BlitzMax: [AUSKLAPPEN] While (location>0 And array[location].key<array[parent(location)].key) in der methode "decreaseKey". Einfügen tue ich ein eigenes Objekt (TAStarNode) mit einem beliegen wert, den wegkosten entsprechend. Egal obs mit hohen oder niedriegen werten ist ![]() Das ganze mit einem if und einem assert zeigt: BlitzMax: [AUSKLAPPEN] Method decreaseKey(location:Int, newkey:Int) Assert wird ausgelöst, weil array[parent(location)] = null ist. Der Location print findet NIEMALS statt, dh direkt beim (2ten?) durchlauf kommt der fehler. Mein erstellen: (new TAStar.Create(....) -> Hier kommt es nicht zu einem fehler. Dist ist die manhatten dist zum ziel, g - Sprich mein Key - entspricht ebenfalls diesem wert.) BlitzMax: [AUSKLAPPEN]
Erst beim ersten durchlauf meines astar algos kommt es zu einem fehler: BlitzMax: [AUSKLAPPEN] 'garnicht vorhanden? Dies ist der fall, wenn ein punkt weder in der offen-liste noch in der geschlossen-liste ist. Anzumerken sei auch, das ich direkt das erste eingefügte objekt wieder entferne. Sprich: Astar wird erstellt: Ich erstelle den binary tree und füge den ersten wegpunkt ein. Astar update entfernt nun den ersten (weil mit niedrigsten kosten) wegpunkt aus deinem tree und prüft die nachbarschaft. Ist ein punkt nicht vorhanden, wird er eingefügt und der fehler tritt auf. Das ist, worauf ich mich beziehe. Ich muss zugeben, ich bin mir nicht sicher, was sich da genau als Fehler tut. Kannst du mir vielleicht einen Code geben, der den Fehler reproduziert, damit ich ihn mir im Debug anschauen kann? Das wär echt nett. Zu deinem anderen Linienproblem: 2D oder 3D? |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
hier, auf die schnelle gebastelt. Scheint wirklich am "fill:-1" gelegen zu haben ![]() BlitzMax: [AUSKLAPPEN] SuperStrict Dreckig, hässlich, tut seinen job. Oder eben nicht: Ich bin vorgegangen wie in der AStar sache. Ein punkt rein, dann solange noch was drin ist, immer einen rausholen und was machen. Hier tue ich allerdings nichts weiter wie: Punkt rausholen, punkt reinstecken (mit einer kleinen _cnt variable um eine while of death zu vermeiden!) Der fehler tritt wieder auf ![]() Ändert man die remove methode von dir wie folgt: BlitzMax: [AUSKLAPPEN] Method remove:TBANode(i:Int) Funktioniert es. Bitte überprüfe das ganze nocheinmal bitte ![]() (ps: grade bei der removemethode.. array[i] =array[l] - array L neu belegen - array L = null. Hm, verquer gedacht? ![]() Das ich gefragt habe, worauf du dich beziehst, war dumm - hätte mir klar sein sollen hihi. War wohl "leicht" übermüdet gestern ^^ (liniensache: Wird zwar eine pseudo3d umgebung, aber die koordinaten in 2d reichen *grins*) |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group