Algoritmus für 3er-Paare von n Zahlen

Status
Nicht offen für weitere Antworten.

Pfeiffy

Mitglied
Hallo,
irgendwie stehe ich gerade auf dem Schlauch und bekomme es einfach nicht hin: folgendes Problem:
ich habe n Zahlen 1,2....n, aus diesen sollen alle Kombinationen von 3e-Paaren ermittelt werden, jedes 3er-Paar soll jedoch nur einmal vorkommen, und jede Zahl nu 1 mal im Paar Reihenfolge ist egal
Beispiel: Zahlen: 1,2,3,4
Erg:
1,2,3
1,2,4
1,3,4
2,3,4
Wie kann ich das in Java programmieren?

Gruß und Dank
Pfeiffy
 
S

SlaterB

Gast
du brauchst drei Schleifen oder eine Rekursion, die beliebig viele Schleifen zulässt,

in der ersten Schleife wählst du als erstes die 1,
in der zweiten Schleife wählst du als erstes die nächst höhere Zahl, die 2,
in der dritten Schleife wählst du als erstes die nächst höhere Zahl, die 3,
dann hast du die erste Kombination gefunden (1,2,3),

nun wird munter hochgezählt, wie man es bei ineinander geschachtelten Schleifen so kennt natürlich erstmal in der inneren Schleife,
in der dritten Schleife kommt nach 3 die 4 -> 1,2,4 gefunden,

da 4 der Maximalwert ist ist die dritte Schleife vorerst beendet, die zweite Schleife wieder dran, statt 2 dort nun 3 und die dritte Schleife muss wieder arbeiten (die jetzt nicht auch 3 wählen darf, sondern bei 4 anfangen muss)

so bekommst du nach und nach alle erlaubten Kombinationen,
wichtig ist, dass jede Schleife den aktuellen Wert der vorherigen berücksichtigt,

mit Rekursion ist das recht elegant zu lösen, für den Anfang solltest du aber verschachtelte Schleifen verwenden,
fange z.B. zunächst mit zwei Schleifen an und einer Ausgabe
1,2
1,3
1,4
2,3
2,4
3,4
 

Marco13

Top Contributor
Eine erwas zu pauschale Aussage. Man kann viele Probleme sehr elegant mit Rekursion lösen, bei denen eine iterative Lösung ein ziemlicher K(r)ampf wäre :autsch: Insbesondere, wenn die Laufzeit exponentiell mit der Rekursionstiefe steigt, dürfte der Spiecher das geringste Problem sein :wink:
 

Maeher

Bekanntes Mitglied
Marco13 hat gesagt.:
Man kann viele Probleme sehr elegant mit Rekursion lösen, bei denen eine iterative Lösung ein ziemlicher K(r)ampf wäre
Ich hatte mal eine Variante geschrieben, die ohne Rekursion aus einer beliebigen Kombination die jeweils nächste geliefert hat, bin gerade auf der Suche, war aber glaube ich in C++.
Die Rechenzeit war mit Abstand das größte Problem, solange man nicht auf die Idee kommt alle Ergebnisse speichern zu wollen. Der Vorteil bei dieser Lösung ist, dass man die Funktion von überall her aufrufen kann, während man bei einer Rekursion die Verwendung der Ergebniskombinationen irgendwie fest einbauen muss.
(Editiert)
Edit: hab's gefunden und Java draus gemacht, ist aber nicht wirklich schön...
 

0x7F800000

Top Contributor
Also, ich hätte hier eine ziemlich allgemeine Lösung, die für eine endliche Menge alle Teilmengen der festgelegten Größe liefert:

Code:
import java.util.*;

public class FiniteSubsets {
	
	/** getSubsets
	 * 
	 * @param <T>	any Type 
	 * @param S		a finite Set with elements of Type T
	 * @param n		size of subsets
	 * @return		set of subsets of S that have size n
	 */
	
