Autor |
Beitrag |
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Do 17.09.09 13:29
Ich brauche eine Liste von Werten, in denen ich einfügen,das kleinste entfernen und verändern kann.
Und das möglichst schnell. (für A* wegsuche)
Im Ringpuffer kann ich schnell (ohne ständiges array größen verändern usw) Daten speichern. die dann am besten noch geordnet, sodass ich mittels intervall halbieren neue daten schnell ein- und existierende (veränderte) schnell umsortieren kann.
Dann hab ich aber vom Binären oder dem Fibonacci heap gehört.
Was ist jetzt besser?
Anzahl der Einträge schätze ich im durchschnitt auf 1-2 tausend
ich kann doch mit dem ringpuffer das ständige verändern der array größe verhindern. also müsste ich statt einer sortierten liste im puffer nur den binary heap speichern wie hier: www.policyalmanac.or...ames/binaryHeaps.htm
wie funktioniert der fibonacci heap?
geht das damit dann noch schneller (also auch ohne die größen eines arrays zu verändern?)
|
|
Thorsten83
      
Beiträge: 191
Erhaltene Danke: 1
|
Verfasst: Do 17.09.09 17:47
Hey,
die Veränderung der Array-Größe ist nicht so wild wie das erstmal aussieht, solange du die Größe beim Vergrößern immer mit einem konstanten Wert (z.B. 2  ) multiplizierst ist die amortisierte Laufzeit immer noch konstant, da ist z.B. das Sortieren bzw. Suchen des kleinsten Wertes viel schlimmer, da du entweder die Elemente immer an der richtigen Stelle einfügen oder aber aus der unsortierten Liste das kleinste Element suchen musst, beides hat eine lineare Laufzeit.
Ein binärer Heap ist eigentlich ziemlich schnell programmiert, und liegt beim Einfügen, Entfernen und Modifizieren bei log(n), bei letzterem natürlich nur dann, wenn du weißt, wo das zu modifizierende Objekt im Heap liegt.
Bei 1000 Elementen heißt das, dass das Einfügen in eine Liste bzw. ein Array 1000 Zugriffe erfordert, bei einem Heap sind's ungefähr 10.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Do 17.09.09 18:46
jop das mit der laufzeit ist bekannt.
bei einer sortierten liste habe ich den vorteil, dass ich das zu modifizierende element schnell finde:
ich suche in der sortierten liste nach dem wert den das element hat und kann dann noch prüfen, welches der elemente in der liste es ist (da werte ja auch mehrfach auftauchen können, aber dann immer an der gleichen stelle sind)
mal etwas code:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| function PFFindOpenNode(const ID:Integer;const aF:Single):Integer; var i,l:Integer; begin l:=OpenBuffer.first; Result:=OpenBuffer.tail-1; if(OpenBuffer.Entrys[l].F^>=aF) then Result:=l else begin Repeat i:=(l+Result) div 2; if(OpenBuffer.Entrys[i].F^<aF) then l:=i else Result:=i; Until(l>=Result-1); end; for i:=Result to OpenBuffer.tail-1 do if(OpenBuffer.Entrys[i].ID=ID) then exit(i); end; |
was ich damit habe:
einfügen: log(n)
kl.el.entfernen: 1 (!!!)
modifizieren: 2*log(n)
beim bin.heap wäre es:
einfügen: log(n)
kl elemente entfernen: log(n)
modifizieren: n/2+log(n) (erst durchsuchen)
überall muss ich ca die hälfte der elemente noch umkopieren.
ABER:
1) nicht beim entfernen aus der sortierten liste
2) bei der sortierten liste kopiere ich die elemente auf einmal statt wie beim heap einzeln -->schneller
das sind ebn so meine bedenken
|
|
Thorsten83
      
