Verschachtelte for schleife mit dynamischer Anzahl an Schleifen

Status
Nicht offen für weitere Antworten.

Jagito

Mitglied
Hallo,

programmiere gerade einen Algorithmus, welcher generisch sein soll (also bei Änderung der Eingabedaten, muss kein Programmcode verändert werden).

Nun stehe ich vor folgendem Problem. Vielleicht habt ihr eine kreative Lösung dazu:

Am Anfang gebe ich eine Problemgröße an, z.B. 400. Eine Hashmap hm mit 400 Einträgen wird nun erzeugt, wobei jeder Eintrag aus einer arraylist besteht, welche im Laufe des Durchlaufs mit Zahlen gefüllt wird.

Nun möchte ich jedes einzelne Element der arraylist von der hm an den Stellen 100,200,300,400 abfragen und eine mathematische Umformung damit machen. (siehe java-code unten, wobei die hier angegebenen Umformungen "o[...]=..." vereinfacht sind)

Das Problem ist bei Änderung der Hashmap-Größe z.B. auf 300 oder 700, da ich dann zuerst for-schleifen löschen bzw. einbauen muss.

Java:
int max = 0;
int o_gesamt = 0;
for (int i=0; i<hm.get(100).size();i++){
	o[1]=hm.get(100).get(i)+1;
	for (int i=0; i<hm.get(200).size();j++){
		o[2]=hm.get(200).get(i)+1;
		for (int k=0; k<hm.get(300).size();k++){
			o[3]=hm.get(300).get(i)+1;
			for (int l=0; l<hm.get(400).size();l++){
				o[4]=hm.get(400).get(i)+1;
				o_gesamt=o[1]+o[1]+o[2]+o[3];
				if (o_gesamt >max){
				   max = o_gesamt;
			        }
			}
		}
	}	
}
Wie könnte ich dieses Problem angehen?
 

Marco13

Top Contributor
Groß in Richtung von
Code:
for (Integer i : hashMap.keySet())
{
    ArrayList list = hashMap.get(i);
    ...
}
(ggf. effizienter mit EntrySet, nur zur Verdeutlichung)

EDIT: Sieht aber insgesamt seltsam aus - beschreib' am besten mal formaler/genauer, WAS für eine Datenstruktur das ist.... also, was damit wie modelliert wird und so...
 

Jagito

Mitglied
Hi,

ich versuche mal das Problem näher darzustellen. Es handelt sich um einen "Dynamischen Programm" -Algorithmus. Nehmen wir an, wir haben z.B. 400 Knoten, welche Städte in Deutschland darstellen und wir wollen den "besten" Weg zwischen Stadt 1 und Stadt 400 finden, wobei die Städte nach der Reihe, also 1,2,3,...,400 durchlaufen werden sollen. Man kann nun entscheiden, ob man z.B. per Bahn, Bus, Auto, Rad von einer zur anderen Stadt gelangt, was eine unterschiedliche Anzahl an Ressourcen (Zeit, Geld, CO2) verbraucht.
Ziel ist eine möglichst günstige Kombination an Ressourcenverbrauch, wobei ein gewisser maximaler Wert an Zeit, Geld, CO2 nicht überschritten werden darf.

In jeder Stadt wird nun gespeichert, wieviel an Ressource bis zu dieser Stadt verbraucht worden ist. z.B. wird in Stadt 45 alle Möglichkeiten gespeichert, wie man zu dieser Stadt kommen kann und der jeweilige Ressourcenverbrauch (bei 4 Fortbewegungsmöglichkeiten-Bahn, Bus, Auto, Rad- und 45 Städten, sind das also 4^45 Möglichkeiten, wobei einige davon gelöscht werden können)

Da das Problem zu groß ist, zerlege ich es in 100er Schritten. Also ich bilde Wege von Stadt 1-100, 101-200, 201-300, etc. und speicher im Knoten 100, 200,300,... den Bedarf an Zeit, Geld, CO2 von allen "guten" Wegen (d.h. alle Wege, die nicht in allen drei Kategorien schlechter als ein anderer Weg sind und daher gelöscht werden können).

