| 
| Autor | Beitrag |  
| Horst_H 
          Beiträge: 1654
 Erhaltene Danke: 244
 
 WIN10,PuppyLinux
 FreePascal,Lazarus
 
 | 
Verfasst: Do 16.05.13 14:59 
 
Hallo,
 ich habe Perm5aus8 ausgemistet.
 Ich ziehe also k=5 Karten aus einem Stapel Karten, in dem es n=8 verschiedene Typen gibt.
 Die Anzahl des jeweiligen Typen kann 0..k sein.
 Es werden alle möglichen Anordnungen davon erzeugt.
 EDIT: Das nennt sich wohl Variation.
de.wikipedia.org/wik...ion_mit_Wiederholung Aber hier nicht mit zurücklegen, sondern es gibt verschiedene Elemente in unterschiedlicher Vielfachheit.
 												| 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:
 
 | program Kombination;
 
 {$IFDEF FPC}
 {$mode Delphi}
 {$DEBUGINFO-}
 {$R- $V- $O-}
 {$Optimization ON}
 {$Optimization regvar}
 {$Optimization PEEPHOLE}
 {$Optimization CSE}
 {$Optimization ASMCSE}
 {$CODEALIGN proc=32}
 {$ASMMODE INTEL}
 {$ELSE}
 {$APPTYPE CONSOLE}
 {$ENDIF}
 
 uses
 sysutils;
 type
 nativeinteger = longInt;const
 KombLaenge =3 ;  KL_1 = KombLaenge-1;
 n = KombLaenge+2;
 var
 PermCount: Int64;
 T1,T0 : int64;
 FeldAnzahl : array[0..n-1] of LongInt;
 Komb : array[0..KL_1] of byte;
 
 
 function GetCPU_Time: int64;
 type
 TCpu = record
 HiCpu,
 LoCpu : Dword;
 end;
 var
 Cput : TCpu;
 begin
 asm
 RDTSC;
 MOV Dword Ptr [CpuT.LoCpu],EAX;  MOV Dword Ptr [CpuT.HiCpu],EDX
 end;
 with Cput do  result := int64(HiCPU) shl 32 + LoCpu;
 end;
 
 procedure VerarbeitungKomb; var
 I : nativeinteger;
 Begin
 INC(PermCount);
 
 For i := Low(Komb) to High(Komb) do
 write(Komb[i]:2);
 writeln;
 end;
 
 procedure VerarbeitungKombZaehl; inline;
 
 Begin
 INC(PermCount);
 end;
 
 procedure permute(depth:nativeinteger);
 var
 i: nativeinteger;
 Begin
 IF depth > KL_1 THEN Begin
 VerarbeitungKomb;
 EXIT;
 end;
 
 i := Low(FeldAnzahl);
 repeat
 IF FeldAnzahl[i] >0 then begin
 dec(FeldAnzahl[i]);
 Komb[depth] := i;
 permute(depth+1);
 Komb[depth] := 0;      inc(FeldAnzahl[i]);
 end;
 inc(i);
 until i > High(FeldAnzahl);
 end;
 
 procedure Init;
 var
 i: integer;
 sum: longint;
 begin
 randomize;
 repeat
 sum := 0;
 For i := Low(FeldAnzahl) to High(FeldAnzahl) do Begin
 FeldAnzahl[i] := random(3);      inc(Sum,FeldAnzahl[i]);
 end;
 until Sum >= KombLaenge;
 
 write('  Index: ');
 For i := Low(FeldAnzahl) to High(FeldAnzahl) do
 write(i:2);
 writeln;
 write(' Anzahl: ');
 For i := Low(FeldAnzahl) to High(FeldAnzahl) do
 write(FeldAnzahl[i]:2);
 writeln;
 writeln('Weiter mit <ENTER>') ;
 ReadlN;
 end;
 
 var
 Time1,Time0: TDateTime;
 I: nativeinteger;
 
 Begin
 Init;
 
 Time0 := Time;T0 := GetCPU_Time;
 permute(0);
 T1 := GetCPU_Time;Time1 := Time;
 
 writeln(PermCount:12,' Anzahl der Kombinationen');
 writeln((T1-T0)/PermCount:12:5,' CPU-Takte pro Durchgang');
 IF Time1-Time0 > 0 then
 Writeln((Time1-Time0)*(86000.0*1e9)/PermCount:12:6,' ns');
 writeln(FormatDateTime('HH:NN:SS.ZZZ',Time1-Time0));
 end.
 |  Die Ausgabe:
 		                       Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 17:
 18:
 
 |   Index:  0 1 2 3 4Anzahl:  0 1 2 0 0
 Weiter mit <ENTER>
 
 1 2 2
 2 1 2
 2 2 1
 3 Anzahl der Kombinationen
 oder
 nur Zählen mit 7 aus 10 wobei alle 7 fach vorhanden:
 Index:  0 1 2 3 4 5 6 7 8 9
 Anzahl:  7 7 7 7 7 7 7 7 7 7
 Weiter mit <ENTER>
 
 10000000 Anzahl der Kombinationen
 27.40196 CPU-Takte pro Durchgang
 7.763889 ns
 00:00:00.078
 |  Am langsamsten ist es, bei der jeweiligen Anzahl = 1 
 5 aus 8 ~43 CPU-Takte und 12 aus 12 = 12! 
 28 Sekunden== 188 CPU-Takte, da ist auch der Aufwand inc/ dec und die Vegleiche>0 einfach zu groß.
 Gruß Horst |  |  |  