Beiträge: 191
Erhaltene Danke: 1
|
Verfasst: Do 17.09.09 21:46
Hey,
wie genau willst du das Einfügen in eine lineare Datenstruktur in log(n) machen?
Bei einer verketteten Liste funktioniert das Suchen per Intervallhalbierung nicht, bei einem Array müsstest du die nachfolgenden Einträge nach hinten schieben, oder verpeil ich da gerade was?
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 18.09.09 07:27
Versuch es doch einfach mal mit einer Skiplist: www.delphipraxis.net...p;highlight=skiplist
Alternativ könnte dieser Artikel über Priority Queues Dich weiterbringen: en.wikipedia.org/wiki/Priority_queue
Thorsten83 hat folgendes geschrieben : | Bei einer verketteten Liste funktioniert das Suchen per Intervallhalbierung nicht |
Nicht ganz. Bei einer Skiplist wird etwas ähnliches gemacht.
Ich würde mal annehmen, das eine Skiplist die beste Wahl ist, denn einerseits ist sie so schnell wie eine Hashmap, andererseits bietet sie eine sortierte, verkettete Liste. Also alles, was das Herz begehrt.
_________________ Na denn, dann. Bis dann, denn.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Fr 18.09.09 10:06
Thorsten83 hat folgendes geschrieben : | Hey,
wie genau willst du das Einfügen in eine lineare Datenstruktur in log(n) machen?
Bei einer verketteten Liste funktioniert das Suchen per Intervallhalbierung nicht, bei einem Array müsstest du die nachfolgenden Einträge nach hinten schieben, oder verpeil ich da gerade was? |
das ganze ist ein array. einfügen so:
Delphi-Quelltext 1: 2: 3:
| i:=PFFindOpenPos(aF); if(OpenBuffer.tail>i) then Move(OpenBuffer.Entrys[i],OpenBuffer.Entrys[i+1],(OpenBuffer.tail-i)*SizeOf(TBuffEntry)); |
die PFFindOpenPos sucht die stelle, wo es rein soll mittels intervallhalbierung (müsste somit log(n) sein) und mit dem move verschiebe ich den rest nach hinten
bei dem binary heap in array darstellung(s. link im 1.post) muss ich auch die hälfte der daten verschieben...vl weniger als hier, aber dafür immer nur einen datensatz. der prozessor kann aber diese volle verschiebung besser optimieren (caching...)
zu der skiplist brauche ich ein besseres bsp. wikipedia bringt hier nicht so viel und die implementierung bringt zum verständnis auch nicht wirklich was
ich sehe auf jeden fall schonmal nen höheren speicherverbrauch...und häufiges allozieren von speicher...
|
|
Tryer
      
Beiträge: 226
Erhaltene Danke: 7
|
Verfasst: Fr 18.09.09 11:17
Flamefire hat folgendes geschrieben : | bei dem binary heap in array darstellung(s. link im 1.post) muss ich auch die hälfte der daten verschieben...vl weniger als hier, aber dafür immer nur einen datensatz. der prozessor kann aber diese volle verschiebung besser optimieren (caching...) |
Warum verschieben? Du ersetzt das erste Element nur das letzte und "sortierst" es mit einfachen Swap()-Operationen nach unten (log(n)). Danach passt halt ein Element mehr rein, aber genauso wie TList das macht sollte man Capacity und Count unterscheiden. Beim Einfügen wird Count+1 > Capacity geprüft und ggf. seitenweise vergrössert(4k). Speicher ist in heutiger Zeit ja nun nicht gerade Mangelware. Ich hab mir auch mal einen BinHeap zusammengebastelt, mit dem grossen Vorteil das ich dabei die Chance hatte die BinHeap - Position des Items im Item selber abzulegen (muss halt nur beim Swap() korrigiert werden). Das Durchsuchen bei Veränderung entfällt dann.
MfG,
Dirk
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Fr 18.09.09 11:46
nja beim swap werden ja auch daten verschoben...
und das mit dem capacity mache ich ja schon im ringpuffer
es geht nur darum, dass das programm häufig ausgeführt wird (bsp 10 mal zur selben zeit)
und da wäre es praktisch, wenn es wenig speicher belegt
die position im binheap zu speichern ist eine möglichkeit...nur könnte das wieder ziemlich verlangsamen...
weil:
item von letzter an erste position und nach unten hangeln: der eintrag des items array muss auf die endgültige position im heap gesetzt werden: 1 array zugriff,1 schreibop
item nach unten hanglen: alle veränderten müssen auch im array verändert werden: je item also: 1 tauschoperation mit 2 arrayzugriffen, 1 veränderung mit je 1 array zugriff
kannste du deinen source mal posten? wenn ich mein programm soweit lauffähig habe, werde ich die laufzeiten mal vergleichen.
|
|
Thorsten83
      
Beiträge: 191
Erhaltene Danke: 1
|
Verfasst: Fr 18.09.09 12:49
Die Skipliste kannte ich noch nicht, sieht ganz interessant aus...
Wenn du einen Eintrag in ein Array einfügst müssen ja die folgenden Einträge nach hinten kopiert werden, das nimmt wieder lineare Laufzeit.
@Tryer: So hab ich das auch mal gemacht, fand's irgendwie nicht wirklich elegant, aber schnell war's trotzdem 
|
|
Tryer
      
