for in for Schleife ineffizient?

chripo19

Mitglied
Guten Tag,

ich habe folgendes kleines Programm geschrieben zur Bestimmung wie viele Möglichkeiten es gibt diese Gleichung:
98x + 35y<=10000
durch beliebige x und y zu erfüllen.

Java:
ArrayList <Integer>preise= new ArrayList<Integer>();
for(int i=0;i<103;i++){
    for (int j=0;j<286;j++){
        int a=i*98+j*35;
        if(a>10000){
            break;
        }
        if(preise.contains(a)==false){
            preise.add(a);   
        }
    }
}

Bis hier hin alles easy. Das Programm Dauert seine 5millisek und gibt mir 1402 aus.

Nun würde ich gerne dasselbe mit dieser Gleichung machen: 833x+616<=(10^21)-1

Java:
ArrayList <Double>preise= new ArrayList<Double>();
for(double i=0;i<120048019207684.0;i++){
   for (double j=0;j<162337662337662338.0;j++){
       double a=i*833+j*616;
       if(a>99999999999999999999.0){
            break;
        }
        if(preise.contains(a)==false){
            preise.add(a);   
        }
    }
}

Nach 1,5h habe ich aufgegeben und das Programm abgebrochen. Wie kann ich das Programm optimieren?
 

Der Müde Joe

Top Contributor
Ist doch nur Mathe? (oder hab ich schon ein Bier zuviel)

Code:
// 833x+616<=(10^21)-1
// 833x    <=(10^21)-617 (999999999999999999383)
//

BigInteger fac = BigInteger.valueOf(833l);
// (10^21)-617
BigInteger max = BigInteger.valueOf(10l).pow(21).subtract(BigInteger.valueOf(617l));

System.out.println("Start: " + max);
// ((10^21)-617) / 833
BigInteger maxDiv = max.divide(fac); // modulo egal
System.out.println("Max x: " +maxDiv);

BigInteger modulo = max.mod(fac);
// test: maxDiv * 833 + (max mod 833) == max
System.out.println("Check: " + maxDiv.multiply(fac).add(modulo));
System.out.println(max.equals(maxDiv.multiply(fac).add(modulo)));
[\code]
 

eldrior

Aktives Mitglied
Momentan probierst du ganz stumpf einfach jede Möglichkeit durch. Das kann man bei kleinen Aufgaben machen (wie deiner ersten), aber du hast selbst gesehen, dass das bei größeren Problemen unsinnig ist.
Geht es dir nur um die Anzahl der möglichen Lösungen, gibt es bessere (mathematische) Lösungen, das das, was ich dir jetzt vorschlage.

Nehmen wir an du hast a*x+b*y<=z
dann könntest du mit x=0 und y=0 anfangen (oder von miraus auch im negativen Bereich) und y hochzählen, bis die Zahl >z ist.
Du kannst aber y auch in jedem Durchgang um 5000 erhöhen, bis es >z wird und nur dann jede Zahl probieren. (Zahlen kannst du selbst anpassen ;))