| Delphi-Laie 
          Beiträge: 1600
 Erhaltene Danke: 232
 
 
 Delphi 2 - RAD-Studio 10.1 Berlin
 
 | 
Verfasst: Fr 17.05.13 11:02 
 
Mal wieder ein Eigenzitat:
 	  |  Delphi-Laie hat folgendes geschrieben  : |  	  | Wiederum hat der Quelltext mehr Labels als Schleifen. Daß BenBE nochmal als Helfer in der gar nicht vorhandenen Not einspringt, diese Labels zu eliminieren, wage ich nicht zu hoffen. | 
 Mein lauter Gedankengang wurde erhöret: Der gute Benny Baumann (BenBE) half mir dankenswerterweise auch diesmal. Er benutzte dafür eine Software namens "Git", die die verpönten Labels und gotos automatisch entfernt. Herausgekommen ist eine Lösung mit zirkulärem Prozeduraufruf (Anhang). Ich halte das nicht für eine echte Verbesserung der Übersichtlichkeit und vermied deshalb so etwas bis heute. Zum Glück wußte ich aber, daß man mit der forward-Deklaration so etwas zum Compilieren und Laufen bringen kann, deshalb soll das ganze auch hier der Vollständigkeit halber veröffentlicht werden.
 Auch Herrn Sedgewicks veröffentlichte 3 Algorithmen zu Steinhaus-Johnson-Trotter übersetzte ich nach Pascal (und entdeckte dabei kleine Unsauberkeiten), kann sie hier auf Wunsch hin auch veröffentlichen.
Einloggen, um Attachments anzusehen!
 |  |  |  
| Horst_H 
          Beiträge: 1654
 Erhaltene Danke: 244
 
 WIN10,PuppyLinux
 FreePascal,Lazarus
 
 | 
Verfasst: Fr 17.05.13 13:44 
 