Beiträge: 226
Erhaltene Danke: 7
|
Verfasst: Fr 18.09.09 13:04
Aso einen lauffähigen Code kann ich Dir hier nicht posten..
ich hab das ganze 2003 geschrieben, damals sicherlich noch nicht so wie ich es heute machen würde ;/
Hier zumindest der damalige BinHeap. Die Wegsuche selber war für ein 2D - Onlinespiel und ist in der Wegberechnung durch zusätzliche "Sprunglöcher" etwas unübersichtlich, das würde hier nicht weiterhelfen. Grundlage ist ein array[x,y] of TMapItem welches immer ausschliesslich für eine Wegsuche benutzt wird. Wenn die Daten nicht mehr gebraucht werden wird das Array neu initialisiert.
Ich denk mal das man da noch einiges verbessern kann, habe aber bis jetzt noch keine erneute Verwendung gehabt und den Quelltext nicht mehr angerührt.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169:
| type PCoords = ^TCoords; TCoords = packed record case LongInt of 0: (Y,X :Word ); 1: (XY :DWord); end;
PPMapItem = ^PMapItem; PMapItem = ^TMapItem; TMapItem = packed record Parent: PMapItem; Coord: TCoords; GCost: LongWord; GWCost: LongWord; HCost: LongWord; Region: TMapRegion; BinHeapPos: LongWord; IsClosed: Boolean; end;
TMapItemBinHeap = class private FStruct: array of PMapItem; FCount: LongInt; procedure Swap(PItem1, PItem2: PPMapItem); protected function Compare(Item1, Item2: PMapItem):LongInt; procedure DeleteFirst; public destructor Destroy; override; procedure Add(Data: PMapItem); procedure Clear; function Drop: PMapItem; function Empty: Boolean; procedure ReSort(Index: LongInt); end;
implementation
procedure TMapItemBinHeap.Add(Data: PMapItem); var Pos: LongInt; pp: PPMapItem; ppParent: PPMapItem; begin Inc(FCount); if FCount >= Length(FStruct) then begin SetLength(FStruct, FCount + 1024); end; FStruct[FCount] := Data; Pos := FCount; Data^.BinHeapPos := Pos; while Pos <> 1 do begin pp := @FStruct[Pos]; ppParent := @FStruct[Pos div 2]; if Compare(pp^, ppParent^) < 1 then begin Swap(pp, ppParent); Pos := Pos div 2; end else Break; end; end;
procedure TMapItemBinHeap.Clear; begin SetLength(FStruct,0); FCount := 0; end;
function TMapItemBinHeap.Compare(Item1, Item2: PMapItem): LongInt; begin Result := (Item1^.GWCost + Item1^.HCost) - (Item2^.GWCost + Item2^.HCost); end;
procedure TMapItemBinHeap.DeleteFirst; var cIndex1: LongInt; cIndex2: LongInt; cLeftIndex: LongInt; cRightIndex: LongInt; begin FStruct[1] := FStruct[FCount]; FStruct[1]^.BinHeapPos := 1; Dec(FCount); cIndex2 := 1; repeat cIndex1 := cIndex2; cLeftIndex := 2*cIndex1; cRightIndex := cLeftIndex + 1; if cRightIndex <= FCount then begin if Compare(FStruct[cIndex1], FStruct[cLeftIndex]) > -1 then cIndex2 := cLeftIndex; if Compare(FStruct[cIndex2], FStruct[cRightIndex]) > -1 then cIndex2 := cRightIndex; end else begin if (cLeftIndex <= FCount) and (Compare(FStruct[cIndex1], FStruct[cLeftIndex]) > -1) then begin cIndex2 := cLeftIndex; end; end; if cIndex1 <> cIndex2 then Swap(@FStruct[cIndex1], @FStruct[cIndex2]) else Break; until False; end;
destructor TMapItemBinHeap.Destroy; begin Clear; inherited Destroy; end;
function TMapItemBinHeap.Drop: PMapItem; begin Result := FStruct[1]; DeleteFirst; Result^.BinHeapPos := 0; end;
function TMapItemBinHeap.Empty: Boolean; begin Result := FCount = 0; end;
procedure TMapItemBinHeap.ReSort(Index: LongInt); var pp: PPMapItem; ppParent: PPMapItem; Pos: LongInt; begin Pos := Index; while Pos > 1 do begin pp := @FStruct[Pos]; ppParent := @FStruct[Pos div 2]; if Compare(pp^, ppParent^) < 1 then begin Swap(pp, ppParent); Pos := Pos div 2; end else Break; end; end;
procedure TMapItemBinHeap.Swap(PItem1, PItem2: PPMapItem); var temp: PMapItem; tempPos: LongWord; begin temp := PItem1^; PItem1^ := PItem2^; PItem2^ := temp; tempPos := PItem1^^.BinHeapPos; PItem1^^.BinHeapPos := PItem2^^.BinHeapPos; PItem2^^.BinHeapPos := tempPos; end; |
Vielleicht hilft´s ja bei der Lösungsfindung.
Grüsse,
Dirk
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Fr 18.09.09 14:51
anhand der Delphi-Quelltext 1: 2: 3:
| GCost: LongWord; GWCost: LongWord; HCost: LongWord; | daten entnehme ich, dass du eine A* suche ausgeführt hast, richtig?
das ist genau das was ich auch mache...mein array is nur diesmal keine X*Y karte sonder ein graph...
ok
was ich deinem code entnehmen kann, ist wie du elemente einfügst und das erste entfernst
wie machst du das beim aktualisieren?
du gehst ja beim A* von einem feld aus und suchst die erreichbaren felder ab.
hier meine fragen:
wie prüfst du, ob ein feld schon betrachtet wurde(offen,geschlossen,keins)?
wie prüfst du dessen wert?
und wie veränderst du es in dem heap?
ich nehme an, du hast woanders noch ein array of TMapItem, oder?
|
|
Tryer
      