Du könntest auch alle Ergebnisse von a*x bis x=??? berechnen. Dann zählst du, wie viele von den eben berechneten Ergebnissen <= z-b*y ist. (Da sieht man das klassische Problem wieder: Je weniger Rechenleistung du zur Lösung eines Problems in fixer Zeit x aufwenden willst, desto mehr Speicher brauchst du. Je weniger Speicher du nutzen willst, desto mehr Rechenleistung brauchst du.

Und dann gibts da natürlich noch die Möglichkeit der parallelisierung. Die ist hier eigentlich sehr gut anzuwenden.

Du kannst jetzt entweder nach einer mathematischen Lösung suchen (ist allgemein die beste und intelligenteste Lösung), oder deinen Code optimieren.
 

Dompteur

Top Contributor
Du hast da ein Problem mit quadratischer Komplexität. Das heißt, wenn du den Wert rechts vom <= mal 2 nimmst, dann erhöht sich die Anzahl der Ergebnisse um 2 hoch 2 (=4).
Bei einer Verdreifachung hast du schon 3 hoch 2 (=9) mal soviele Ergebnisse.
Die Laufzeit der Aufgabe wächst entsprechend der Anzahl der Ergebnisse.

Weiters darfst du nicht vergessen, dass du im ersten Beispiel int und im 2. Beispiel double's verwendest. Berechnungen mit ganzen Zahlen sind immer schneller.

Ich weiß nicht, wieviel der Java-Compiler optimiert, aber du könntest diese Variante ausprobieren. Ich habe da Multiplikationen durch Additionen ersetzt. Üblicherweise ist das schneller.

Java:
ArrayList <Integer>preise= new ArrayList<Integer>();
xpart = 0;
for(int i=0;i<103;i++, xpart += 98){
     int a = xpart;
     for (int j=0;j<286;j++, a+=35){
         if(a>10000){
             break;
         }
         // an dieser Stelle hast du eine weitere Lösung des Ungleichung gefunden : (i, j).
         if(preise.contains(a)==false){
             preise.add(a);  
         }
     }
}

Off topic: Mir ist nicht klar, was du in preise speicherst bzw. was du genau ermitteln willst.
 

Enceladus271

Bekanntes Mitglied
Ich bezweifel dass es möglich einen halbwegs effizienten Algorithmus für das Problem zu finden:

1. Allein die äußere Schleife braucht ewig. Wenn ein Schleifendurchlauf durchschnittlich 1ns benötigt läuft die Schleife schon ca 33 Stunden.

2. Es ist nicht möglich die Ergebnisse in einer Liste zu speichern. Wenn x=0 ist gibt es schon 10^21 / 616 y-Werte die die Gleichung erfüllen. Allein um die zu speichern baruchst du 649350 TeraByte Speicher.
 

InfectedBytes

Top Contributor
Brute Force ist nun wirklich der falsche Ansatz^^
98x + 35y<=10000 kannst du z.b. umformen in y <= 2000/7 - 14x/5
daraus resultiert im grunde eine fläche unterhalb der linie die durch y=2000/7 - 14x/5 gegeben ist.

Rechne dir dann mal den schnittpunkt mit der x achse aus, also 0=2000/7 - 14x/5 nach x lösen (5000/49)
Im Grunde brauchst du dann nichts weiter machen, als von x=0 bis x=5000/49 zu gehen und jedes mal den y wert davon zu berechnen, die ergebnisse kannst du aufsummieren.

Vielleicht mal nen kleines Beispiel:
Wenn x=20 ist, ist y=1608/7, d.h. allein für diesen einen x Wert, gibt es rund 229 y Werte, für die das Ergebnis die Gleichung erfüllt
 

Dompteur

Top Contributor
Brute Force ist nun wirklich der falsche Ansatz^^
Ich sehe hier keinen Brute Force Ansatz. Schau dir doch den Code des 1. Beispiels im ersten Beitrag noch einmal an. Jede Kombination (i,j) bis zum Abbruch der inneren Schleife durch das break ist eine gültige Lösung.

Das Problem ist, dass die Anzahl der Lösungen sehr schnell steigt. Enceladus271 hat ja vorgerechnet, wie viele Lösungen es schon für einen x-Wert gibt.
 

InfectedBytes

Top Contributor
Also ich finde alles durchzuprobieren ist schon bruteforce
Java:
for(int i=0;i<103;i++){
    for (int j=0;j<286;j++){
        int a=i*98+j*35;
        if(a>10000){
...
Die Hälfte der Durchläufe liefert einen Wert über 10.000 und sollte daher erst gar nicht betrachtet werden.

Und bezüglich der Anzahl der Lösungen hast du natürlich recht, jedoch ist die Frage ob wirkliche alle Lösungen ausgegeben werden sollen, oder ob es reicht zu wissen wieviele es gibt.
Außerdem könnte man auch anstatt alle (x,y) zu speichern auch nur (x, ymax) speichern
Anstatt also (20, 0), (20, 1), ... (20, 229) könnte man genauso gut nur (20, 229) speichern, was eben aussagen würde, das der x-Wert 20 mit den y-Werten 0 bis 229 ein passendes Ergebnis liefert
 

Dompteur

Top Contributor
Die Hälfte der Durchläufe liefert einen Wert über 10.000 und sollte daher erst gar nicht betrachtet werden.
Das stimmt nicht. Für jeden Durchlauf der äußeren Schleife gibt es genau einen Fall, bei dem 10.000 überschritten wird. Danach wird die innere Schleife abgebrochen. Also gibt es 103 Fälle, bei denen 10.000 überschritten wird..

... jedoch ist die Frage ob wirkliche alle Lösungen ausgegeben werden sollen, oder ob es reicht zu wissen wieviele es gibt.
Da hast du recht. Ich habe schlampig gelesen und nicht regestriert, dass es um die Anzahl geht. Ich ging davon aus, dass alle Lösungen ausgegeben werden sollten.
 

black swan

Mitglied
Der Oberbegriff Brute-Force-Methode passt schon, weil er im Allgemeinen bedeutet, alle Möglichkeiten durchzuprobieren. In der Mathematik ist das evtl. nicht ganz passend, da es hier nicht um "raten" geht. Es werden (lokale) Maxima einer Kurve gesucht.
 

JStein52

Top Contributor
Hallo, ganz habe ich das Problem worum es geht nicht verstanden. Geht es dir um einen generellen Lösungsansatz für beliebige Geraden Oder geht es um ganz spezielle Geraden und du suchtst nur einen Weg dies optimal zu codieren ? Und suchst du nur ganzzahlige Tupel (x,y) die diese Bedingung erfüllen ? Es geht mir wie dem müden Joe mit dem Bier zuviel. Du suchst doch schlicht alle Wertepaare unterhalb (bzw. auch noch auf) einer Geraden. Wobei schlicht jetzt evtl. untertrieben ist. Ist das so ?
 

JStein52

Top Contributor
Und bzgl. "schlicht" bin ich der Meinung von Enceladus, es wird einfach praktisch nicht möglich sein da einen effizienteren Algorithmus zu finden der das Problem allgemein löst. Es wird im Prinzip nichts anderes übrig bleiben für jeden x-Wert den zugehörigen y-Wert auszurechnen. Da könntest du sicher noch ein bisschen optimieren denn die Steigung der Geraden ist ja bekannt so dass du das ganze auf Additionen reduzieren kannst. Aber wenn das Intervall in x-Richtung nunmal gigantisch ist hilft jeder Programmiertrick nur bedingt. Im übrigen bin ich nicht der Meinung dass die Komplexität quadratisch ist, sie ist linear. Wenn das x-Intervall doppelt so gross wird müssen auch doppelt so viele y-Werte berechnet werden. Und im allgemeinen ist die Anzahl möglicher Lösungen natürlich unendlich, aber du begrenzt ja das x-Intervall auf einen bestimmten Bereich.
 
Zuletzt bearbeitet:

chripo19

Mitglied
Danke erstmal für die viele Antworten. Hier ist nochmal die exakte Aufgabenstellung: Es gibt Kupfer-,Silber- und Goldmünzen.
Eine Silbermünze = 35 Kupfermünze
Eine Goldmünze = 98 Kupfermünzen

Wie viele Preise bis 10.000 Kupfer können nur mit Silber und Goldmünzen bezahlt werden ->
35x+98y<=10000

Also es scheitert an der Mathematik. Habe es über einen anderen Ansatz versucht.
Java:
for(int i=0;i<103;i++){
    a+=(10000-(i*98))/35;
    if (i>0){
      a+=1;
   }
}
System.out.println(a-1);

Ich komme auf 14768. Müsste aber auf 1402 kommen. Wie bekomme ich die Preise gefiltert die vorher schonmal getroffen wurden?
 

JStein52

Top Contributor
Also, nach dieser Aufgabenstellung hast du folgendes mathematische Problem:
Du suchst alle ganzzahligen Tupel (x,y) die unterhalb der Geraden liegen die durch die Gleichung 35x + 98y = 10000 gegeben ist. Du kannst die Gleichung noch umformen und erhältst:

y = 10000/98 - 35x/98

und jetzt gehst du her und setzt für x nacheinander alle ganzen Zahlen, beginnend mit 0 ein solange wie der zugehörige y-Wert >= 0 ist. für jedes x erhältst du nun einen ymax-Wert (nämlich den der auf der Geraden drauf liegt) und weisst dann dass für diesen x-Wert alle ganzzahligen Werte von 0 bis ymax die Bedingung erfüllen. Und diese ganzen (auf ganze Zahlen abgeschnittenen) ymax werte addierst du in der Schleife für jedes x auf und solltest dann am Ende die Zahl der Kombinationen haben. Da die Steigung -35/98 ist kannst du natürlich den ersten Wert für x = 0 ausrechnen und für alle folgenden x einfach 35/98 subtrahieren und das solange wie y noch >= 0 ist.
Und das in Java umsetzen darfst du jetzt.
 

JStein52

Top Contributor
Und aufpassen: wenn du für x=1 z.B. ymax = 3.7 erhältst dann passen die Tupel (1,0), (1,1), (1,2), (1,3) !!! Also nicht einfach 3.7 abschneiden auf 3, die 0 gehört auch noch dazu, also 4 Kombinationen !
 

chripo19

Mitglied
Naja überleg doch mal: Es ist die Frage: Wie viele Preise von 10.000 möglichen Preisen können bezahlt werden. 14k ist da ein wenig unnlogisch. auf 14k komme ich schon seit langem. Hast du dir das ganze thema durchgelesen? Auf 1402 komme ich wenn ich alle ergebnisse speichere, und vergleiche, und keine doppelten in meine array list lasse. Aber das sprengt bei größeren Aufgaben den Rahmen. auf 14769 komme ich auch mit dem um 19:21 geposteten Code.
 

JStein52

Top Contributor
Und meiner Meinung nach ist das auch richtig mit den 14k. Mein Code sieht so aus:

Java:
  public int computeKombi(float a, float b, float c) {
      // a*x + b*y = c -> y = c/b - a/b*x
      float abschnitt = c/b;
      float steigung  = a/b;

      // den Wert x = 0 rechnen wir per Hand aus
      float y         = abschnitt;
      int   kombis    = (int)abschnitt; // x=0, y=0 macht keinen Sinn !
   
      while (y >= steigung) { // solange wie man die Steigung subtrahieren kann
          y = y - steigung;
          kombis = kombis + (int)y + 1;
      }
      return kombis;
  }

Was sind denn da doppelte Kombinationen ?? ich addiere doch in jedem Schleifendurchgang, d.h. neues x einfach die möglichen y-Werte dazu ?? Oder ich habe die Aufgabe falsch verstanden, ich dachte du willst die möglichen Kombinationen wissen wie du diese Preise zahlen kannst ?
 
Zuletzt bearbeitet:

InfectedBytes

Top Contributor
eine möglichkeit wäre es, ein boolean Array mit 10.000 Einträgen anzulegen und bei den Berechnungen eben den Wert im Array auf true setzen. Anschließend muss das Array einmal durchlaufen werden um zu zählen wie oft true vorkommt.
Dieser Ansatz kostet zwar Speicher, spart aber Laufzeit im Vergleich zur Liste

p.s. @vorposter
Dem TE geht es darum, dass z.b. die beiden Tupel (0,98) und (35,0) beide jeweils den Wert 3430 ergeben, dementsprechend sollen der Wert 3430 nur einmal gezählt werden und nciht zweimal
 

E00358

Mitglied
Hallo (ich hoffe ich irre mich nicht),
Wie oben schon gesagt wurde kann der Preis 3430 durch 2 Kombinationen erhalten werden, d.h. aber auch, das alle möglichen Preise sich oberhalb 3430 was die Abstände angeht wiederholen und nicht neu berechnet werden müssen. Es muss zuerst die Gleichung 98Y = 35X auf die kleinste ganzzahlige Lösungen untersucht werden. Ist diese gefunden können die möglichen Preise berechnet werden, die sich aus Silber und Goldmünzen Kombinationen für diesen Wert ergeben. Aufpassen muss man dann nur noch bei dem Rest, 10000 ist kein ganzzahligen Vielfaches von 3430 und der Frage ob 0 ein Preis ist oder nicht.
 

JStein52

Top Contributor
Aber im Prinzip gilt das was Enceladus oben schon vorgerechnet hat. Es wird in dieser Grössenordnung halt nun mal ewig dauern. Aber warum ist das überhaupt ein Problem für dich ? Benutzt du das in irgendeinem konkreten Projekt wo z.B. ein Benutzer davor sitzt und auf das Ergebnis wartet oder ist es nur eine Übungsaufgabe bzw. akademisches Problem und du hast jetzt den Ehrgeiz da noch ein paar Prozent rauszuholen so dass es statt 15 Stunden nur noch 10 dauert ?
 

E00358

Mitglied
Guten Morgen,
Das Problem ist linear und eher ein mathematisches oder Textaufgabe. Wenn die kleinste ganzzahlige Lösung für die Gleichung 98Y = 35X gefunden wurde, muss man nur die unterschiedlichen absolut Beträge der Kombinationen zählen, danach lässt sich der Rest mit den Grundrechenarten erledigen und ist von dem Endwert linear abhängig.
Die Kombinationen sind immer < 10000. Vielleicht wird das klarer, wenn man besser auf einander abgestimmte Münzen nimmt wie Euro und 2 Eurostücke. Mit 2 Eurostücken bekomme ich 10000/2 -1 Preise hin mit beiden Münzen sind es 10000 -1 genau so viele wie mit 1 und 2 Euro Münzen. In dem Beispiel habe ich die Reihen 35,70,105,140,... ; 98,196,294, ... und die Kombination 1x98 + x35 , 2x98 x 35, ... . Spätestens ab 3430 wiederholt sich das Ganze

VG Michael
 

JStein52

Top Contributor
Die Länge der äusseren Schleife (alle möglichen x-Werte) hängt natürlich von allen Koeffizienten ab. Bei deinem Zahlenbeispiel (833, 616, 10^21 ) wird diese rund 10^18 mal durchlaufen. Rechne mal wie Enceladus mit einer ns pro Schleifendurchgang. Dann bist du bei 10^9 sekunden. Bis dahin hat sich allerdings die Hardware soweit verbessert dass du es neu starten kannst und dann vielleicht nur noch ein Tausendstel (d.h. 10^6 sekunden) benötigst :):):):):)
 
