Best Practice Ein int Array richtig mischen

  • Themenstarter Themenstarter Xyz1
  • Beginndatum Beginndatum
X

Xyz1

Gast
Java:
public static void mischen(int[] array, float n, Random r) {
	double n1 = n;
	int n2 = (int) (array.length * n1);
	for (int i = 0; i < n2; i++) {
		swap(array, r.nextInt(array.length), r.nextInt(array.length));
	}
}

public static void swap(int[] array, int i1, int i2) {
	int i = array[i1];
	array[i1] = array[i2];
	array[i2] = i;
}

public static float permutability(int[] array1, int[] array2) {
	int s = 0;
	for (int i = 0; i < array1.length; i++) {
		if (array1[i] == array2[i]) {
			s++;
		}
	}
	return (float) s / (float) array1.length;
}

public static void main(String[] args) throws Exception {
	int length = 1000;
	int[] array1 = new int[length];
	int[] array2 = new int[length];
	for (int i = 0; i < length; i++) {
		array1[i] = i;
	}
	System.arraycopy(array1, 0, array2, 0, length);

	for (int i = 0; i <= 5; i++) {
		mischen(array2, (float) (i / 2.0), new Random());
		System.out.println(permutability(array1, array2));
		System.arraycopy(array1, 0, array2, 0, length);
	}
}


Hallo, meine Frage wäre nun, wie ich bei mischen(int[] array, float n, Random r) n wählen muss, damit das int Array wirklich richtig gemischt wäre...

Achso das Ergebnis noch:
Code:
1.0
0.367
0.139
0.055
0.019
0.006
 
Für 100_000 ist das Ergebnis ähnlich:
Code:
1.0
0.36743
0.13581
0.05016
0.01805
0.00672
0.00269
8.6E-4
2.1E-4
2.1E-4
8.0E-5


Aber es ist zu erkennen dass wir nur annäherungsweise an die 0 kommen...
 
Deine permutability sagt nichts über "Zufälligkeit" aus.

Nimm etwas gegen die Variante von Collections#shuffle (müsste ne Variante von Knuths Shuffle sein)?
 
Bei Knuths Shuffle wäre der erste Parameter i oder? Also swap(array, i, r.nextInt(array.length));?

Und eine Methode die wirklich die "Zufälligkeit" angibt weiß ich nicht.
 
Was ist perfekt gemischt? Ich würde das so definieren, dass die Wahrscheinlichkeit für jeden Zahl and jede Position des Arrays zu kommen gleich hoch ist...

Also aus der Praxis: wenn du Karten ‚richtig‘ mischst, dann besteht immer die Chance, dass eine Karte wieder auf dem Platz ist, auf dem sie vorher war. Also rein aus dieser Vorstellung heraus sollte doch eigentlich deutlich werden, dass dies keine Aussagekraft hat.

Man kann das auch mathematisch betrachten. Wenn du perfekt gemischt hast, dann kannst du die Wahrscheinlichkeit ja berechnen. Wenn du perfekt 52 Karten gemischt hast, dann ist die Chance für jede Karte die erste zu sein, genau 1/52.
So kann man für jede Zusammenstellung genau die Wahrscheinlichkeit berechnen.
Aber vom Verständnis her: wenn du perfekt gemischt hast und nun die erste Karte doch wieder die erste Karte ist: das ändert doch nichts daran, dass du perfekt gemischt hast. Das ist ja schlicht eine Frage der Wahrscheinlichkeit.

Evtl wird dadurch die Betrachtung deutlicher.
 
Ja das stimmt schon @kneitzel . Man würde aber trotzdem nicht sagen, wenn 1/3 der Karten an ihrem Platz bleiben, dass "gut" vom Croupier gemischt wurde...
 
Und eine Methode die wirklich die "Zufälligkeit" angibt weiß ich nicht.
Das kann man durch ausreichend viele Tests machen. Sowie du einen Würfel ganz oft nutzen kannst um dann festzustellen, ob jede Ziffer im Schnitt gleich oft kommt, kannst du auch ein Array nehmen und es zig mal durcheinander bringen. Nach jedem Mal prüfst du, welche Ziffer an welcher Stelle ist.

Also z.B. Länge des Arrays ist n, dann hast du ein zweidimensionales Array von n mal n als Zähler und nach jedem shuffel gehst du dein Array durch und erhöhst denn jeweiligen Wert.
Nach x Tests sollte überall ca. x/n sein.

Wichtig ist: Durchlauf meint ein ganzes Shuffeln. Also wenn du meinst, dass du für ein Array der Größe n von mir aus n Mal Paare tauschen willst, dann machst Du das auch entsprechend oft.

Der Test wird also extrem umfangreich, da du verschiedene Arraygrößen und auch verschiedene Anzahl der Pärchen-Täusche haben willst....
 
Ja das stimmt schon @kneitzel . Man würde aber trotzdem nicht sagen, wenn 1/3 der Karten an ihrem Platz bleiben, dass "gut" vom Croupier gemischt wurde...
Das ist einfach eine Frage der Zufälligkeit. Wenn letzte Woche bestimmte 6 Lottozahlen gezogen wurden, dann würde jeder sagen: es ist etwas faul, wenn diese beim nächsten Mal erneut gezogen werden. Aber Fakt ist: die Wahrscheinlichkeit ist erneut gleich hoch....

Und man kann die Wahrscheinlichkeit sogar berechnen ... und bei einem Kartenspiel mit 52 Karten und jemandem, der das Hauptberuflich macht und im Schnitt x Mal die Karten am Tag gibt ... ich wäre nicht überrascht, wenn raus kommt, dass genau sowas mit relativ hoher Wahrscheinlichkeit vorkommen wird...
 
deterministisches Mischen will gelernt sein 😛
wenn man so möchte, so ist obiges auch deterministisches Mischen 😛

Ne aber wirklich... RTL, die Moderatorin oder die Zuschauer oder alle schienen wohl mit der Situation überfordert gewesen...

BTW... ich spiele mal ne Runde Poker. 🙂

(Schade... dass Raab in Rente gegangen ist.)
 
Könnt ihr mir sagen was hieran nicht richtig ist?
Java:
	public static float permutability(int[] array1, int[] array2) {
		int ex = 0;
		double d = 0;
		for (int i = 1; i < 1000; i++) {
			d += Math.pow(1.0 / array1.length, i);
			if (d >= 0.5) {
				ex = i;
				break;
			}
		}
		int s = 0;
		for (int i = 0; i < array1.length; i++) {
			if (array1[i] == array2[i]) {
				s++;
			}
		}
		return Math.abs((float) (s - ex) / (float) array1.length);
	}

	public static void main(String[] args) throws Exception {
		int length = 10_000;
		int[] array1 = new int[length];
		int[] array2 = new int[length];
		for (int i = 0; i < length; i++) {
			array1[i] = i;
		}
		System.arraycopy(array1, 0, array2, 0, length);

		for (int i = 0; i <= 100; i++) {
			mischen(array2, (float) (i / 2.0), new Random());
			System.out.println(permutability(array1, array2));
			System.arraycopy(array1, 0, array2, 0, length);
		}
	}


Der Erwartungswert ist nicht 0 sondern bei length 10000 ca 1.0E-4. Diesen will ich davon abziehen um 0 zu erhalten.
 

Zurück
Oben