Hallo,
 ich dachte die Initialisierung könnte man vor die Schleife ziehen, ala :
 												| 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:
 
 | unit Unit1;
 interface
 
 uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;
 
 type
 TForm1 = class(TForm)
 ListBox1: TListBox;
 procedure FormCreate(Sender: TObject);
 private
 
 public
 
 end;
 
 var
 Form1: TForm1;
 
 implementation
 
 {$R *.DFM}
 
 procedure GetPermutations(x:string);
 var zaehler:cardinal;
 i,inversionsanzahl_alt,inversionsanzahl_neu:byte;
 h:char;
 d:array of integer;
 p:array of byte;
 j,k,l,n:byte;
 first:boolean;
 
 function inversionsanzahl:word;
 var k,l:word;
 begin
 result:=0;
 for k:=1 to pred(length(x)) do
 for l:=k to length(x) do
 if x[k]>x[l] then
 inc(result);
 end;
 
 procedure Ausgabe;
 Begin
 inversionsanzahl_neu:=inversionsanzahl;
 Form1.ListBox1.Items.Add(inttostr(zaehler)+': '+x+', Inversionsanzahl: '+inttostr(inversionsanzahl_neu)+', Differenz: '+inttostr(inversionsanzahl_neu-inversionsanzahl_alt));
 Form1.ListBox1.Refresh;
 Form1.ListBox1.TopIndex:=pred(Form1.ListBox1.Items.Count);
 inversionsanzahl_alt:=inversionsanzahl_neu;
 end;
 
 procedure step1;forward;
 
 procedure step2;
 begin
 if n>2 then
 begin
 dec(n);
 step1
 end
 else
 begin
 l:=1;
 first:=true
 end
 end;
 
 procedure step1;
 begin
 l:=p[n]+d[n];
 p[n]:=l;
 if l=n then
 begin
 d[n]:=-1;
 step2
 end
 else if l=0 then
 begin
 d[n]:=1;
 inc(k);
 step2
 end
 end;
 
 
 begin
 inversionsanzahl_alt:=1;
 setlength(d,succ(length(x)));
 setlength(p,succ(length(x)));
 zaehler:=0;
 for j:=1 to n do begin
 p[j]:=0;
 d[j]:=1
 end;
 first:=false;
 
 repeat
 n:=length(x);
 for i:=1 to length(x) do Begin
 k:=0;
 
 step1;
 inc(zaehler);
 
 Ausgabe;
 
 l:=l+k;    h:=x[l];
 x[l]:=x[succ(l)];
 x[succ(l)]:=h;
 end
 until first
 end;
 
 procedure TForm1.FormCreate(Sender: TObject);
 var s:string;
 begin
 Form1.Show;
 s:=Inputbox('Zu permutierenden String eingeben','String?',s);
 GetPermutations(s)
 end;
 
 end.
 |  Meine Goto-Freie Version www.entwickler-ecke....der=asc&start=27  braucht zumindest keine Rekursion, Step1-> Step2->Step1...
 Aber muss diesen einen Vergleich machen l=n, welcher aber auch wirklich nur einmal  durchlaufen wird -> Gute Sprungvorhersage.
 Sollte so etwas,wie Steinhaus-Johnson-Trotter/permLex nicht mal in Delphi Library, die etwas dünn besetzt ist.
www.entwickler-ecke....nd+Assembler_77.html Permutation/Kombination/Variation
 Man muss es ja nicht auf Strings beschränken, wie man am 8-Damen Problem ja sieht.
 Gruß Horst |  |  |  
| Delphi-Laie 
          Beiträge: 1600
 Erhaltene Danke: 232
 
 
 Delphi 2 - RAD-Studio 10.1 Berlin
 
 | 
Verfasst: Fr 17.05.13 14:44 
 
Hallo Horst!
 	  |  Horst_H hat folgendes geschrieben  : |  	  | ich dachte die Initialisierung könnte man vor die Schleife ziehen, ala : | 
 Dazu äußere ich mich jetzt nicht (keine Kraft und Lust, mich da hineinzudenken), aber hierzu:
 Ja, Deine Lösung war die erstere und noch übersichtlichere. Ich kann Deinem Beitrag aber nur einmal den Dank verpassen.
 	  |  Horst_H hat folgendes geschrieben  : |  	  | Aber muss diesen einen Vergleich machen l=n, welcher aber auch wirklich nur einmal  durchlaufen wird -> Gute Sprungvorhersage. | 
 Dito, keine Äußerung dazu. Nicht jetzt.
 	  |  Horst_H hat folgendes geschrieben  : |  	  | Sollte so etwas,wie Steinhaus-Johnson-Trotter/permLex nicht mal in Delphi Library, die etwas dünn besetzt ist. | 
 Algorithmen gibt es (abzählbar) unendlich viele, man wird also immer etwas finden, was dort fehlt. Wegen meiner gern. Ich hätte schon genug Algorithmen aus der 1. Hälfte der 90er beizusteuern (die ich allerdings abtippen müßte), überwiegend kombinatorische, alle damals selbst geschrieben, und sicher keine genialen, neuwertigen, aber funktionierende.
 	  |  Horst_H hat folgendes geschrieben  : |  	  | Man muss es ja nicht auf Strings beschränken, wie man am 8-Damen Problem ja sieht. | 
 Strings sind eine unverselle, flexible und gleichzeitig recht simple Datenstruktur. Da sie implizit auch Arrays (of char) sind, sind damit Arrays automatisch gleich impliziert. |  |  |  