Zuletzt bearbeitet:

JStein52

Top Contributor
Ich wette meinen Hintern dass du das mit den grossen Zahlenwerten die du genannt hast niemals in einer Woche schaffen wirst. Die Optimierungen die Michael vorgeschlagen hat mögen ja funktionieren. Aber wie er auch schon sagt, das Problem ist linear abhängig vom Endwert. Und da ergibt eine einfache Überschlagsrechnung dass es nicht funktionieren kann. Selbst wenn ich mich bei meinen Rechnungen um einen Faktor 1000 vertan habe (wegen möglichen Optimierungen).
 

JStein52

Top Contributor
Du kannst es doch leicht selbst probieren. Ich habe eine Schleife über alle möglichen x-Werte gemacht, und darin nur mit einer einzigen Subtraktion den max. Y-Wert ausgerechnet. Sonst gar nix. Dann braucht er bei den Werten (833, 616, 10^13) 250 Sekunden (gute 4 Minuten ) dafür !!! Und da bin ich von 10^21 meilenweit entfernt.
 

Dompteur

Top Contributor
Eventuell kann man das mit einem anderen Ansatz sehr wohl viel schneller lösen.
Hier meine Gedanken dazu:
Die Aufgabe besteht darin, die Anzahl aller möglichen (x,y) Kombinationen zu finden, die die Ungleichung erfüllen.