In Java habe ich das so modelliert, dass der key einer Hashmap eine Stadt bildet. Jeder Stadt wird eine Arraylist zugeordnet, welche die Möglichkeiten enthält, wie man zu dieser Stadt kommen kann.

Am Ende suche ich dann aus allen guten Wegen der 100er, 200er, 300er,... Knoten die Kombination derer aus, bei denen der Maximalverbrauch an Zeit,Geld,CO2 eingehalten wurde und die dabei die beste Kombination von Ressourcenverbrauch haben. Beispielsweise könnte ein Ergebnis sein: Von Stadt 1 bis Stadt 100 nehme ich Weg Nummer 7. Von 101-200 den Weg Nr. 27 und von 201-300 Weg Nr 3 etc.

Der letzte Absatz beschreibt das Kombinationsproblem, das ich durch die for-schleifen abbilden möchte. Hierbei ändern sich natürlich die Anzahl an for-Schleifen, falls ich eine unterschiedliche Anzahl an Städten habe und vor diesem Problem stehe ich gerade.

Falls ich noch etwas genauer erklären soll, gebt mir einen Hinweis.
 

Marco13

Top Contributor
OK, das ist dann schon nicht so trivial... Da müßte man sich eigentlich über das Problem an sich und dessen Modellierung einige Gedanken machen, und DANN nochmal über die konkrete Lösung mit DP, daher sieh' meine Antworten immer unter dem Vorbehalt, dass ich das ja noch nicht gemacht habe...

Du hast also eine Menge von Knoten. Jedem Knoten ist eine Liste von Möglichen Wegen zugeordnet (vom vorherigen Knoten zu diesem), und jeder Weg hat bestimmte Kosten...

*grübel*

Eigentlich müßte man auf dieses Problem jetzt auch wieder einen "Dynamic-Programming-Ansatz" anwenden ....

Aber das hast du im ursprünglichen Post (mit den Schleifen) ja auch nicht, von daher ...

Hm... so als zwischenfrage: Warum liegen die Daten in einer Map? Also, warum statt der Map, die {100->DatenA, 200->DatenB, 300->DatenC...} enthält nicht einfach eine List, die nur {DatenA, DatenB, DatenC} enthält? (Ich glaube, an sich könnte man die Lösung relativ einfach rekursiv bauen - auch wenn das eben NICHT DP wäre...)
 

Jagito

Mitglied
Hi,

die Daten liegen ursprünglich in einer Map, um auf sie während des Durchlaufs des DP gezielt zugreifen zu können.

Am Ende könnte man diese dann auch in eine List, die nur {DatenA, DatenB, DatenC} enthält, überspielen. Kein Problem.

Wie kann ich jedoch dann mein Problem lösen, dass ich die optimalste Kombination aus je einem einzigen Element aus A,B und C haben möchte, wenn dies generisch sein soll, also ich z.B. beim nächsten Durchlauf die Einstellung vornehme, dass ich nun bis 500 Knoten habe, also am Ende eine Liste mit {DatenA, DatenB, DatenC, DatenD, DatenE}?

EDIT: Eigentlich läuft es auf ein Kombinatorik-Problem hinaus. Man hat z.B. fünf Töpfe A,B,C,D,E mit einer unterschiedlichen Anzahl an Elementen darin. Wie kann ich jetzt jedes Element mit jedem anderen kombinieren, wobei ich aus jedem Topf genau ein Element entnehme? (die Reihenfolge, wann ich aus welchem Topf nehme, spielt keine Rolle). Das generische ist, dass ich am Anfang die Anzahl der Töpfe angebe und während des Durchlaufs die Elemente in den Töpfen erzeugt werden.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Hab' gerade nicht viel Zeit, aber es klang jetzt als könnte man da grob sowas machen wie
Code:
private Path bestPath = null;

void findPath(List input, int index, Path currentPath)
{
    if (index >= input.size())
    {
        if (currentPath.betterThan(bestPath)) bestPath = currentPath.copy();
        return;
    }
    for (all possible path segments at input.get(index))
    {
        currentPath.append(segment);
        findPath(input, index+1, currentPath);
        currentPath.remove(segment);
    }
}
Wenn's zu knapp ist (oder nicht passt - das klingt für dieses komplexe Problem eigentlich ZU einfach) sag' nochmal bescheid.
 