| BenBE 
          Beiträge: 8721
 Erhaltene Danke: 191
 
 Win95, Win98SE, Win2K, WinXP
 D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
 
 | 
Verfasst: Fr 17.05.13 17:05 
 
	  |  Delphi-Laie hat folgendes geschrieben  : |  	  | Mal wieder ein Eigenzitat: 
 
 	  |  Delphi-Laie hat folgendes geschrieben  : |  	  | Wiederum hat der Quelltext mehr Labels als Schleifen. Daß BenBE nochmal als Helfer in der gar nicht vorhandenen Not einspringt, diese Labels zu eliminieren, wage ich nicht zu hoffen. | 
 
 Mein lauter Gedankengang wurde erhöret: Der gute Benny Baumann (BenBE) half mir dankenswerterweise auch diesmal.
 | 
 Unmögliches macht der liebe Gott sofort, Wunder brauchen etwas länger    	  |  Delphi-Laie hat folgendes geschrieben  : |  	  | Er benutzte dafür eine Software namens "Git", die die verpönten Labels und gotos automatisch entfernt. | 
 DAS Feature habe ich noch nicht gefunden. Gleich mal bei Linus Torvalds beantragen    Git ist eine Versionsverwaltung, die an der Stelle recht praktisch war, um die Vorgehensweise recht gut zu demonstrieren, da man Einzelschritte abspeichern kann. Muss nur die Patch-Serie noch etwas aufräumen, falls da Interesse besteht.
 	  |  Delphi-Laie hat folgendes geschrieben  : |  	  | Herausgekommen ist eine Lösung mit zirkulärem Prozeduraufruf (Anhang). Ich halte das nicht für eine echte Verbesserung der Übersichtlichkeit und vermied deshalb so etwas bis heute. Zum Glück wußte ich aber, daß man mit der forward-Deklaration so etwas zum Compilieren und Laufen bringen kann, deshalb soll das ganze auch hier der Vollständigkeit halber veröffentlicht werden. | 
 Es sei angemerkt, dass der Code OHNE Compiler umgebaut wurde... Hatte grad keine Lust meinen anderen Rechne zu starten._________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
 |  |  |  
| Horst_H 
          Beiträge: 1654
 Erhaltene Danke: 244
 
 WIN10,PuppyLinux
 FreePascal,Lazarus
 
 | 
Verfasst: Di 21.05.13 10:34 
 