Ich habe also die Ungleichung 98x + 35y <= 10.000
Die Anzahl der Möglichen Werte ist die Summe über eine arithmetische Reihe.
Die Reihe wird durchnummeriert von 0 bis n ( also n = 10.000/98 (=102) )

a0 (für x=0) = 10.000 / 35 - (98 / 35) * 0= 285
a1 (für x=1) = 10.000 / 35 - (98 / 35) * 1 = 282
..
a101 (für x=101) = 10.000 / 35 - (98 / 35) * 101 = 2
a102 (für x=102) = 10.000 / 35 - (98 / 35) * 102 = 0

Für die Summe der Werte einer arithmetischen Reihe gibt es ja die Formel :
summe = ( n + 1 ) ( a0 + an ) / 2

Das Problem, das es noch zu lösen gilt, ist die Problematik, dass die Werte der Reihe nicht ganzzahlig sind.
Hier endet nämlich mein Schulwissen ;-)
Vielleicht gibt es hier einen Mathematiker, der das lösen kann.

Auf jeden Fall kommt man auf diese Weisen sehr schnell zu einer guten Näherungslösung. Diese ist auch unabhängig von den Parametern.
 

JStein52

Top Contributor
Interessante Idee. Aber wenn ich die Werte die du hingeschrieben hast einsetze komme ich auf 14677.5 Das ist aber weder die exakte Lösung noch berücksichtigt es das Problem mit den doppelten Werten. Stimmt die Formel die du genannt hast ?
 