	public static <T> Set<Set<T>> getSubsets(Set<T> s, int n){
		
		Set<Set<T>> resultingSetOfSubsets=new HashSet<Set<T>>();
		
		if(n<=0){	
			//the set of subsets with size=0 contains only the empty subset
			//the result IS NOT EMPTY, it's a set that contains the empty set!
			resultingSetOfSubsets.add(new HashSet<T>());
		}else{		
			//return all nonempty subsets
			for(T e:s){
				//take the element e out of the finite Set s and calculate all (n-1)-Subsets of s\e
				Set<T> s_e=new HashSet<T>(s); s_e.remove(e);
				Set<Set<T>> subsetsOfS_e=getSubsets(s_e, n-1);
				
				//now reunite each subset of s\e with {e}
				//and add the result into the set of subsets of s
				for(Set<T> subsetOfS_e : subsetsOfS_e){
					subsetOfS_e.add(e);				//reunite with {e}
					resultingSetOfSubsets.add(subsetOfS_e);	//add to the set of subsets of s
				}
			}
		}
		
		return resultingSetOfSubsets;
	}
	
	// TEST
	public static void main(String[] args){
		//array int[] is autoboxed to Integer[], transformed into List and added to HashSet...
		//looks a little bit complicated^^
		HashSet<Integer> s=new HashSet<Integer>(Arrays.asList(new Integer[]{1,2,3,4,5}));
		
		//now get all subsets of s with size=3
		Set<Set<Integer>> subsets=getSubsets(s,3);
		
		//print the result
		System.out.println("Set\t\t="+s);
		System.out.println("Set of Subsets\t="+subsets);
		
	}
}

auf dieses konkrete Beispiel bezogen liefert es zum beispiel für die menge {1,2,3,4,5} alle teilmengen mit Betrag 3:
Set =[1, 2, 3, 4, 5]
Set of Subsets =[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [2, 3, 4], [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5], [3, 4, 5]]
Das sind auch genau (5 über 3) stück...

Es ist rekursiv und in der Tat wohl recht speicherfressend und auch nicht allzuschnell. (Wobei bei solchen kombinatorischen Geschichten die benötigte Zeit und Speicherverbrauch allgemein recht schnell ansteigt)
Dafür ist das imho die denkbar einfachste Lösung.

Speziell für int[]-Arrays würde das ganze wohl noch ein bisschen einfacher aussehen, da ohne generics, aber das kann man sich aus diesem Beispiel bei bedarf schnell basteln, wenn das prinzip klar ist...
 

Maeher

Bekanntes Mitglied
Hier meine Variante aus dem alten C-Code (nicht schön aber funktioniert, nur der Startwert 0,1,2,... wird nicht ausgegeben):
Man kann durch Aufruf von getNext() ohne nennenswerten Speicherverbrauch immer wieder neue (Integer-)Kombinationen erzeugen (auch viele Mio).
Code:
public class SortGen {

    private int st; //Anzahl Stellen
    private int moegl; //Anzahl Möglichkeiten pro Stelle
    private int[] akt; //aktuelles Ergebnisarray
    private boolean[] istm; //istm[a] gibt an ob a eine Möglichkeit ist oder bereits verwendet ist

    /**
     * 
     * @param st Stellen
     * @param vals Anzahl der möglichen Werte
     */
    SortGen(int st, int vals) {
        this.st = st;
        moegl = vals;
        istm = new boolean[moegl];
        akt = new int[st];

        for (int i = 0; i < st; i++) {
            akt[i] = i;
        }
    }

    private void istMoegl() {
        int i;
        for (i = 0; i < moegl; i++) { //Alle auf möglich setzen
            istm[i] = true;
        }
        for (i = 0; i < akt.length; i++) {
            istm[akt[i]] = false; //Für in akt vorkommende Werte auf false setzen
        }
    }
    //Nächste Reihenfolge errechnen
    private boolean next() {
        int i, j, k, l; //Schleifeniteratoren
        istMoegl();

        for (i = 0; i < st; i++) { //Für jede Stelle (von hinten)
            istm[akt[st - 1 - i]] = true; //Zu bearbeitende Stelle wieder möglich
            for (j = akt[st - 1 - i] + 1; j < moegl; j++) { //Vom Wert der i-ten Stelle von hinten (+1) bis zum max. mögl. Wert
                if (istm[j]) { //Wenn Wert noch möglich
                    akt[st - 1 - i] = j; //An der i-ten Stelle von hinten Wert einsetzen
                    istm[j] = false; //Wert j an anderen Stellen nicht mehr möglich
                    for (k = st - i; k < st; k++) { //Folgende auffüllen mit kleinstmöglichen Werten (k=Position)
                        for (l = 0; l < moegl; l++) { //mögliche Werte durchprobieren
                            if (istm[l]) {
                                akt[k] = l;
                                istm[l] = false;
                                break;
                            }
                        }
                    }
                    return true;
                }
            }
        }
        akt = null;
        return false;
    }