Hallo,
 ich habe mal die anderen Versionen nochmals getestet.
  Fiete  Version mit Move ist bei tDat = Byte am schnellsten.
 permute_i bei Longint.
 Eine Stringvariante, die die innersten Permutationen von 3 Positionen gespeichert hat, ist auch nicht übel.Das könnte man bei char/byte, auf 4 Positionen erweitern und einen LongInt zusammenstellen, aber das geht zu sehr in Richtung Assembler.
 		                       Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 12:
 13:
 14:
 15:
 16:
 
 | Mit tDat = Byte:Permute_i
 479001600 Anzahl der Kombinationen
 35.39909 CPU-Takte pro Durchgang
 11.009300 ns
 00:00:05.298
 Permute_Move
 479001600 Anzahl der Kombinationen
 23.70283 CPU-Takte pro Durchgang
 7.370703 ns
 00:00:03.547
 Permute_s
 479001600 Anzahl der Kombinationen
 10.78625 CPU-Takte pro Durchgang
 3.353909 ns
 00:00:01.614
 |  		                       Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 10:
 11:
 
 | tDat = LongIntPermute_i
 479001600 Anzahl der Kombinationen
 24.81255 CPU-Takte pro Durchgang
 7.715653 ns
 00:00:03.713
 Permute_Move
 479001600 Anzahl der Kombinationen
 36.27229 CPU-Takte pro Durchgang
 11.279441 ns
 00:00:05.428
 |  Damit sind diese Permutationen schneller als Steinhaus-Johnson-Trotter mit 4.1s, nun 3,5 .. 3,7 Sekunden und getrickst 1,6s
 												| 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:
 170:
 171:
 172:
 173:
 174:
 175:
 176:
 177:
 178:
 179:
 180:
 181:
 182:
 183:
 184:
 185:
 186:
 187:
 188:
 189:
 190:
 191:
 192:
 193:
 194:
 195:
 196:
 197:
 198:
 199:
 200:
 201:
 202:
 203:
 204:
 205:
 206:
 207:
 208:
 209:
 210:
 211:
 212:
 213:
 214:
 215:
 216:
 217:
 218:
 219:
 220:
 221:
 222:
 223:
 224:
 225:
 226:
 227:
 228:
 229:
 230:
 231:
 232:
 233:
 234:
 235:
 236:
 237:
 238:
 239:
 240:
 241:
 242:
 243:
 244:
 245:
 246:
 247:
 248:
 249:
 250:
 251:
 252:
 253:
 254:
 255:
 256:
 257:
 258:
 259:
 260:
 261:
 262:
 263:
 264:
 265:
 266:
 267:
 268:
 269:
 270:
 271:
 272:
 273:
 274:
 275:
 276:
 277:
 278:
 279:
 280:
 281:
 282:
 283:
 284:
 285:
 286:
 287:
 288:
 289:
 290:
 291:
 292:
 293:
 294:
 295:
 296:
 297:
 298:
 299:
 
 | program Variation;
 
 {$IFDEF FPC}
 {$mode Delphi}
 {$DEBUGINFO-}
 {$R- $V- $O-}
 {$Optimization ON}
 {$Optimization regvar}
 {$Optimization PEEPHOLE}
 {$Optimization CSE}
 {$Optimization ASMCSE}
 {$CODEALIGN proc=32}
 {$ASMMODE INTEL}
 {$ELSE}
 {$APPTYPE CONSOLE}
 {$ENDIF}
 
 uses
 sysutils;
 const
 k =10;    KL_1 = k-1;
 n = k+3;
 type
 tDat = Byte;
 tKombIndex = 0..KL_1;
 tKomb = array[tKombIndex] of tDat;
 
 tCallBack = function (const Komb:tKomb;depth:longInt): boolean;
 tPerm = procedure (depth:nativeint);
 var
 T1,T0 : int64;
 PermCount: LongWord;  FeldAnzahl : array[0..k-1] of LongInt;
 Komb : tKomb;
 
 verarbeite: tCallBack;
 
 s: string;
 sKomb: pChar;
 Index : tDat;
 
 
 function Check(const Komb:tKomb;depth:longInt): boolean;
 begin
 result := true;end;
 
 function Check_Ausg(const Komb:tKomb;depth:longInt): boolean;
 var
 i : integer;
 t: string[3];  s: string[2*k+1];
 begin
 i:= 0;
 s:='';
 repeat
 str(Komb[i]:2,T);
 s := s+t;
 inc(i);
 until i>depth;
 writeln(s);
 
 result := false;
 end;
 
 procedure PermMove;
 var
 Tausch:tDat;
 begin
 inc(PermCount);
 Index:=K;
 while Index>0 do
 begin
 Tausch:=Komb[0];
 MOVE(Komb[1],Komb[0],(Index-1)*SizeOf(Komb[0]));
 Komb[Index-1]:=Tausch;
 if Tausch=Index then
 dec(Index)
 else
 begin
 inc(PermCount);
 Index:=K;
 end;
 end;
 end;
 
 function GetCPU_Time: int64;
 type
 TCpu = record
 HiCpu,
 LoCpu : Dword;
 end;
 var
 Cput : TCpu;
 begin
 asm
 RDTSC;
 MOV Dword Ptr [CpuT.LoCpu],EAX;
 MOV Dword Ptr [CpuT.HiCpu],EDX
 end;
 with Cput do  result := int64(HiCPU) shl 32 + LoCpu;
 end;
 
 
 procedure Permute(depth:nativeint);
 var
 i: nativeint;
 Begin
 IF depth >= K THEN Begin
 inc(PermCOunt);
 EXIT;
 end;
 i := Low(FeldAnzahl);
 repeat
 IF FeldAnzahl[i] >0 then begin
 dec(FeldAnzahl[i]);
 Komb[depth] := i;
 permute(depth+1);
 inc(FeldAnzahl[i]);
 Komb[depth] := 0;
 end;
 inc(i);
 until i > High(FeldAnzahl);
 end;
 
 procedure Init;
 var
 i,j: integer;
 sum: longint;
 begin
 
 setlength(s,n);
 sKomb := @s[1];
 For i in tKombIndex  do Begin
 Komb[i] := i+1;
 sKomb[i] := chr(65+i);
 end;
 
 
 randomize;
 repeat
 sum := 0;
 For i := Low(FeldAnzahl) to High(FeldAnzahl) do Begin
 j := random(3);
 FeldAnzahl[i] := j;
 inc(Sum,j);
 end;
 until Sum >= n;
 
 write('  Index: ');
 For i := Low(FeldAnzahl) to High(FeldAnzahl) do
 write(i:2);
 writeln;
 write(' Anzahl: ');
 For i := Low(FeldAnzahl) to High(FeldAnzahl) do
 write(FeldAnzahl[i]:2);
 writeln;
 
 
 
 PERMcount:=0;
 end;
 
 procedure Permute_i(depth:nativeInt);
 var
 i: nativeInt;
 tmp : tDat;
 begin
 IF depth <= 0 then
 begin
 inc(PermCOunt);
 EXIT;
 end;
 i := depth+1;
 repeat
 dec(i);
 tmp:= Komb[depth];
 Komb[depth]:=Komb[i];
 Komb[i] := tmp;
 Permute_i(depth-1);
 Komb[i] := Komb[depth];
 Komb[depth]:=tmp;
 until i<= 0;
 end;
 
 procedure Permute_s_3;
 var
 stmp : array[0..3] of char;  s : pChar;
 begin
 
 s:= sKomb;
 stmp[0] :=s[0];stmp[1] :=s[1];      inc(PermCount);
 stmp[2] :=s[2];
 s[0]:= sTmp[1];s[1]:= sTmp[0];                     inc(PermCount);
 s[1]:= sTmp[2];s[2]:= sTmp[0];      inc(PermCount);
 s[0]:= sTmp[2];s[1]:= sTmp[1];                     inc(PermCount);
 s[1]:= sTmp[0];s[2]:= sTmp[1];      inc(PermCount);
 s[0]:= sTmp[0];s[1]:= sTmp[2];                     inc(PermCount);
 s[1]:=stmp[1];s[2]:= stmp[2];    end;
 
 procedure Permute_s(depth:nativeint);
 var
 i: nativeInt;
 tmp : char;
 begin
 IF depth<3 then begin
 Permute_s_3;
 EXIT;
 end;
 i := depth;
 repeat
 tmp:= sKomb[depth];
 sKomb[depth]:=sKomb[i];
 sKomb[i] := tmp;
 Permute_s(depth-1);
 sKomb[i] := sKomb[depth];
 sKomb[depth]:=tmp;
 dec(i);
 until i< 0;
 end;
 
 procedure Testlauf(proc:tPerm;depth:nativeInt);
 var
 Time1,Time0: TDateTime;
 begin
 PermCount:= 0;
 Time0 := Time;T0 := GetCPU_Time;
 proc(depth);
 T1 := GetCPU_Time;Time1 := Time;
 writeln(PermCount:12,' Anzahl der Kombinationen');
 IF PermCOunt>0 then begin
 writeln((T1-T0)/PermCount:12:5,' CPU-Takte pro Durchgang');
 IF Time1-Time0 > 0 then
 Writeln((Time1-Time0)*(86000.0*1e9)/PermCount:12:6,' ns');
 end;
 writeln(FormatDateTime('HH:NN:SS.ZZZ',Time1-Time0));
 end;
 
 var
 
 I: nativeint;
 Begin
 Init;
 IF k < 11 then
 Testlauf(@permute,0);
 
 For i := Low(Komb) to High(Komb) do
 Komb[i] := i+1;
 Verarbeite := @Check;  writeln('Permute_i');
 Testlauf(@Permute_i,k-1);
 
 writeln('Permute_Move');
 For i := Low(Komb) to High(Komb) do
 Komb[i] := i+1;
 Testlauf(@PermMove,k);
 
 writeln('Permute_s');
 Testlauf(@Permute_s,k-1);
 writeln('Weiter mit <ENTER>') ;
 ReadLn;
 end.
 |  Gruß Horst |  |  |  |