Dompteur

Top Contributor
Die Abweichung entsteht dadurch, dass die Formel für arithmetische Reihen im ganzzahligen Bereich gedacht ist. Hier haben wir aber rationale Zahlen und durch die Rundungen entstehen Fehler.
Daher auch meine Frage, ob da ein Mathematiker eine Lösung für rationale Zahlen kennt.

Das Problem der doppelten Werte verstehe ich nicht ganz. Nur, weil der gleiche Preis herauskommt, sind es trotzdem verschiedene Kombinationen.
Oder gibt es da noch eine Zusatzbedingung ?
 

InfectedBytes

Top Contributor
es geht dem TE eben nicht um die Tupel Kombinationen, sondern nur um die Preise die durch verschiedene Kombinationen erreicht werden können.

p.s.
vielleicht sollte der TE diese "drei unabhängigen Quellen" mal fragen xD
 

JStein52

Top Contributor
Die Idee von Dompteur wäre ja schon super. Aber jede Abhandlung über Reihen, Folgen etc. beginnt damit dass die Definitionsmenge die natürlichen Zahlen sind. Und ich denke mal der Übergang zu rationalen Zahlen bedeutet dann Differential- und Integralrechnung.

Edit: Stimmt glaube ich nicht ganz. Die Formel von Dompteur stimmt schon und pass auch. Das ist die Summe aller Y-Werte für das gegebene x-Intervall. Aber eben wirklich alles aufsummiert als rationale Zahl. Und es ist aus der Summe nicht mehr rauszufinden wieviele es jetzt als natürliche Zahlen sind. (also 5.7 und 5.4 ergibt dann eben 11.1 und nicht wie es richtig wäre 10 !
 
Zuletzt bearbeitet:

JStein52

Top Contributor
Und an den @TE : Du willst ja erstens sicher eine genaue Lösung haben und nach wie vor die doppelten Kombinationen entfernen ? Und gibt es denn schon eine unabhängige Quelle die sagt das geht ? Oder wurde bei der Aufgabenstellung behauptet es geht ?
 

taro

Bekanntes Mitglied
öhm ... wie wärs damit?

Java:
static int silber = 35;
  static int gold = 98;
  static int maxBetrag = 10000;

  public static void main(String[] args) {
  int zaehler = 0;
  for (int i = 1; i <= maxBetrag; i++) {
  if (kombination(i)) {
  zaehler++;
  }
  }

  System.out.println(zaehler);

  }

  public static Boolean kombination(int wert) {
  for (int j = 0; (j * silber) <= maxBetrag; j++) {

  for (int k = 0; k * gold + j * silber < maxBetrag; k++) {
  if (j * silber + k * gold == wert) {
  return true;
  }
  }
  }
  return false;
  }

Ihr denkt mir manchmal echt zu kompliziert :D

EDIT: Einrückungen scheinen mit dem "neuen" Editor wohl ein Problem zu sein?!
 
Zuletzt bearbeitet:

JStein52

Top Contributor
@taro : es geht nicht darum eine Lösung zu finden, da gibt es mehrere richtige Ansätze. Es geht darum ob das zweite Zahlenbeispiel des TE in endlicher Zeit zu lösen ist. Und auch du hast eine Schleife von 1 bis maxBetrag. Und wenn maxBetrag 10^21 ist dann hast du nächstes Jahr um die Zeit die Lösung !!!
(und mit int kannst du dann sowieso nicht mehr rechnen, und ich sehe noch nicht wo du das mit den doppelten Kombinationen berücksichtigst ?)
Das hier tut das gleiche wie deines:
Java:
  public long computeKombi(double a, double b, double c) {
      // a*x + b*y = c -> y = c/b - a/b*x
      double abschnitt = c/b;
      double steigung  = a/b;
      // boolean[] value = new boolean[(int)c];

      // den Wert x = 0 rechnen wir per Hand aus
      double y         = abschnitt;
      long   kombis    = (long)abschnitt; // x=0, y=0 macht keinen Sinn !

      while (y >= steigung) { // solange wie man die Steigung subtrahieren kann
          y = y - steigung;
          kombis = kombis+(long)y+1L;
      }
      return kombis;
  }

mit einer, und dazu noch kürzeren Schleife.
 
Zuletzt bearbeitet von einem Moderator:

taro

Bekanntes Mitglied
@taro : es geht nicht darum eine Lösung zu finden, da gibt es mehrere richtige Ansätze. Es geht darum ob das zweite Zahlenbeispiel des TE in endlicher Zeit zu lösen ist. Und auch du hast eine Schleife von 1 bis maxBetrag. Und wenn maxBetrag 10^21 ist dann hast du nächstes Jahr um die Zeit die Lösung !!!
(und mit int kannst du dann sowieso nicht mehr rechnen, und ich sehe noch nicht wo du das mit den doppelten Kombinationen berücksichtigst ?)

Das zweite Zahlenbeispiel hatte ich gar nicht wirklich wahrgenommen.

Die doppelten Kombinationen interessieren mich nicht - sobald ein Wert entsprechend in "silber" und "gold" zahlbar ist, ist es ein zahlbarer wert, unabhängig davon ob es noch weitere Kombinationen gibt - er spring dann auch entsprechend raus ...
 

taro

Bekanntes Mitglied
@taro : ..
Das hier tut das gleiche wie deines:
Code:
  public long computeKombi(double a, double b, double c) {
      // a*x + b*y = c -> y = c/b - a/b*x
      double abschnitt = c/b;
      double steigung  = a/b;
      // boolean[] value = new boolean[(int)c];

      // den Wert x = 0 rechnen wir per Hand aus
      double y         = abschnitt;
      long   kombis    = (long)abschnitt; // x=0, y=0 macht keinen Sinn !

      while (y >= steigung) { // solange wie man die Steigung subtrahieren kann
          y = y - steigung;
          kombis = kombis+(long)y+1L;
      }
      return kombis;
  }

mit einer, und dazu noch kürzeren Schleife.

Nein, tut er nicht ...
 

JStein52

Top Contributor
Ja, ist schon klar, ich hatte das mit deinen doppelten Kombinationen zuerst nicht gecheckt. Aber wie gesagt,
die Laufzeit bei dir ist soger noch extrem schlimmer als bei anderen schon vorgestellten Lösungen weil du ja wirklich für jeden einzelnen Betrag prüfswt ob es eine Kombi gibt. Und auch bei dir gilt: selbst wenn ein Schleifendurchlauf durch die äussere Schleife 1 ns (optimistisch, eher mehr weil du darin ja nochmal geschachtelte Schleifen hast !) dauert dann kommst du auf 10^12 Sekunden !!!! Wenn du deinen Rechner für die nächsten paar Jahre nicht brauchst kannst du es ja mal mit diesen Zahlen starten
 

chripo19

Mitglied
Ich habe mal nachgefragt und habe den finalen Tipp bekommen, der auch recht sinnvoll ist:

Das kgV von 35 und 98 ist 490 (5*98 oder 14*35).
D.h. wenn ich wie schon oben versucht eine For-Schleife mit a+=(10000-(i*98))/35 mache bekomme ich die Anzahl der ergebnisse. Die ergebnisse wiederholen sich ab 5*98. Somit kann es ab da vernachlässigt werden.
Auch wenn man mir hier nicht direkt helfen konnte, bedanke ich mich bei allen.

Mfg chripo19
 

chripo19

Mitglied
Selbes Prinzip habe ich nun übertragen. Lese mich nicht in BigInteger ein und benutze double. in 1 ms komme ich auf 1.4285714285714297E19. Wie kann ich die Zahl ganz ausschreiben lassen?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Best Practice Problem mit (einfacher) Doppelt-Schleife Java Basics - Anfänger-Themen 53
C Abbruch einer Schleife mit break, meine Übung funktioniert nicht richtig Java Basics - Anfänger-Themen 4
C Erste Schritte While-Schleife Java Basics - Anfänger-Themen 3
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
S Verschachtelte for-Schleife Java Basics - Anfänger-Themen 2
M Problem bei verschachtelter for-Schleife bei zweidimensionalen Arrays Java Basics - Anfänger-Themen 3
laxla123 Verschachtelte If-Else Schleife Java Basics - Anfänger-Themen 21
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
G 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
W Schleife und einmal variable++ zu viel Java Basics - Anfänger-Themen 20
sgtcoopa Array übergeben Schleife Java Basics - Anfänger-Themen 0
T Mäxchenspiel mit Schleife Java Basics - Anfänger-Themen 3
D try/catch-Block bei for-Schleife Java Basics - Anfänger-Themen 14
D Hilfe bei einer Aufgabe mit for-Schleife Java Basics - Anfänger-Themen 6
J Schleife Problem Java Basics - Anfänger-Themen 2
X Hilfe beim Übertragen in eine For-Schleife Java Basics - Anfänger-Themen 1
L while Schleife mit 2 Bedingung endet nicht Java Basics - Anfänger-Themen 3
stormyark 4 Bit in einer for-schleife funktioniert nicht Java Basics - Anfänger-Themen 3
M ArrayList mit einer Schleife befüllen Java Basics - Anfänger-Themen 2
K Schleife berechnet kein Ergebnis (Vererbung) Java Basics - Anfänger-Themen 6
S Sentinel-Schleife Java Basics - Anfänger-Themen 0
D Array mit while-schleife Java Basics - Anfänger-Themen 12
Kiki01 Wie würde eine geeignete Schleife aussehen, die die relative Häufigkeit für jeden Charakter in einem Text bestimmt? Java Basics - Anfänger-Themen 3
P9cman Vokal Zähler mit switch case und for-Schleife Java Basics - Anfänger-Themen 4
B do while Schleife Java Basics - Anfänger-Themen 3
I Fehler bei for-Schleife Java Basics - Anfänger-Themen 6
S Mit for-Schleife ein 2D JLabel-Array mit veränderbaren Icons erstellen Java Basics - Anfänger-Themen 3
D Codeverständis For-Schleife Java Basics - Anfänger-Themen 4
SergioCK Do while Schleife wiederholen Java Basics - Anfänger-Themen 14
M For-Schleife Java Basics - Anfänger-Themen 20
el_pato DialogFenster wird nicht in Schleife geöffnet? Java Basics - Anfänger-Themen 30
J if-Schleife innerhalb einer if-Schleife wird in der Konsole nicht gelesen Java Basics - Anfänger-Themen 4
EinNickname9 Denkfehler bei einfacher Schleife Java Basics - Anfänger-Themen 83
paulen1 Methoden Unerwünschte Ausgabe bei System.out.print in For-Schleife Java Basics - Anfänger-Themen 8
S Array mit for-Schleife besetzen Java Basics - Anfänger-Themen 7
CptK For-Schleife in Thread nach jedem Durchlauf pausieren Java Basics - Anfänger-Themen 35
M for schleife ohne geschweifte Klammer Java Basics - Anfänger-Themen 15
H For-Schleife bis Index von Eingabe laufen lassen Java Basics - Anfänger-Themen 24
Informatikf Methoden While Schleife Java Basics - Anfänger-Themen 3
U geschachtelte if-Schleife Java Basics - Anfänger-Themen 15
M While Schleife? Java Basics - Anfänger-Themen 4
Poppigescorn Quersumme Berechnen mit einer While Schleife Java Basics - Anfänger-Themen 13
I Potenz berechnen mit for-Schleife Java Basics - Anfänger-Themen 3
J Koordinaten per Schleife ausgeben Java Basics - Anfänger-Themen 6
S Schleife funktioniert nicht Java Basics - Anfänger-Themen 2
M For Schleife/ArrayList Java Basics - Anfänger-Themen 12
OZAN86 Methoden for schleife Java Basics - Anfänger-Themen 3
G --i versus i++ in for-Schleife Java Basics - Anfänger-Themen 11
OZAN86 For Schleife von 1-50 die Zahlen werden durch ein Komma getrennt Java Basics - Anfänger-Themen 10
M Wie kann ich Werte die in einer While Schleife sind weiter genutzt werden? Java Basics - Anfänger-Themen 7
T for-each-Schleife, verschiedene Datentypen Java Basics - Anfänger-Themen 1
T Methode um Array mit for-each-Schleife auszulesen Java Basics - Anfänger-Themen 7
Jana01 Schleife Java Basics - Anfänger-Themen 12
H Kann eine while-Schleife ein Programm blockieren? Java Basics - Anfänger-Themen 8
D For Schleife Java Basics - Anfänger-Themen 8
D Doppelte For Schleife / Array Java Basics - Anfänger-Themen 3
TimoN11 Array -> Schleife wieder von vorne durchlaufen lassen Java Basics - Anfänger-Themen 1
O Methode in while-Schleife aufrufen geht nur beim ersten Mal Java Basics - Anfänger-Themen 2
T Variable in for Schleife ansprechen ohne Array ? Java Basics - Anfänger-Themen 25
MiMa log4j als separate Dateien in Schleife? Java Basics - Anfänger-Themen 6
A Wie schaffe ich das eine while Schleife addiert danach subtrahirt? Java Basics - Anfänger-Themen 1

Ähnliche Java Themen

Neue Themen


Oben