Changeset 160 for trunk/AI/StdAI/Pile.pas
- Timestamp:
- Mar 6, 2019, 8:10:23 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/AI/StdAI/Pile.pas
r124 r160 1 { 2 main parts contributed by Rassim Eminli}1 {single instance priority queue 2 main parts contributed by Rassim Eminli} 3 3 4 4 {$INCLUDE Switches.inc} 5 5 6 unit Pile; 6 7 … … 14 15 function Get(var Item, Value: integer): boolean; 15 16 17 16 18 implementation 17 19 18 20 const 19 MaxSize =9600;21 MaxSize=9600; 20 22 21 23 type 22 23 Item:integer;24 Value:integer;25 24 TheapItem = record 25 Item: integer; 26 Value: integer; 27 end; 26 28 27 29 var 28 bh: array [0 .. MaxSize - 1] of TheapItem; 29 Ix: array [0 .. MaxSize - 1] of integer; 30 n, CurrentSize: integer; 31 {$IFDEF DEBUG}InUse: boolean; {$ENDIF} 30 bh: array[0..MaxSize-1] of TheapItem; 31 Ix: array[0..MaxSize-1] of integer; 32 n, CurrentSize: integer; 33 {$IFDEF DEBUG}InUse: boolean;{$ENDIF} 34 32 35 33 36 procedure Create(Size: integer); 34 37 begin 35 {$IFDEF DEBUG}assert(not InUse, 'Pile is a single instance class, ' + 'no multiple usage possible. Always call Pile.Free after use.'); {$ENDIF} 36 assert(Size <= MaxSize); 37 if (n <> 0) or (Size > CurrentSize) then 38 begin 39 FillChar(Ix, Size * sizeOf(integer), 255); 40 n := 0; 41 end; 42 CurrentSize := Size; 43 {$IFDEF DEBUG}InUse := true; {$ENDIF} 38 {$IFDEF DEBUG}assert(not InUse, 'Pile is a single instance class, ' 39 +'no multiple usage possible. Always call Pile.Free after use.');{$ENDIF} 40 assert(Size<=MaxSize); 41 if (n <> 0) or (Size > CurrentSize) then 42 begin 43 FillChar(Ix, Size*sizeOf(integer), 255); 44 n := 0; 45 end; 46 CurrentSize := Size; 47 {$IFDEF DEBUG}InUse:=true;{$ENDIF} 44 48 end; 45 49 46 50 procedure Free; 47 51 begin 48 {$IFDEF DEBUG}assert(InUse); 49 InUse := false; {$ENDIF} 52 {$IFDEF DEBUG}assert(InUse);InUse:=false;{$ENDIF} 50 53 end; 51 54 52 55 procedure Empty; 53 56 begin 54 55 56 FillChar(Ix, CurrentSize *sizeOf(integer), 255);57 58 57 if n <> 0 then 58 begin 59 FillChar(Ix, CurrentSize*sizeOf(integer), 255); 60 n := 0; 61 end; 59 62 end; 60 63 61 // 62 function Put(Item, Value: integer): boolean; // 64 //Parent(i) = (i-1)/2. 65 function Put(Item, Value: integer): boolean; //O(lg(n)) 63 66 var 64 i, j:integer;67 i, j: integer; 65 68 begin 66 assert(Item <CurrentSize);67 68 69 begin70 if bh[i].Value <= Value then71 72 result := false;73 74 75 end76 77 78 79 80 69 assert(Item<CurrentSize); 70 i := Ix[Item]; 71 if i >= 0 then 72 begin 73 if bh[i].Value <= Value then 74 begin 75 result := False; 76 exit; 77 end; 78 end 79 else 80 begin 81 i := n; 82 Inc(n); 83 end; 81 84 82 while i > 0 do 83 begin 84 j := (i - 1) shr 1; // Parent(i) = (i-1)/2 85 if Value >= bh[j].Value then 86 break; 87 bh[i] := bh[j]; 88 Ix[bh[i].Item] := i; 89 i := j; 90 end; 91 // Insert the new Item at the insertion point found. 92 bh[i].Value := Value; 93 bh[i].Item := Item; 94 Ix[bh[i].Item] := i; 95 result := true; 85 while i > 0 do 86 begin 87 j := (i-1) shr 1; //Parent(i) = (i-1)/2 88 if Value >= bh[j].Value then break; 89 bh[i] := bh[j]; 90 Ix[bh[i].Item] := i; 91 i := j; 92 end; 93 // Insert the new Item at the insertion point found. 94 bh[i].Value := Value; 95 bh[i].Item := Item; 96 Ix[bh[i].Item] := i; 97 result := True; 96 98 end; 97 99 98 100 function TestPut(Item, Value: integer): boolean; 99 101 var 100 102 i: integer; 101 103 begin 102 assert(Item <CurrentSize);103 104 104 assert(Item<CurrentSize); 105 i := Ix[Item]; 106 result := (i < 0) or (bh[i].Value > Value); 105 107 end; 106 108 107 // 108 // 109 function Get(var Item, Value: integer): boolean; // 109 //Left(i) = 2*i+1. 110 //Right(i) = 2*i+2 => Left(i)+1 111 function Get(var Item, Value: integer): boolean; //O(lg(n)) 110 112 var 111 i, j:integer;112 last:TheapItem;113 i, j: integer; 114 last: TheapItem; 113 115 begin 114 115 116 result := false;117 118 116 if n = 0 then 117 begin 118 result := False; 119 exit; 120 end; 119 121 120 121 122 Item := bh[0].Item; 123 Value := bh[0].Value; 122 124 123 125 Ix[Item] := -1; 124 126 125 dec(n); 126 if n > 0 then 127 begin 128 last := bh[n]; 129 i := 0; 130 j := 1; 131 while j < n do 132 begin 133 // Right(i) = Left(i)+1 134 if (j < n - 1) and (bh[j].Value > bh[j + 1].Value) then 135 Inc(j); 136 if last.Value <= bh[j].Value then 137 break; 127 dec(n); 128 if n > 0 then 129 begin 130 last := bh[n]; 131 i := 0; j := 1; 132 while j < n do 133 begin 134 // Right(i) = Left(i)+1 135 if(j < n-1) and (bh[j].Value > bh[j + 1].Value)then 136 inc(j); 137 if last.Value <= bh[j].Value then break; 138 138 139 140 141 142 j := j shl 1 + 1; //Left(j) = 2*j+1143 139 bh[i] := bh[j]; 140 Ix[bh[i].Item] := i; 141 i := j; 142 j := j shl 1+1; //Left(j) = 2*j+1 143 end; 144 144 145 146 147 148 149 result := true145 // Insert the root in the correct place in the heap. 146 bh[i] := last; 147 Ix[last.Item] := i; 148 end; 149 result := True 150 150 end; 151 151 152 152 initialization 153 n:=0; 154 CurrentSize:=0; 155 {$IFDEF DEBUG}InUse:=false;{$ENDIF} 156 end. 153 157 154 n := 0;155 CurrentSize := 0;156 {$IFDEF DEBUG}InUse := false; {$ENDIF}157 158 end.
Note:
See TracChangeset
for help on using the changeset viewer.