    /**Startwert wird nie ausgegeben; nach dem letzten Wert wird <code>null</code> zurückgegeben.
     * 
     * @return
     */
    public int[] getNext() {
        next();
        return akt;
    }

    //Testmethode
    public static void main(String[] args) {
        SortGen sG = new SortGen(5, 6);

        long time = System.nanoTime();
            for (int i = 0; i < 500; i++) {
                int[] r = sG.getNext().clone();
                System.out.println(r[0] + " " + r[1] + " " + r[2] + " " + r[3] + " " + r[4]);
            }
        System.out.println(System.nanoTime() - time);
    }
}
Bitte entschuldigt das Kauderwelsch und den hässlichen Abbruch

Edit: main() Testmethode
 

0x7F800000

Top Contributor
könntest du auch schnell noch eine beispiel-main methode in den code einfügen, irgendwie ist mir nicht ganz klar wie man das anwendet ???:L
"3er-Paar" ist aber ein echt interessantes Wort fällt mir grad auf... 3-Tupel heisst es eigentlich^^ :D
 

Maeher

Bekanntes Mitglied
Andrey hat gesagt.:
könntest du auch schnell noch eine beispiel-main methode in den code einfügen, irgendwie ist mir nicht ganz klar wie man das anwendet ???
Falls du mich meinst: erledigt (s.o.). Die Zeitmessung misst so nach meiner Erfahrung allerdings hauptsächlich die System.out's.
Vielleicht sollte ich mich mal um eine Anständige Dokumentation kümmern ???:L
 

0x7F800000

Top Contributor
@diggaa1984:
diggaa1984 hat gesagt.:
heisst das dann nicht Tripel? :D
das mit n-Tupeln ist imho irgendwie allgemeiner, da muss man sich nciht jedes mal überlegen wie es denn eigentlich heisst^^ :D

@Maeher:
dein code liefert zusätzlich alle denkbaren Permutationen, dem OP war aber die Reihenfolge egal. Aber schön zu wissen, dass man auch die Untergruppen der Symmetrischen Gruppe auf diese weise schnell berechnen kann (da müsste man dann aber noch ein wenig was ergänzen)
 

Pfeiffy

Mitglied
Hallo,
also erstmal vielen Dank für die Lösungen, das mit dem Speicherfressen muss ich dann erst mal sehen, bei meiner Rechnung werden schon sehr viele Zahlenmengen eingegeben, ich muss dann sehen, wie es sich verhällt, aber mein Dienstrechner kann einiges ab.

Gruß und Dank
Pfeiffy
 

Maeher