Beiträge: 226
Erhaltene Danke: 7
|
Verfasst: Fr 18.09.09 15:45
Flamefire hat folgendes geschrieben : | wie machst du das beim aktualisieren? |
Dann wird ReSort(MyItem^.BinHeapPos) aufgerufen, und das Element genauso wie beim Add() nach oben sortiert. Eine Änderung kann ja nur sein das der Weg "kürzer" geworden ist.
Flamefire hat folgendes geschrieben : | ich nehme an, du hast woanders noch ein array of TMapItem, oder? |
Gut erkannt. Da ich damals aber eine unbekannte Anzahl umgebender Felder hatte (durch die möglichen Sprunglochziele), hab ich einen einfachen Stack genommen. Kann gut sein das hier ein Array eigentlich schneller wäre, das hab ich nie geprüft. 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104:
| PSimpleStackItem = ^TSimpleStackItem; TSimpleStackItem = record Next :PSimpleStackItem; Data :Pointer; end;
TSimpleStack = class private FFirst :PSimpleStackItem; FCount :LongInt; public constructor Create; destructor Destroy; override; procedure Push(P: Pointer); virtual; function Pop: Pointer; virtual; function Empty: Boolean; property Count: LongInt read FCount; procedure Clear; virtual; end;
TNextNodeList = class(TSimpleStack) public procedure AddIfExists(P: PMapItem); function Drop: PMapItem; end;
procedure TSimpleStack.Clear; var p, d: PSimpleStackItem; begin if FFirst <> nil then begin while FFirst^.Next <> nil do begin p := FFirst^.Next; d := FFirst; Dispose(d); FFirst := p; end; p := FFirst; FFirst := nil; Dispose(p); FCount := 0; end; end;
constructor TSimpleStack.Create; begin inherited; FCount := 0; end;
destructor TSimpleStack.Destroy; begin Clear; inherited Destroy; end;
function TSimpleStack.Empty: Boolean; begin Result := FCount = 0; end;
function TSimpleStack.Pop: Pointer; var p :PSimpleStackItem; begin if FCount > 0 then begin Result := FFirst^.Data; p := FFirst; FFirst := FFirst^.Next; Dispose(p); Dec(FCount); end else Result := nil; end;
procedure TSimpleStack.Push(P: Pointer); var PNew: PSimpleStackItem; begin New(PNew); PNew^.Next := FFirst; FFirst := PNew; PNew^.Data := P; Inc(FCount); end;
procedure TNextNodeList.AddIfExists(P: PMapItem); begin if P <> nil then Push(P); end;
function TNextNodeList.Drop: PMapItem; begin Result := PMapItem(Pop); end; |
Flamefire hat folgendes geschrieben : | wie prüfst du, ob ein feld schon betrachtet wurde(offen,geschlossen,keins)?
wie prüfst du dessen wert?
und wie veränderst du es in dem heap? |
Ausschnitt aus FindPath():Boolean: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
| if Assigned(FMap) then begin try FActive := True; FMap.InUse := True;
if not FMap.Clean then FMap.Reset;
if FDest.XY = FStart.XY then Exit; if not(Allowed(Map[FStart]) and Allowed(Map[FDest])) then Exit;
FDestNode := nil;
pNode := Map[FStart]; pNode^.HCost := CalcHCost(pNode); pNode^.GWCost := 0; pNode^.Parent := nil; FOpenList.Add(pNode); FMap.Clean := False;
while not FOpenList.Empty do begin pNode := FOpenList.Drop; pNode^.IsClosed := True; AddNextNodes(pNode); if (pNode^.Coord.XY = FDest.XY) then begin FDestNode := pNode; Result := True; Break; end; end;
finally WayToString; FOpenList.Clear; ... |
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| procedure TPathFinder.AddNextNodes(pNode: PMapItem); var nNodes: TNextNodeList; p: PMapItem; iJump: LongInt; i: LongInt; begin nNodes := TNextNodeList.Create; try GetNextNodes(pNode, nNodes); for i := Pred(nNodes.Count) downto 0 do begin p := nNodes.Drop; if Allowed(p) then begin if not p^.IsClosed then begin if (p^.BinHeapPos > 0) then begin if (p^.GCost + pNode^.GWCost <= p^.GWCost) then begin p^.Parent := pNode; p^.GWCost := p^.GCost + pNode^.GWCost; if Distance(p^.Coord, pNode^.Coord) > 1 then begin p^.GWCost := p^.GWCost + FMap.JumpCost; end; FOpenList.ReSort(p^.BinHeapPos); end; end else begin p^.Parent := pNode; p^.GWCost := p^.GCost + pNode^.GWCost; p^.HCost := CalcHCost(p); FOpenList.Add(p); end; end; end; end; finally nNodes.Free; end; end; |
Grüsse, Dirk
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Fr 18.09.09 16:17
das ist ne gute idee.
danke
deine verwaltung der knoten im graph/feld finde ich etwas umständlich aber insgesammt ist das natürlich super.
ich denke auf diese weise kann ich den binary heap auch verwenden.
dein PPMapItem kann doch durch die verwendung von "var" im paramter wegfallen, wenn ich das richtig gesehen habe, oder?
finde nur deine ganzen pointer etwas verwirrend (nicht pointer im algemeinen, aber du hast ja eigendlich nirgends tatsächlich etwas, sondern immer nur nen pointer)
trotzdem die Frage: wo genau speicherst du die daten? sind die dann im graph drin?
weil in dem code hast du immer nur nen pointer darauf.
ich habe es so, dass ich einerseits meinen graphen hab, den ich sehr klein halte (nur x,y und verbindungen zu nachbarn) und andrerseits ein array of TMapItem (wäre es in deinem fall) für die wegsuche erstelle, dass die gleich anzahl an elementen hat wie ich wegpunkte hab. das kann ich dann nach der wegsuche freigeben und hab den speicher durch F,G,Open... wieder...
das sind bei 20k einträgen (insgesammt sogar über 100k) gleich mal ein paar mb die ich spare
|
|
Tryer
      
Beiträge: 226
Erhaltene Danke: 7
|
Verfasst: Fr 18.09.09 17:07
Mit var - Parametern würde es auch gehen, klar. Es geht ja nur darum die beiden Pointer die im Array stehen zu vertauschen, und innerhalb des MapItems die richtige Position einzutragen.
Die Daten stehen in FMap, das ist ein TMapArray = array of array of TMapItem. In meinem Fall durch Auswertung eines Bitmap´s erstellt, wobei die verschiedenen Farben für unterschiedliche "Regions" und "Einflugkosten" standen. Klar kommen da einige MB zusammen - das Abwägen zwischen Speicherplatz und Performance ist halt meistens ein Kompromiss.
Bei mir stand zum Beispiel in jedem Element des Arrays seine Position im Array. Die umliegenden Felder findet man darüber dann sehr schnell. Da würde ich heutzutage eher sparen und die Arrayposition über den Adress - Offset zum ersten Arrayelement bestimmen, das geht auch schnell genug.
Grüsse,
Dirk
Faszinierend wieviele Wege es gibt den kürzesten zu finden 
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Mi 30.09.09 13:37
so moin
hab grad mal meinen sortierten ringpuffer gegen den binary heap ausgetauscht.
resultat: etwas kürzere laufzeit:
statt 8,3s nur noch 6,6s
funktioniert also
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 30.09.09 21:07
Wenn Du deine Testsuite hier postest, könnte man nochmals rumbasteln.
_________________ Na denn, dann. Bis dann, denn.
|
|
|