Kobinationsalgorithmus

Hallo rokdd,
nein, das ist keine Endlosschleife. Der string wird immer länger und Du gibst an, wie lang er werden darf.
Bis 5 Elemente hast Du eine moderate Rechenzeit von einigen Sekunden. Die Rechenzeit steigt aber sehr steil an. Um die von Dir mal angedachte Länge von 50 Elementen zu erreichen, wirst Du den Rechner vermutlich auf Jahre beschäftigen. :wink:
cu Rainer

hallo,
schon aml vielen dank für deine hilfe. habe den quelltext jetzt in meine programmiersprache übernohmen. habe da aber noch ein frage: du hast geschrieben dass word bei mir wordlist der gegebene stringarray ist, oder? die äussere schleife geht aber weit über die länge der wordlist über hinaus,da du ja die schleife n+1 m laufen lasst willst! da habe ich wahrscheinlich irgendetwas schief verstanden…

Übrigens gehe ich nicht zum Griechen essen…

rokdd

var counter:longint; // das ist der Zaehler
cdiv, cmod:integer; // zur Hilfe
output:string;
wordlist:array of string;
n,m:longint;
begin
n:=3;
m:=15;
counter:=0;
setlength(wordlist,3);
wordlist[0]:=’’;
wordlist[1]:=‚1‘;
wordlist[2]:=‚2‘;
while( counter 0) do begin// Solange noch etwas zu berechnen ist
// bestimme die naechste Ziffer des Zaehlers
// in der n+1 Darstellung („von rechts nach links“)
cmod := cdiv MOD (n+1);

// die momentan berechnete Ziffer ist der Index fuer das naechst
// zu verwenende Wort in der Liste der Woerter
// word[0] muss der leere String „“ sein !!
output := wordlist[cmod] + output; // „+“ meint Konkatenation

// berechne was bleibt, wenn wir die gerade
// behandelte Ziffer raus dividieren
cdiv :=ROund(cdiv / (n+1)); // das „/“ hier MUSS die integer
// division sein! auf keinen Fall eine
// fuer floating point
end;
form1.test.Lines.Add(output);
form1.test.Update;
counter:=counter+1;
end;
end;

Hallo Rokdd,

hilft es schon wenn jeder string nur maximal 3 mal vorkommen
darf oder? Das würde vielleicht auch reichen…

Ja, dann gibt es wenigstens eine endliche Lösungsmenge und somit wird dein Programm irgendeinmal fertig sein.
Dein Problem ist, dass du nicht begreifst welche Datenmenge du da fabrizieren willst.

Nur schon einmal bibär betrachtet:
Für jeden deiner 50 Strings nimmst du ein Bit um ihn sichtbar oder unsichtbar zu schalten, die 50 Strings bleiben aber immer in der gleichen Rehenfolge.
Dies sind 2^50 = 1.125 * 10^15 Möglichkeiten (inklusive 1x gar nichts).

Nehmen wird einmal an du willst das Ausdrucken:
Mit kleiner Schrift bekommst du 100 Zeilen auf ein Blatt, zudem nehmen wird an ein Ergebnis passt immer auf eine Zeile:
Dann brauchst du 1.125 * 10^13 Blätter.
Ein Blatt hat eine Dicke von 0.1 mm
Damit wird dein Stapel 1.125 * 10^12 mm Hoch

1.125 * 10^12 mm = 1.125 * 10^9 m = 1.125 * 10^6 km = 1’125’000km
Nur so zum Vergleich:
Flughöhe eines Flugzeugs : ca. 10km
Flughöhe Spaceshuttle: ca. 300km
Abstand Erde Mond: ca 300’000 km

Nehmen wir mal an dein Laserdrucker druckt 20 Blatt/Minute:

1.125 * 10^13 Blätter = 5.652 * 10^11 Minuten Druckdauer (Ohne Papier und Toner nachfüllen und ohne Reparaturen.)

5.652 * 10^11 Min = 9.375 * 10^9 Stunden = 3.90525 * 10^8 Tage
(Ein Jahr hat im Mittel etwa 365.25 Tage)
= 1.069 * 10^6 Jahre
Also rund 1 Million Jahre !!

Was im Himmelswillen willst du damit anfangen ???

MfG Peter(TOO)

Hi rokdd,

habe da aber

noch ein frage: du hast geschrieben dass word bei mir wordlist
der gegebene stringarray ist, oder? die äussere schleife geht
aber weit über die länge der wordlist über hinaus,da du ja die
schleife n+1 m laufen lasst willst! da habe ich wahrscheinlich
irgendetwas schief verstanden…

irgendwas stimmt mit dem Satz oben nicht; jedenfalls versteh ich ihn nicht geanu. Die auessere Schleife zaehlt alle moeglichen Kombinationen von m aus einer Liste von n+1 strings auf. Das sind *viel* mehr (ca (n+1)^m) als die Laenge der Wortliste (n+1, wenn man den leeren String mitzaehlt).

In Deinem Programm muss n=2 sein und nicht 3. Du hast nur zwei Strings 1 und 2. So habe ich jedenfalls n bisher immer benutzt, als Anzahl tatsaechlicher Strings. Du kannst natuerlich auch n auf 3 setzen und dafuer uebrall wo (n+1) steht nur noch n schreiben.

Ausserdem verwendest Du Round() fuer die Integerdivision. Da solltest Du Floor() benutzen, wenn es das in Deiner Programmiersprache gibt.
Round kann auch nach oben aufrunden, Du brauchst aber immer nur den ganzzahligen Anteil der Kommazahlen, die bei Floatingpointdivision entstehen. I.P geht es auch so:
cdiv = (cdiv/(n+1)) - ( (cdiv MOD (n+1)) / (n+1))
wobei „/“ hier die floating point division ist.
(Viele Compiler nehmen uebrigens automatisch Integerdivision, wenn die verwendeten Ausdruecke Integers sind; hast Du das getestet? Dann reicht naemlich cdiv = cdiv/(n+1);

Statt m=15 reicht es wohl mit etwas kleineren Stringlaengen zu testen

Realsharkies Algorithmus funktioniert uebrigens wahrscheinlich so aehnlich wie der von mir.

Ciao,
Thomas

PS: Sushi find ich auch lecker

PPS: Falls Du die Ausgabestrings der Groesse ( = Anzahl der substrings) sortiert haben willst, geht’s auch so:

Du laesst den leeren String in der Wortliste weg und fuegst den bisherigen Code in eine neue Schleife ein:

int mmax = 15;
for ( m=0; m

Danke,
hat funktioniert! hat zwar ganz schön gedauert… aber super!

rokdd