Jagito

Mitglied
Hi,
schaut spannend aus. Eine rekursive Lösung, wenn ich es richtig verstanden habe. Das einfache könnte die Lösung sein. Dank deiner Hilfe ist mir klar geworden, dass sich mein aktuelles Problem als reine Permutation (Kombinationsproblem) lösen läst.

Beim Code ist mir noch unklar, wie sichergestellt ist, dass (um beim Beispiel mit den Töpfen zu bleiben) aus jedem Topf jeweils nur ein Element genommen wird und dies mit allen möglichen Kombinationen der andern Töpfe kombiniert wird.

Also bspw. haben wir |A|=7, |B|=5 und |C|=11, dann müsste der Code 7*5*11=385 Kombinationen berechnen. Macht er das?

Wie kann der Code also folgende Aufgabe berechnen:
Seien die Mengen A,B,C wie oben, wobei jede Menge z.B. Tupel aus (Zeitbedarf/Geldverbrauch) enthält.
Jetzt wird das Minimum einer Dreier-Kombination von je einem Element aus A,B,C gesucht, wobei das Minimum aus der Funktion a.zeit+2*a.geld+b.zeit+2*b.geld+c.zeit+2*c.geld berechnet wird.
Ich suche also die konkreten a,b,c (bzw. die Indizes in den Mengen A,B,C, um a,b,c zu identifizieren), welche obige Funktion minimieren.
 

Marco13

Top Contributor
Ja, ein paar Utility-Klassen für sowas gibt's unter http://www.java-forum.org/codeschnipsel-u-projekte/81973-combinatorics.html aber das braucht's hier eigentlich nicht.


Hier nochmal ein ausführlicheres Beispiel
Code:
// For http://www.java-forum.org/java-basics-anfaenger-themen/90564-verschachtelte-schleife-dynamischer-anzahl-schleifen.html#post573696
import java.util.*;

class Segment
{
    int zeit;
    int geld;

    public Segment(int z, int g)
    {
        zeit = z;
        geld = g;
    }

    public int value()
    {
        return zeit + 2 * geld;
    }

    public String toString()
    {
        return "("+zeit+","+geld+")";
    }

}


class Node
{
    List<Segment> segments = new ArrayList<Segment>();

    void add(Segment segment)
    {
        segments.add(segment);
    }
}

class Path
{
    List<Segment> segments = new ArrayList<Segment>();

    void append(Segment segment)
    {
        segments.add(segment);
    }

    void remove(Segment segment)
    {
        segments.remove(segment);
    }

    int value()
    {
        if (segments.size() == 0) return Integer.MAX_VALUE;

        int result = 0;
        for (Segment segment : segments) result += segment.value();
        return result;
    }

    boolean isBetterThan(Path that)
    {
        return this.value() < that.value();
    }

    public Path copy()
    {
        Path p = new Path();
        p.segments.addAll(segments);
        return p;
    }

    public String toString()
    {
        return "Path "+value()+" : "+segments.toString();
    }


}

class PathFinder
{
    public static void main(String args[])
    {
        new PathFinder().find();
    }

    private Random random = new Random(0);
    private Path bestPath = new Path();
    private List<Node> inputList;
    private int counter = 0;

    public PathFinder()
    {
        inputList = new ArrayList<Node>();
        inputList.add(createRandomNode(7));
        inputList.add(createRandomNode(5));
        inputList.add(createRandomNode(11));
    }

    private Segment createRandomSegment()
    {
        return new Segment(random.nextInt(10), random.nextInt(10));
    }

    private Node createRandomNode(int segments)
    {
        Node node = new Node();
        for (int i=0; i<segments; i++)
        {
            node.add(createRandomSegment());
        }
        return node;
    }


    void find()
    {
        findPath(inputList, 0, new Path());

        System.out.println("bestPath "+bestPath);
        System.out.println("counter "+counter);
    }

    String indent(int n)
    {
        String result = "";
        for (int i=0; i<n; i++)
        {
            result += "    ";
        }
        return result;
    }