Bekanntes Mitglied
Andrey hat gesagt.:
@Maeher:
dein code liefert zusätzlich alle denkbaren Permutationen, dem OP war aber die Reihenfolge egal.
Hupps :oops:, hab wohl gestern die ersten Posts nicht sauber gelesen.
Da ist meine Lösung natürlich nicht wirklich zweckmäßig.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Algoritmus Distribution in einer Matrix Allgemeine Java-Themen 7
B Algorithmus für Arbeit mit fehlenden Listenelementen? Allgemeine Java-Themen 1
kodela Eingabe für TextArray bedingt sperren Allgemeine Java-Themen 3
Karl_Der_Nette_Anfänger Hat wer ne Lösung für verknüpfte Postleitzahlen? (Baum/Wurzel Struktur) Allgemeine Java-Themen 11
R 11 GB File lesen ohne zu extrahieren Filedaten Bereich für Bereich adressieren dann mit Multi-Thread id die DB importieren Allgemeine Java-Themen 3
G KeyListener für JTextField Allgemeine Java-Themen 5
webracer999 Library für Textsuche (z. B. include/exclude, and/or)? Allgemeine Java-Themen 5
I Module-Info für Jar erzeugen Allgemeine Java-Themen 7
krgewb Java-Bibliothek für ONVIF Allgemeine Java-Themen 1
B Simpler Eventlistener für Tastaturtaste bauen? Allgemeine Java-Themen 13
_user_q Eingegebenen Text Zeile für Zeile ausgeben lassen Allgemeine Java-Themen 11
E Key für TOTP Algorythmus(Google Authentificator) Allgemeine Java-Themen 0
S Formel für Sonnenwinkel in ein Programm überführen Allgemeine Java-Themen 11
M pfx-Zertifikat in Tomcat für SSL-Verschlüsselung nutzen Allgemeine Java-Themen 14
R Best Practice Erfahrungswerte für eine Migration von JSF nach Angular (oder anderes JS-Framework) Allgemeine Java-Themen 1
B HeapSort für Array of Strings funktioniert nur teilweise Allgemeine Java-Themen 3
jhCDtGVjcZGcfzug Klassen Was genau passiert hier? Kann mir das jemand bitte Zeile für Zeile erklären? Allgemeine Java-Themen 1
rosima26 Bester Sortieralgorithmus für kurze Arrays Allgemeine Java-Themen 40
S Mit Methoden kann man definieren für was <T> steht. Geht das auch irgendwie für Variablen? Allgemeine Java-Themen 12
MangoTango Operatoren while-Schleife für Potenz Allgemeine Java-Themen 3
B Lottospiel, genug Reihen tippen für 3 Richtige (Spaß mit Arrays)? Allgemeine Java-Themen 46
B Mit welchen Datentypen und Strukturierung am Besten dutzende Baccaratspiele Shcritt für Schritt durchsimulieren? Allgemeine Java-Themen 26
D Klassendesign für einen Pascal Interpreter Allgemeine Java-Themen 6
I OCR Library für Belegerkennung Allgemeine Java-Themen 7
farah GetterMathod für Farbkanäle Allgemeine Java-Themen 6
B Welcher Datentyp für sehr große Zahlenbereiche? Allgemeine Java-Themen 1
S Webservices für binäre Daten? Allgemeine Java-Themen 5
G Licence-Header für InHouse entwickelten Source Allgemeine Java-Themen 8
M Schleife für einen TicTacToe Computer Allgemeine Java-Themen 5
O git ignore für Intellji braucht es die .idea Dateien? Allgemeine Java-Themen 8
F Java Script für das Vorhaben das richtige? Allgemeine Java-Themen 9
M wiviel Java muss ich für die Berufswelt können ? Allgemeine Java-Themen 5
Robertop Datumsformat für GB ab Java 16 Allgemeine Java-Themen 1
Thallius Verschiedene entities für gleichen Code…. Allgemeine Java-Themen 8
OnDemand Zentrale "Drehscheibe" für verschiedene APIs Allgemeine Java-Themen 14
S Übergabe eines Sortierkriteriums für ein Artikel Array mittels BiPredicate<Artikel, Artikel> Allgemeine Java-Themen 13
F Streams als Alternative für dieses Problem ? Allgemeine Java-Themen 15
D SHA-3 für Java-version 1.8 Allgemeine Java-Themen 1
N Validator für einen SQL-Befehl Allgemeine Java-Themen 22
Muatasem Hammud Erstellung von Testdaten für Arrays Allgemeine Java-Themen 6
B Logikfehlersuche, das perfekte Lottosystem für 3 Richtige mit Arraylists? Allgemeine Java-Themen 61
G Methoden für die Zukunft sinnvoll? Allgemeine Java-Themen 4
M API für PLZ Umkreissuche Allgemeine Java-Themen 3
1Spinne JDK 8 für Eclipse installieren Allgemeine Java-Themen 5
Tobero Meine Funktion für das beinhalten eines Punktes in einem Kreis funktioniert nicht Allgemeine Java-Themen 5
L Methoden Parser für gängige Datumsformate? Allgemeine Java-Themen 1
H Interface PluginSystem ClassNotFound exception für library Klassen Allgemeine Java-Themen 10
N relativier Pfad für sqlite-Datenbank in Gradle/IntelliJ Allgemeine Java-Themen 2
buchfrau Anagram für beliebiges Wort Allgemeine Java-Themen 2
TonioTec Api für Datenaustausch zwischen Client und Server Allgemeine Java-Themen 0
W Suche Ursache für NPE - woher kommt sie? (Hilfe beim Debugging) Allgemeine Java-Themen 19
Kirby.exe Distanz Map für die Distanztransformation erstellen Allgemeine Java-Themen 1
F PI Regler für Heizung Allgemeine Java-Themen 7
8u3631984 Generelle Log4j.xml für alle Module Allgemeine Java-Themen 5
M Wie übergebe ich den Zähler für die Anzahl Rekursionsschritte korrekt? Allgemeine Java-Themen 2
B Login für User, der im Hintergrund Schedules ausführt Allgemeine Java-Themen 16
L RegEx für Teile einer Berechnung Allgemeine Java-Themen 14
S Java-Task-Management-Tool für Windows und Mac selber programmieren Allgemeine Java-Themen 4
M Java 2D Array für ein Grid erstellen ? Allgemeine Java-Themen 2
Z Welches GUI Framework für Java ist aktuell? Allgemeine Java-Themen 16
N Convert.FromBase64 von C# für Java Allgemeine Java-Themen 11
N fixed-keyword von C# für Java Allgemeine Java-Themen 6
O Suche Scripter für alt:V Project! Allgemeine Java-Themen 0
S Interface Design von HookUp oder Callback Methoden für eigenes Framework Allgemeine Java-Themen 9
O Suche Unterstützung für ein OpenSource-Projekt (grafischer Editor) Allgemeine Java-Themen 13
Kirby.exe Software für Graphische Visualisierung Allgemeine Java-Themen 20
B OOP Auslöser für NullPointerException Allgemeine Java-Themen 3
L Generator für einen Parser implementieren Allgemeine Java-Themen 13
DonMalte Ambitioniertes Projekt für Einsteiger & Motivierte Allgemeine Java-Themen 0
Kirby.exe Movement System für Spiel Allgemeine Java-Themen 13
Kirby.exe Framework für Game Design Allgemeine Java-Themen 8
W Alternative für Threads Allgemeine Java-Themen 6
S Rückgabe einer HttpURLConnection für eine Seite einlesen bei der man eingeloggt ist..? Allgemeine Java-Themen 5
Elyt Compiler-Fehler Datei kann nicht erstellt werden. Die Syntax für den Dateinamen etc. ist falsch. Allgemeine Java-Themen 2
Thallius Rätsel für Windows Profis Allgemeine Java-Themen 8
D OOP Gemeinsamen ID-Raum für zwei Klassen implementieren Allgemeine Java-Themen 7
D Input/Output Implementierung eines CommandHandlers/Parsers für viele Eingaben Allgemeine Java-Themen 26
Thallius Alternative für SwingWorker Allgemeine Java-Themen 5
I Lohnt sich heutzutage der Aufwand einer Portierung für MacOS Allgemeine Java-Themen 8
L Klassen Algorithmus für das folgende Problem entwickeln? Allgemeine Java-Themen 30
J Datenstruktur für eine Map erstellen Allgemeine Java-Themen 2
H OOP Setting(config) für Applikation sicheren? Allgemeine Java-Themen 9
OnDemand PDF Libary für Formulare Allgemeine Java-Themen 7
S Warmup für Lineare-Suche mit Zeitmessung Allgemeine Java-Themen 2
T Allgemeine Frage: GUI für 3D-Visualisierung Allgemeine Java-Themen 5
M Brainstorming für mein Projekt Allgemeine Java-Themen 30
K OOP Suche Hilfe + Erklärung für eine Hausaufgabe Allgemeine Java-Themen 1
F Was ist der Dateityp meines Parameters für die Main Methode. Allgemeine Java-Themen 6
C Bibliotheken für Algorithmische Geometrie Allgemeine Java-Themen 2
C Daten für Klassifikationsverfahren gewinnen Allgemeine Java-Themen 6
C code oder Bibliotheken für 2-Center Problem Allgemeine Java-Themen 4
I Overlay für Spiele Allgemeine Java-Themen 5
B Suche nach einem Testprogramm für meine BA Allgemeine Java-Themen 0
I GUI für kleine Pop-Ups unter Windows Allgemeine Java-Themen 1
A NetBeans Suche Programmierer für eine Belegarbeit Allgemeine Java-Themen 11
HarleyDavidson Best Practice Wohin mit der Konfigurationsdatei für Desktopapplikationen? Allgemeine Java-Themen 3
R MAC-Adresse eindeutig für einen PC ? Bezug zu Netzwerk, wieso ? Allgemeine Java-Themen 7
N Java API für CardDav und CalDav gesucht Allgemeine Java-Themen 4
R Idee für Methodenrumpf Allgemeine Java-Themen 5
O Suche größeres Beispiel für WebserverAnwendung mit Java Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben