Sagen wir, ich habe ABCDEF
. Dann sind es 6! Permutationen der Neuordnung dieser Zeichenfolge. Nun möchte ich nur auf die Permutationen eingehen, in denen es keine benachbarten Zeichen gibt. Das heißt, ich will an allen Permutationen suchen, die diese Bedingungen erfüllen:Algorithmus zum Generieren aller Permutationen einer Zeichenfolge ohne benachbarte Zeichen
- B ist nicht neben A oder C
- C nicht weiter nach B oder D
- D ist nicht neben C oder E
- E nicht neben D oder F
diesen Algorithmus Mein Ansatz ist der folgende Pseudo-Code:
//generate all 6! permutations
//check all permutations and see where B is next to A || C
//remove all instances
//check all permutations and see where C is next to D
//remove all instances
//check all permutations and see where D is next to E
//remove all instances
//check all permutations and see where E is next to F
//remove all instances
Diese Maskierungsoperationen werden jedoch sehr ineffizient und dauern viel zu lange, besonders wenn meine Stringlänge größer als 6 ist. Wie kann ich das effizienter machen? Ich sehe diese ähnlichen Beiträge, 1, 2, und hoffte, einige Schlüsselideen zu extrahieren, die mir helfen könnten. Dies ist jedoch auch eine Brute-Force-Prüfung. Ich möchte eigentlich nur die einzigartigen Muster von Anfang an generieren und nicht alles erzeugen und eins nach dem anderen überprüfen.
EDIT: Derzeit ist das, was ich benutze, um alle Permutationen zu generieren.
static String[] designs;
static int index;
protected static String[] generateDesigns(int lengthOfSequence, int numOfPermutations){
designs = new String[numOfPermutations];
StringBuilder str = new StringBuilder("1");
for(int i = 2; i <= lengthOfSequence; i++)
str.append(i);
genDesigns("", str.toString()); //genDesigns(6) = 123456 will be the unique characters
return designs;
}
//generate all permutations for lenOfSequence characters
protected static void genDesigns(String prefix, String data){
int n = data.length();
if (n == 0) designs[index++] = prefix;
else {
for (int i = 0; i < n; i++)
genDesigns(prefix + data.charAt(i), data.substring(0, i) + data.substring(i+1, n));
}
}
Hmm, machen wir eine grobe Schätzung. Bei einer Zufallsperm für n Buchstaben beträgt die Wahrscheinlichkeit, dass zwei bestimmte Buchstaben nebeneinander liegen, 2 (n-1)/(n (n-1)) = 2/n. Da wir n-1 dieser Constraints haben, sagt eine handwellige Unabhängigkeitsannahme aus, dass eine zufällige Perm mit Wahrscheinlichkeit ungefähr (1-2/n)^(n-1) ≈ 1/e^2 ≈ 0,135 für großes n gültig ist . Wenn dies eine vernünftige Schätzung ist, dann können Sie nicht auf große Gewinne hoffen - es gibt zu viele gültige Dauerwellen (eins in sieben oder acht)! –
Hmm, hier ist die tatsächliche Gleichung, die verwendet wird, um zu bestimmen, wie viele solcher Permutationen es gibt: "Die Wahrscheinlichkeit, dass Nachbarn nach zufälligen Umordnungen Nachbarn bleiben", Amer. Mathematik. Monthly 87 (1980), 122-124 –
Gleiche Formel. Gut zu wissen, dass es eine formale Herleitung gibt (aber ich bin überhaupt nicht überrascht). –