    void findPath(List<Node> input, int index, Path currentPath)
    {
        if (index >= input.size())
        {
            counter++;
            System.out.println(indent(index)+"Comparing "+currentPath);
            System.out.println(indent(index)+"to        "+bestPath);

            if (currentPath.isBetterThan(bestPath))
            {
                System.out.println(indent(index)+"Found new best path: "+currentPath);
                bestPath = currentPath.copy();
            }
            return;
        }
        Node node = input.get(index);
        for (Segment segment : node.segments)
        {
            System.out.println(indent(index)+"Appending "+segment+" to "+currentPath+" and recurring");

            currentPath.append(segment);
            findPath(input, index+1, currentPath);
            currentPath.remove(segment);
        }
    }

}


Beachte aber, dass das eben NICHT mit Dynamischer Programmierung gelöst ist (und in obiger Form natürlich auch gehackt...)
 

Jagito

Mitglied
Hi,
hatte jetzt Zeit mir das ganze zu durchdenken. Es läuft wunderbar :). Leider weiß ich nicht, wie ich es an meine Gegebenheiten anpassen kann. Das Wichtigste fürs Sortieren ist m.E. die findPath-Methode.
Die segments und node und random-Methoden kann man wahrscheinlich bei konkreten gegebenen Daten weglassen, obwohl ich mir da nicht so ganz sicher bin.

Meine Datenstruktur sieht zur Zeit so aus, dass ich eine Hashmap hm mit z.B. 40 Einträgen habe (die Anzahl kann in 10er Schritten verändert werde, was das generische am Problem darstellt). Jeder dieser Einträge ist eine ArrayList al zugeordnet, welche mit Tupeln aus z.B. Zeit und Geld gefüllt ist. Die Tupel definiere ich mir über eine eigene Klasse Tupel (dürfte deiner Segment-Klasse entsprechen). Die Tupel werden nach gewissen Regeln während des Durchlaufens erzeugt.

Die einzelnen Töpfe (um das vorherige Beispiel aufzugreifen) beinhalten also z.B. von der Hashmap mit Key 10,20,30,40 alle Elemente der dazugehörigen arraylist.

Also hätte der erste Topf alle i's aus hm.get(10).al.get(i), der zweite Topf alle i's aus hm.get(20).al.get(i), etc.

Wie könnte ich das auf den bisherigen Code übertragen?
 

Marco13

Top Contributor
...alle i's aus hm.get(10).al.get(i),...

hm ist die HashMap
hm.get(10) liefert ... irgendwas, was eine ArrayList "al" enthält ???:L
hm.get(10).al.get(i) liefert ein Tupel?

Wenn ich das jetzt richtig verstanden habe, läßt sich das ziemlich direkt abbilden:
Die Tupel sind die "Segments"
Das Ding, das die al enthält ist ein "Node"
Die Einträge der HashMap sind (als Liste) gerade die List<Node> aus dem Beispiel.

Poste ggf. mal ein bißchen Code...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Verschachtelte for-Schleife Java Basics - Anfänger-Themen 2
laxla123 Verschachtelte If-Else Schleife Java Basics - Anfänger-Themen 21
S Verschachtelte Schleife Java Basics - Anfänger-Themen 3
Y Verschachtelte For-Schleife Java Basics - Anfänger-Themen 5
S verschachtelte for-Schleife Java Basics - Anfänger-Themen 6
J verschachtelte Schleife Java Basics - Anfänger-Themen 10
P Verschachtelte Schleife vorzeitig abbrechen. Java Basics - Anfänger-Themen 50
S verschachtelte for Schleife und Ergebniss. Java Basics - Anfänger-Themen 3
C Verschachtelte For-Schleife Java Basics - Anfänger-Themen 6
J Verschachtelte for-Schleife mit Löschen von Iterationen. Wie über Iterator abbilden? Java Basics - Anfänger-Themen 6
W verschachtelte while schleife Java Basics - Anfänger-Themen 8
W verschachtelte For-Schleife - continue Java Basics - Anfänger-Themen 8
R Verschachtelte Schleife? Java Basics - Anfänger-Themen 6
W Verschachtelte If-else --> finde meinen Fehler nicht Java Basics - Anfänger-Themen 30
Düsseldorf2002 Datentypen Verschachtelte LinkedList Java Basics - Anfänger-Themen 5
J Verschachtelte Methoden Java Basics - Anfänger-Themen 9
P Verschachtelte Hashmap Java Basics - Anfänger-Themen 6
P Verschachtelte Array Liste Java Basics - Anfänger-Themen 2
B Verschachtelte For Schleifen Java Basics - Anfänger-Themen 8
W Verschachtelte Objekte wieder auspacken Java Basics - Anfänger-Themen 3
F Methoden Verschachtelte if else Methode Java Basics - Anfänger-Themen 10
Z Verschachtelte If-Bedingung Java Basics - Anfänger-Themen 6
D verschachtelte Schleifen Java Basics - Anfänger-Themen 6
M Verschachtelte Forschleifen Java Basics - Anfänger-Themen 2
F Klassen Zugriff auf verschachtelte Objekte Java Basics - Anfänger-Themen 11
J static verschachtelte Klassen und innere Klassen Java Basics - Anfänger-Themen 1
TheMenox Verschachtelte If Bedingung Java Basics - Anfänger-Themen 4
R Verschachtelte Arraylist und deren Größe auslesen Java Basics - Anfänger-Themen 7
C Verschachtelte Map auslesen Java Basics - Anfänger-Themen 4
H Best Practice Wie mit break verschachtelte Schleifen komplett verlassen? Java Basics - Anfänger-Themen 2
F Verschachtelte Schleifen Java Basics - Anfänger-Themen 4
J Hilfe verschachtelte Schleifen Java Basics - Anfänger-Themen 5
F Erste Schritte Switch case vs. Verschachtelte If Anweisung Java Basics - Anfänger-Themen 11
G Collections verschachtelte ArrayList abfüllen Java Basics - Anfänger-Themen 5
X verschachtelte suche Java Basics - Anfänger-Themen 8
S Verschachtelte Exceptions - Übersicht verbessern Java Basics - Anfänger-Themen 2
D Verschachtelte Objekterzeugung Java Basics - Anfänger-Themen 6
X Verschachtelte Annotationen Java Basics - Anfänger-Themen 9
J verschachtelte for-schleifen Java Basics - Anfänger-Themen 2
S Verschachtelte Klassen Java Basics - Anfänger-Themen 12
D Verschachtelte IF-Anweisung Java Basics - Anfänger-Themen 10
C Verschachtelte for-schleifen Java Basics - Anfänger-Themen 10
C Verschachtelte For-Schleifen Java Basics - Anfänger-Themen 5
3 Verschachtelte Zuweisung Java Basics - Anfänger-Themen 4
M Tief verschachtelte Packages Java Basics - Anfänger-Themen 7
T add-Methode für verschachtelte ArrayLists Java Basics - Anfänger-Themen 10
E Verschachtelte If-Anweisungen - "else without if" Java Basics - Anfänger-Themen 4
T Datentypen Verschachtelte Map durchlaufen Java Basics - Anfänger-Themen 4
P Verschachtelte For-Schleifen Java Basics - Anfänger-Themen 4
F Verschachtelte Arrays kopieren und überschreiben Java Basics - Anfänger-Themen 4
M Verschachtelte Strukturen. Java Basics - Anfänger-Themen 7
M Viele verschachtelte Schleifen Java Basics - Anfänger-Themen 14
A Verschachtelte Hashtable ausgeben. Java Basics - Anfänger-Themen 3
G Verschachtelte Case Fallunterscheidung Java Basics - Anfänger-Themen 7
M sehr weit verschachtelte XML-datei mit jdom auslesen Java Basics - Anfänger-Themen 4
S verschachtelte while Schleifen Java Basics - Anfänger-Themen 5
R Bedingte Opeatoren / Verschachtelte Operatoren Java Basics - Anfänger-Themen 4
M While-Schleife mit Wartezeit Java Basics - Anfänger-Themen 15
T Ich brauche eine Schleife die eine beliebige Zahl so lange durch 10 teilt bis zur Null Java Basics - Anfänger-Themen 5
DrahtEck Schleife soll wieder da anfangen wo ich es möchte ! Java Basics - Anfänger-Themen 17
Finn_lol Fehlermeldung bei Schleife mit Array Java Basics - Anfänger-Themen 4
Ranger229 Endless loop in while Schleife Java Basics - Anfänger-Themen 3
MaZ Quadrat Schleife(Pyramide) Java Basics - Anfänger-Themen 9
M Datentypen While-Schleife eine Java Methode erstellen Java Basics - Anfänger-Themen 3
P Wie kann diese Schleife beenden Java Basics - Anfänger-Themen 1
T float soll durch schleife die größte mögliche Zahl herausfinden, Ausgabe ist aber "Infinity" Java Basics - Anfänger-Themen 1
T Variable in Schleife deklarieren, Speicherplatz, Garbage Collector Java Basics - Anfänger-Themen 10
Ostkreuz While Schleife neustarten Java Basics - Anfänger-Themen 20
M Problem bei verschachtelter for-Schleife bei zweidimensionalen Arrays Java Basics - Anfänger-Themen 3
S Erste Schritte do-while Schleife Münzwurf Java Basics - Anfänger-Themen 1
S while Schleife Taschenrechner Java Basics - Anfänger-Themen 1
P Best Practice While loop schleife Java Basics - Anfänger-Themen 5
ohneInformatik; For Schleife. Was macht dieser Code?? Java Basics - Anfänger-Themen 5
I For Schleife Summe berechnen Java Basics - Anfänger-Themen 13
A Erste Schritte Aufgabe mit while Schleife Java Basics - Anfänger-Themen 11
R do while Schleife Verständnisfrage Java Basics - Anfänger-Themen 2
Say Fehlenden Code finden in einer while-Schleife? Java Basics - Anfänger-Themen 11
N Warum Springt iterator nur in der Schleife weiter Java Basics - Anfänger-Themen 9
J for Schleife kleinste Zufallszahl finden Java Basics - Anfänger-Themen 25
A Return in While Schleife Java Basics - Anfänger-Themen 6
M Erste Schritte While Schleife / Ausgabe von buchstabe & ASCII Wert Java Basics - Anfänger-Themen 4
J do..while Schleife Java Basics - Anfänger-Themen 14
J Java To String Methode, Array mit For-Schleife Java Basics - Anfänger-Themen 2
S Textausgabe in einer For-Schleife Java Basics - Anfänger-Themen 12
B Automatisierte Ausgabe (Schleife, If-Abfrage?) Java Basics - Anfänger-Themen 24
C 2D Array Ausgabe mit for-Schleife i,j Java Basics - Anfänger-Themen 4
T Mit jedem Wert in der for-Schleife weiter arbeiten Java Basics - Anfänger-Themen 3
berserkerdq2 Warum muss man manchmal in der RUnmethode sleep in eine schleife tun? Java Basics - Anfänger-Themen 9
F for-Schleife halbiert Durchläufe ungewollt Java Basics - Anfänger-Themen 6
ravenz Schleife mit for über String Array „zahlen“und prüfen ob Wert „a“ oder „b“ oder „c“ entspricht (mittels || ) Java Basics - Anfänger-Themen 4
Bugs Bunny Fehlerhafte Berechnung beim erneuten Durchlaufen der Schleife Java Basics - Anfänger-Themen 5
J Methoden iterator for-schleife (hasNext() ) Java Basics - Anfänger-Themen 7
S Was macht ++ ohne Schleife? Java Basics - Anfänger-Themen 4
LFB In einer For-Schleife alles in einer Zeile ausgeben Java Basics - Anfänger-Themen 14
Neuling47 for schleife Java Basics - Anfänger-Themen 6
M Variable in einer Schleife initialisieren Java Basics - Anfänger-Themen 46
B Zuweisungen und Methodenaufrufe in Bedingung der while Schleife? Java Basics - Anfänger-Themen 2
JavaBeginner22 Würfeln bis 6 while Schleife Java Basics - Anfänger-Themen 13
D EinMalEins mithilfe einer for-Schleife und Array Java Basics - Anfänger-Themen 1
xanxk Problem For-Schleife mit Charakter Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben