Discussion:
alle Zahlenkombinationen einer Auswahl erstellen
(zu alt für eine Antwort)
Dennis Reinert
2005-08-10 09:28:08 UTC
Permalink
Ich will aus einer Zahlengruppe von 60 Zahlen alle möglichen
Kombinationen erstellen und ausgeben.

Mit der Random Klasse scheint mir das zu umständlich. Hält java noch
andere Klassen zur Realisierung bereit oder hat jemand eine Idee,
wie man das verwirklichen kann?


Gruß Dennis
Ingo R. Homann
2005-08-10 09:37:56 UTC
Permalink
Hi,
Post by Dennis Reinert
Ich will aus einer Zahlengruppe von 60 Zahlen alle möglichen
Kombinationen erstellen und ausgeben.
Du weisst, dass das *viele* sind? (*)
Post by Dennis Reinert
Mit der Random Klasse scheint mir das zu umständlich.
Mit der Random-Klasse geht das IMHO gar nicht!
Post by Dennis Reinert
Hält java noch
andere Klassen zur Realisierung bereit oder hat jemand eine Idee,
wie man das verwirklichen kann?
(*) Erstmal solltest Du spezifizieren, was "alle möglichen
Kombinationen" sind: Eine feste Länge von N Zahlen aus dem Bereich
[0-60]? Oder aus dem Bereich [1-60]? Oder immer alle 60 Zahlen, nur in
unterschiedlicher Reihenfolge? Mit oder ohne Widerholungen?

Der übliche Ansatz dafür ist rekursiv: Du kannst die Kombinationen für N
Zahlen zurückführen auf die Kombinationen von N-1 Zahlen. So reduzierst
Du den Aufwand immer weiter bis zu einem "Startwert" (Die Kombiantionen
von einer Zahl ist nur eine.)

Ciao,
Ingo
Dennis Reinert
2005-08-10 09:48:07 UTC
Permalink
Sicher sind das viele Kombinationen aber dafür soll das Programm auch
gedacht sein.
Die Idee ist, dass der Nutzer entscheiden kann, welche Zahlen er aus dem
Pool von 1 bis 60
in die Berechnung einfließen kann. Dabei besteht auch die Möglichkeit ebend
alle Zahlen zu
nutzen. Weiterhin kann er auswählen, ob er nur 1,2,3 bis alle Kombinationen
anzeigen lässt.

Mit Random bekomme ich zumindest eine Reihe aus allen Zahlen hin und mit
einer Schleife
die Anzahl der gewünschten Reihen. Dabei fehlt allerdings 1. ob der die
Kombination bereits vorkam und 2. die Auswahl aus dem Pool der Menge 1 bis
60 nur eine gewisse Anzahl aber nicht weniger als 10 auszuwählen.
Post by Ingo R. Homann
Hi,
Post by Dennis Reinert
Ich will aus einer Zahlengruppe von 60 Zahlen alle möglichen
Kombinationen erstellen und ausgeben.
Du weisst, dass das *viele* sind? (*)
Post by Dennis Reinert
Mit der Random Klasse scheint mir das zu umständlich.
Mit der Random-Klasse geht das IMHO gar nicht!
Post by Dennis Reinert
Hält java noch
andere Klassen zur Realisierung bereit oder hat jemand eine Idee,
wie man das verwirklichen kann?
(*) Erstmal solltest Du spezifizieren, was "alle möglichen Kombinationen"
sind: Eine feste Länge von N Zahlen aus dem Bereich [0-60]? Oder aus dem
Bereich [1-60]? Oder immer alle 60 Zahlen, nur in unterschiedlicher
Reihenfolge? Mit oder ohne Widerholungen?
Der übliche Ansatz dafür ist rekursiv: Du kannst die Kombinationen für N
Zahlen zurückführen auf die Kombinationen von N-1 Zahlen. So reduzierst Du
den Aufwand immer weiter bis zu einem "Startwert" (Die Kombiantionen von
einer Zahl ist nur eine.)
Ciao,
Ingo
Ingo R. Homann
2005-08-10 11:18:11 UTC
Permalink
Hi,
Post by Dennis Reinert
Mit Random bekomme ich zumindest eine Reihe aus allen Zahlen hin und mit
einer Schleife
die Anzahl der gewünschten Reihen. Dabei fehlt allerdings 1. ob der die
Kombination bereits vorkam und 2. die Auswahl aus dem Pool der Menge 1 bis
60 nur eine gewisse Anzahl aber nicht weniger als 10 auszuwählen.
Ebend. Random ist dafür völlig ungeeignet. Da kannst Du auch die
System.currentTimeMillis() nehmen und dieselben Probleme beklagen! ;-)

Ciao,
Ingo
Stefan Matthias Aust
2005-08-10 09:47:34 UTC
Permalink
Post by Dennis Reinert
Ich will aus einer Zahlengruppe von 60 Zahlen alle möglichen
Kombinationen erstellen und ausgeben.
Das sind aber ziemlich viele. Falls du alle Permutationen einer
60-elementigen Liste meinst, sind das AFAIK
8320987112741390144276341183223364380754172606361245952449277696409600000000000000
Varianten. Angenommen, du kannst 100.000 Permutationen pro Sekunde
ausgeben, sind das glaube ich immer noch 10-hoch-157 Jahre!
--
Stefan Matthias Aust // Lassen Sie uns durch, wir sind Arzt!
Stefan Matthias Aust
2005-08-10 09:54:38 UTC
Permalink
Angenommen, du kannst 100.000 Permutationen [...]
Oops, eine Million meinte ich. Spielt aber bei diesen Zeiten keine
Rolle. Ein einfacher Algorithmus ist übrigens

Sei p die Liste mit 60 Elementen. Gibt jedes Element gefolgt von allen
Permutation der übrigen Elemente aus. Die Permutation der einelementigen
Liste ist die Liste selbst.
--
Stefan Matthias Aust // Lassen Sie uns durch, wir sind Arzt!
Jochen Theodorou
2005-08-10 09:56:19 UTC
Permalink
Post by Dennis Reinert
Ich will aus einer Zahlengruppe von 60 Zahlen alle möglichen
Kombinationen erstellen und ausgeben.
also unendlich viele?

Ansonsten bei fester Länge, ohne Wiederholungen und wenn Permutationen
unwichtig sind: (in groovy)

int[] numbers = [1,2,3,4,5]
int MAX_NUMBERS=numbers.length

def printCombination(int n, marked, selected) {
if (n<=0) {
for (i in 0..<selected.length) print "${selected[i]} "
println()
return
}
for (i in 0..<MAX_NUMBERS) {
if (marked[i]) continue
marked[i] = true
selected[n-1]=numbers[i]
printCombination(n-1,marked,selected)
marked[i] = false
}
}

def printCombination(int n) {
printCombination(n, new boolean[MAX_NUMBERS], new int[n])
}

printCombination(3) // alle Kombinationen der Länge 3

aber irgendwie glaube ich nicht dass es das ist was du willst.
Post by Dennis Reinert
Mit der Random Klasse scheint mir das zu umständlich.
mir scheint Random hier gänzlich ungeeignet zu sein
Post by Dennis Reinert
Hält java noch
andere Klassen zur Realisierung bereit oder hat jemand eine Idee,
wie man das verwirklichen kann?
sobald ich weiss was du eigentlich willst. ein kleines Beispiel vielleicht?


Gruss theo
Dennis Reinert
2005-08-10 10:23:42 UTC
Permalink
Es stellt etwas ähnliches wie ein Lotto System dar.

Mit Random wäre ich in der Lage Zufallszahlen aus einem Pool von 49 Zahlen
zu erstellen. Nun will ich, dass ein Benutzer aus dem Pool von 60 Zahlen
zufällig generierte Folgen von jeweils 6 Zahlen erstellen kann.

Dabei soll er zusätzlich in die Lage versetzt werden, aus diesem Pool nur
beliebige Zahlen für die Generierung der 6er Reihe zu erstellen. Allerdings
soll er dabei minimum 10 Zahlen angeben (OK, dass ist simpel lösbar).

Also ich vergaß zu erwähnen

Menge: N von 1 bis 60
Zufallszahlen immer 6 Stück aus der Menge N

Begrenzen wir mal die Anzahl der möglichen 6er Kombis auf eine
festeinstellbare Menge von
maximal 20 Kombinationen.
Post by Jochen Theodorou
Post by Dennis Reinert
Ich will aus einer Zahlengruppe von 60 Zahlen alle möglichen
Kombinationen erstellen und ausgeben.
also unendlich viele?
Ansonsten bei fester Länge, ohne Wiederholungen und wenn Permutationen
unwichtig sind: (in groovy)
int[] numbers = [1,2,3,4,5]
int MAX_NUMBERS=numbers.length
def printCombination(int n, marked, selected) {
if (n<=0) {
for (i in 0..<selected.length) print "${selected[i]} "
println()
return
}
for (i in 0..<MAX_NUMBERS) {
if (marked[i]) continue
marked[i] = true
selected[n-1]=numbers[i]
printCombination(n-1,marked,selected)
marked[i] = false
}
}
def printCombination(int n) {
printCombination(n, new boolean[MAX_NUMBERS], new int[n])
}
printCombination(3) // alle Kombinationen der Länge 3
aber irgendwie glaube ich nicht dass es das ist was du willst.
Post by Dennis Reinert
Mit der Random Klasse scheint mir das zu umständlich.
mir scheint Random hier gänzlich ungeeignet zu sein
Post by Dennis Reinert
Hält java noch
andere Klassen zur Realisierung bereit oder hat jemand eine Idee,
wie man das verwirklichen kann?
sobald ich weiss was du eigentlich willst. ein kleines Beispiel vielleicht?
Gruss theo
Timo Stamm
2005-08-10 11:07:36 UTC
Permalink
Post by Dennis Reinert
Es stellt etwas ähnliches wie ein Lotto System dar.
Mit Random wäre ich in der Lage Zufallszahlen aus einem Pool von 49 Zahlen
zu erstellen. Nun will ich, dass ein Benutzer aus dem Pool von 60 Zahlen
zufällig generierte Folgen von jeweils 6 Zahlen erstellen kann.
private static int max = 60;
private static int len = 6;

public int[] get() {
int[] s = new int[len];
Random r = new Random(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
s[i] = r.nextInt(max) + 1;
}
return s;
}
Post by Dennis Reinert
Dabei soll er zusätzlich in die Lage versetzt werden, aus diesem Pool nur
beliebige Zahlen für die Generierung der 6er Reihe zu erstellen. Allerdings
soll er dabei minimum 10 Zahlen angeben (OK, dass ist simpel lösbar).
private static int len = 6;

public int[] get(int[] pool) throws NotEnoughNumbersException {
if (pool.length < 10) {
throw new NotEnoughNumbersException();
}
int[] s = new int[len];
Random r = new Random(System.currentTimeMillis());
for (int i = 0; i < len; i++) {
s[i] = pool[r.nextInt(pool.length)];
}
return s;
}
Post by Dennis Reinert
Also ich vergaß zu erwähnen
Menge: N von 1 bis 60
Zufallszahlen immer 6 Stück aus der Menge N
Begrenzen wir mal die Anzahl der möglichen 6er Kombis auf eine
festeinstellbare Menge von
maximal 20 Kombinationen.
Das sind zwei verschiedene Aufgaben. Versuche nicht, beide gleichzeitig
zu lösen. Wie oft du get() in obigen Beispielen aufrufst bleibt dir
überlassen.


Vorsicht: Random ist ein Pseudo-Zufallsgenerator!


Timo
Jochen Theodorou
2005-08-10 11:24:42 UTC
Permalink
Post by Dennis Reinert
Es stellt etwas ähnliches wie ein Lotto System dar.
Mit Random wäre ich in der Lage Zufallszahlen aus einem Pool von 49 Zahlen
zu erstellen. Nun will ich, dass ein Benutzer aus dem Pool von 60 Zahlen
zufällig generierte Folgen von jeweils 6 Zahlen erstellen kann.
das ist etwas ganz anderes. Aber du brauchst doch nur eine Folge, oder?
Post by Dennis Reinert
Dabei soll er zusätzlich in die Lage versetzt werden, aus diesem Pool nur
beliebige Zahlen für die Generierung der 6er Reihe zu erstellen.
Heisst das er soll sagen können, welche Zahlen für die Reihe genommen
werden dürfen bzw. welche nicht?
Post by Dennis Reinert
Allerdings
soll er dabei minimum 10 Zahlen angeben (OK, dass ist simpel lösbar).
Also ich vergaß zu erwähnen
Menge: N von 1 bis 60
Zufallszahlen immer 6 Stück aus der Menge N
ja offensichtlich nicht aus, sondern aus M, wobei M Teilmenge von N ist
und mindestens die Mächtigkeit 10 besitzt und die vom Benutzer gewählten
Zahlen darstellt, oder?
Post by Dennis Reinert
Begrenzen wir mal die Anzahl der möglichen 6er Kombis auf eine
festeinstellbare Menge von
maximal 20 Kombinationen.
wieso? Die Zahl der möglichen 6er Kombis hängt von der Mächtigkeit von M ab.

natürlich kannst du ausrechnen für welche Mächtigkeit du 20
Post by Dennis Reinert
/ |M| \
| | == 20
\ 6 /
m! m!
-------- == 20 --> 20*6! == -------- ==(m-5)*(m-4)*...*(m)
(m-6)!6! (m-6)!
bei m=7 hiesse dass:

20*6! == 7! --> 20=7, zu klein

bei m=8:
20*6! == 8!/2! --> 2*20 == 7*8 --> 40==56, zu gross


die Lösung läge also zwischen 7 und 8


Ich nehme an dein Problem ist a) eine 6er Reihe wählen ohne eine Zahl
doppelt zu wählen b) mehrere 6er Reihen zu wählen ohne eine zu
wiederholen. Stimmt das?


Gruss theo
Peter Büttner
2005-08-10 11:33:52 UTC
Permalink
Post by Dennis Reinert
Es stellt etwas ähnliches wie ein Lotto System dar.
Mit Random wäre ich in der Lage Zufallszahlen aus einem Pool von 49 Zahlen
zu erstellen. Nun will ich, dass ein Benutzer aus dem Pool von 60 Zahlen
zufällig generierte Folgen von jeweils 6 Zahlen erstellen kann.
Dabei soll er zusätzlich in die Lage versetzt werden, aus diesem Pool nur
beliebige Zahlen für die Generierung der 6er Reihe zu erstellen. Allerdings
soll er dabei minimum 10 Zahlen angeben (OK, dass ist simpel lösbar).
Also ich vergaß zu erwähnen
Menge: N von 1 bis 60
Zufallszahlen immer 6 Stück aus der Menge N
Begrenzen wir mal die Anzahl der möglichen 6er Kombis auf eine
festeinstellbare Menge von
maximal 20 Kombinationen.
Ah, nun wird es klarer. Fragen stellen scheint teilweise nicht so einfach.
Das /alle/ Kombinationen aus deinen bisherigen Aussagen ist der Ansatz:
Erst mal alles sammeln, dann seh'n wie weiter. Das sowas recht lange
dauern kann sieht man gut.


Zum Problem:
Ist doch ganz einfach, du hast eine Liste S von n Elementen und willst
daraus m zufällige Teilreihen R mit je k Elementen erstellen. Die
Reihenfolge der Elemente in R ist dabei zu vernachlässigen -
Permutationen sind also als gleich anzusehen.

(Das S nur ein Teil aus der Gesamtliste ist ist unerheblich)

Nette kleine Aufgabe zur Entspannung. Diese Lösung ist nicht
superschnell, aber recht kompakt.
---------------------------------------------------------------
import java.util.*;

public class LottoAlike {

public static void main(String[] args) {
List all = new ArrayList();// input bauen
for(char c='a';c<='z'; c++) all.add( String.valueOf(c));

Collections.shuffle(all); // mischen
List selection = all.subList(0,10);// Die Auswahl

Set rows = new LottoAlike().makeRows(selection, 5, 6);
System.out.println(rows);
}
/*
* numRows kombinationen (länge rowSize) aus list erstellen
*/
Set makeRows(List list, int numRows, int rowSize) {
list = new ArrayList(list); // copy wegen shuffle, s.u.

Set rows = new HashSet(); // gewürfelte reihen, Set: gleiche nur 1x
/*
* hier kann man durchaus in eine Endlosschleife kommen,
* wenn alle Kombis da sind oder immer diesselbe kommt.
* Da muß man viel schlauer werden, oder einfach nach
* 10*NUM_ROWS eine Exception werfen
*/
while(rows.size()<numRows){
// zufällige teilmenge mit rowSize elementen, ergebnis ist sortiert
Collections.shuffle(list); // würfeln
List candidate = new ArrayList(list.subList(0,rowSize)); // lies
subList doku
Collections.sort(candidate);// permutationen erkennen

rows.add(candidate); // dupes werden erkannt
}
return rows;
}
}
---------------------------------------------------------------




Grüße
Peter
--
Shell&Jar : Individual icons for jars
jMineSweeper : extended
www.PeterBuettner.de
Ralf Ullrich
2005-08-10 10:43:04 UTC
Permalink
Post by Dennis Reinert
Ich will aus einer Zahlengruppe von 60 Zahlen alle möglichen
Kombinationen erstellen und ausgeben.
static void main(String... args) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 60; i++) list.add(i);
printPerms(list);
}

void printPerms(List<T> list) {
if (list.size() == 0) System.out.println();
for (int i = 0; i< list.size(); i++) {
System.out.print(list.get(i)+" ");
List<T> copy = new ArrayList<T>(list);
copy.remove(list.get(i));
printPerms(copy);
}
}

Laufzeit: Länger als das Universum existiert.

Wenn du es etwas zufälliger und nur eine bestimmte Anzahl haben willst,
dann kannst du es wie folgt anpassen:

class Counter {
long count;
}

static void main(String... args) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 60; i++) list.add(i);

// show 100 perms with 10 number out of 60;
Collections.shuffle(list);
printPerms(list, new Counter(100), list.size()-10);
}

boolean printPerms(List<T> list, Counter numPerms, long numRemain) {
if (list.size() <= numRemain) {
System.out.println();
numPerms.count--;
return numPerms.count > 0;
} else {
for (int i = 0; i< list.size(); i++) {
System.out.print(list.get(i)+" ");
List<T> copy = new ArrayList<T>(list);
copy.remove(list.get(i));
Collections.shuffle(copy);
if (! printPerms(copy, numPerms, numRemain)) {
return false;
}
}
return true;
}
}


(Code im Mail-Editor geschrieben, ungetestet!)
Loading...