do-while schleife stürzt bei vielen durchläufen ab

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • do-while schleife stürzt bei vielen durchläufen ab

    also, ich hab nen scrip gefunden, welches zufällig 6 zahlen aus 49 ausgeibt. also lottozahlen. danke dafür an den spender.

    ich hab mir daraus ein script gebastelt, welches die zufälligen zahlen dann in eine datenbank speichert, zuvor jedoch per do-while-schleife die bereits vorhandenen einträge in der datenbank überprüft, ob es keine doppelten gibt. und das ganze script ist noch mal von einer do-while-schleife umgeben, die von zähler 1 bis zähler < 13983817, was der anzahl der kombinationsmöglichkeiten für 6 aus 49 entspricht, hochzählt.

    das script stürzt aber ab, es macht nur 6 einträge in die datenbank und dann geht es nicht weiter.

    zugegeben, die 13983816 ist ne groe zahl und und mit zunehmender db-größe hat auch die interne do-while mehr zu tun, da hat die anlage zu rödeln aber selbst wenn ich das z.b. auf <50 für das schleifenende stelle stürzt sie ab. es funktiont entweder immer einzeln oder max, wenn es auf <7 stelle. dann trägt er 6 datensätze ein und dann muss ich wieder aktualisieren.

    hab ich ein fehler im script oder woran könnte es liegen?

    als milchmädchen-lösung könnte man die seite ja nach 10 sec wieder aufrufen, dann würde es auch nach und nach gehen. gibt es dafür ne möglichkeit in php oder hat einer ne ganz andere idee?

    thx und hier mal das script:

    achja, an der stelle: "datensatz schon vorhanden" stirbt das script, dort wäre es schön, wenn auch dort dann automatisch das script neu starten würde und nicht da stehen bleibt.
    gibt es da sowas wie goto zeile 1 oder so?

    PHP-Code:
    <?
    // timeout30 für scriptlaufzeit ausser kraft setzen
    ini_set("max_execution_time","0");
    require("connect.inc.php");

    $a = 1;

    do

    {

    // die folgende Zeile erzeugt einen internen
    //Startwert für den Zufallsgenerator 
            srand ((double)microtime()*1000000);
            
            // die Schleife wird sooft durchlaufen wie
            //$i kleiner 7 ist, 
            // da wir ja 6 Zahlen brauchen
            for($i=1; $i<7; $i++){
               $val = rand(1,49);
               // $val ist eine zufällige Zahl
               //zwischen 1 und 49
            
               (!strpos(" ".$vals, "$val")) ? 
               $vals .= $val." " : $i--;
             // Ist $val noch nicht in $vals
             //enthalten hänge es zzgl. Leerzeichen an
             // wenn doch verringere $i um 1
             //damit am Ende 6 Zahlen rauskommen
            }
            
            
            $arrayLotto = explode(" ", 
            trim($vals));
            // zum Sortieren verwandeln wir
            // die Zahlen am Besten in ein Array
            // trim() entfernt das hintere Leerzeichen
            
            sort($arrayLotto);
            
            
            
            // Anzahl der Datensätze auslesen
            $query = ("SELECT lz_id FROM lottozahlen");
            $result = mysql_query($query); 
           
            $anzahl = mysql_num_rows($result);
            //echo "Anzahl der Datensätze: ".$anzahl."</br>";
            
            
            // Überprüfung ob arrayLotto schon vorhanden ist
            $i = 1;
            $anzahl++;                
                do 
                    //so lange die vorhandenen datensätze
                    //überprüfen, bis übereinstimmung oder letzte id
                    {
                    $query1 = mysql_query("SELECT n1,n2,n3,n4,n5,n6 
                    FROM lottozahlen WHERE lz_id = $i");
                    $data = mysql_fetch_array($query1);
                    
                    if (in_array($data,$arrayLotto))
                    
                    {
                    
                            echo "Datensatz schon vorhanden"."</br>";
                            die;
                    
                    }
                    else
                    
                    {
                    
                            echo " ";
                    
                    }
                    
                    
                    $i++;
                    } while ($i < $anzahl);
            
            
            // einzelnen Inhalte des Arrays auf einzelne neue
            // Variabeln übertragen
             $zahl1 = $arrayLotto[0];
             $zahl2 = $arrayLotto[1];
             $zahl3 = $arrayLotto[2];
             $zahl4 = $arrayLotto[3];
             $zahl5 = $arrayLotto[4];
             $zahl6 = $arrayLotto[5];
             
                      
             mysql_query("INSERT INTO lottozahlen VALUES
             ('','$zahl1','$zahl2','$zahl3','$zahl4','$zahl5','$zahl6')");
            
                    
            
    $a++;

    } while ($a < 7);

    $query = ("SELECT lz_id FROM lottozahlen");
            $result = mysql_query($query); 
           
            $anzahl = mysql_num_rows($result);
            echo "Anzahl der Datensätze: ".$anzahl."</br>";


    ?>
    Zuletzt geändert von damilchmann; 30.04.2007, 01:17.

  • #2
    hmm, hab gerade mal ein wenig mehr über das script nachgedacht. ich bin jetzt bei 631 einträgen und bei jedem klick kommen 6 dazu und für die überprüfung von 631 einträgen braucht die db schon ca. 9 sec. wenn ich das im dreisatz hochrechne und die benötigte zeit für die einzelnen aufeinander folgenden schritte (6 Einträge überprüfen, dann 12, dann 18 usw.) dann komm ich bei 14.000.000 einträgen, die es ja an möglcihen kombinationen gibt, für die do-while auf eine benötigte zeit von 7387 jahren, also würde diese datenbank nie fertig werden.

    ich hoffe ich irre mich, was meint ihr?

    hier das script dazu. hab ich nen denkfehler darin oder gibt es keine hoffnung?

    PHP-Code:
    <?php 
    $i 
    1;
    $teil 0;
    do

    {
            
    $ergebnis = (9*$i/631);
            
            
    $teil = ($teil $ergebnis);
            
            
            
            
            
            
            
    $i = ($i 6);

    } while (
    $i 14000000);

    $ii = ($i 6);

    echo 
    "Bei ".$ii." Einträgen: "."</br>";

    echo 
    "benötigte Zeit: ".$teil." in Sekunden"."</br>";
    $erg = ($teil /60);
    echo 
    "benötigte Zeit: ".$erg." in Minuten"."</br>";
    $ergebnis1 = ($erg 60);
    echo 
    "benötigte Zeit: ".$ergebnis1." in Studen"."</br>";



    ?>

    Kommentar


    • #3
      bevor ich mich auf die diskussion einlasse - was wird das eigentlich? wozu der overkill an unnützlichen daten?

      Kommentar


      • #4
        Re: do-while schleife stürzt bei vielen durchläufen ab

        Original geschrieben von damilchmann
        ich hab mir daraus ein script gebastelt, welches die zufälligen zahlen dann in eine datenbank speichert, zuvor jedoch per do-while-schleife die bereits vorhandenen einträge in der datenbank überprüft, ob es keine doppelten gibt.
        du benötigst kein script, welches zufällige kombinationen ausgibt, sondern eines, dass systematisch alle kombinationen "durchgeht", diese kannst du dann ohne überprüfung in die db eintragen bzw. zuerst in ein csv schreiben und dann in die db importieren.
        bleibt noch die frage, warum du alle kombinationen in einer db speicher möchtest

        PHP-Code:
        $c=0;

        for(
        $n1=1$n1<50$n1++)
         for(
        $n2=$n1+1$n2<50$n2++)
          for(
        $n3=$n2+1$n3<50$n3++)
           for(
        $n4=$n3+1$n4<50$n4++)
            for(
        $n5=$n4+1$n5<50$n5++)
             for(
        $n6=$n5+1$n6<50$n6++)
              
        $c++; // or do something different - write in file or in db

        echo 'count: '.$c

        Kommentar


        • #5
          Hi,

          man beachte das laufzeitverhalten in abhängigkeit vom
          interval das durchlaufen wird. Alle schleifen hängen voneinander
          ab. Du hast exponentielle laufzeit.
          Insofern hast du schon recht was deine befürchtungen angeht.
          Man kann natürlich den wertebereich aufteilen und so die generierung
          parallelisieren was dir vorteile bringt. Dennoch sind es viele
          mögliche kombinationen, um genau zu sein: 6 über 49.
          google mal nach binomialkoeffizient um zu erfahren was das bedeutet.

          greets
          (((call/cc call/cc) (lambda (x) x)) "Scheme just rocks! and Ruby is magic!")

          Kommentar


          • #6
            Dennoch sind es viele
            mögliche kombinationen, um genau zu sein: 6 über 49.
            google mal nach binomialkoeffizient um zu erfahren was das bedeutet.
            das mit den 13 mio. irgendwas hat er ja bereits raus..

            Du hast exponentielle laufzeit.
            ich behaupte mal, er (ich beziehe mich auf 3dmaxs viel anschaulichereren code) hat konstante laufzeit O(1). zwar hängen die schleifen alle voneinander ab, doch die erste hat eine konstante zyklenzahl: 49. somit hängt die zweite schleife von einer konstanten ab und ist somit selbst konstant in der laufzeit.

            ein besseres argument jedoch ist: um exponentielle laufzeit zu haben, muss der algorithmus exponentiell oft _in der eingabegröße_ ausgeführt werden. hier aber gibt es gar keine eingabe, d.h. sein laufverhalten ist konstant.

            dass diese konstante immer noch bei etwas über 13 mio. liegt, ist natürlich eine andere frage

            aber mein einwand blieb unbeantwortet: was soll der unfug?

            Kommentar


            • #7
              aslo, der reihe nach:

              penizillin: tut mir leid, wenn ich dich enttäuschen muss aber es gebt keinen bestimmten grund. ich mach mich halt gerade mit php und sql vertraut und hab einfach das mal angefangen. ist ja auch egal, zum lernen und verstehen reicht es.
              nur ich hab halt das problem mit den while-schleifen und das ist es ja, was mich eigentlich interessiert bzw. verwundert, dass es schon bei 6 stoppt.


              3DMax: auch so neugierig, speichern deshalb, weil ich, wenn ich es schaffe natürlich auch das ergebnis haben will. deine idee hört sich gut und logisch an aber mit deinem script kann ich so noch nix anfangen, kannst du dazu noch erklärende worte loslassen? und was ist ein csv?

              closure: danke für den hinweis aber ich dachte ich hätte die exponentielle laufzeit im zweiten script beachtet und mit eingerechnet. das ergebnis jedes durchgangs wird doch beim folgenden ergebnis immer wieder dazu gerechnet. das ist aber nicht so wichtig.

              am meißten würde mich der vorschlag von 3DMax interessieren, das würde die laufzeit sicher um einiges verkürzen.

              warte neugierig und sehnsüchtig
              Zuletzt geändert von damilchmann; 30.04.2007, 21:03.

              Kommentar


              • #8
                Original geschrieben von penizillin
                das mit den 13 mio. irgendwas hat er ja bereits raus..
                oh, das hab ich überlesen.

                ich behaupte mal, er (ich beziehe mich auf 3dmaxs viel anschaulichereren code) hat konstante laufzeit O(1).
                Ich habe die obere grenze der schleifen, hier also 50
                als eingabe genommen.
                Gehen wir das zunächst mal für zwei schleifen durch.
                Für jedes i im intervall 1..n wird die zweite schleife
                von i+1 ... n durchlaufen.
                in latex-notation

                n + \sum\limits_{i=1}^n n - i

                für zwei schleifen. Das ist nicht konstant
                Es wird natürlich mit wachsender schleifenzahl nicht besser.


                zwar hängen die schleifen alle voneinander ab, doch die erste hat eine konstante zyklenzahl: 49. somit hängt die zweite schleife von einer konstanten ab und ist somit selbst konstant in der laufzeit.
                Hehe, so kann man argumentieren. Aber das wird wohl
                niemand machen.

                greets
                (((call/cc call/cc) (lambda (x) x)) "Scheme just rocks! and Ruby is magic!")

                Kommentar


                • #9
                  jetzt bin ich verwirrt. closure, du beziehst dich jetzt nicht auf meinen teil oder?

                  also mir ist klar, dass das immer länger dauert aber der vorschlag vom 3DMax würde diese zeit extrem verkürzen, da nicht ständig wieder die db-abfrage vollzogen werden müsste.

                  Kommentar


                  • #10
                    Original geschrieben von damilchmann
                    jetzt bin ich verwirrt. closure, du beziehst dich jetzt nicht auf meinen teil oder?
                    Nein auf den code von 3DMax

                    also mir ist klar, dass das immer länger dauert aber der vorschlag vom 3DMax würde diese zeit extrem verkürzen, da nicht ständig wieder die db-abfrage vollzogen werden müsste.
                    Ja natürlich, bleiben die db-abfragen weg, aber du hast immer
                    noch inserts und zwar immer noch 13 mio

                    greets
                    (((call/cc call/cc) (lambda (x) x)) "Scheme just rocks! and Ruby is magic!")

                    Kommentar


                    • #11
                      Original geschrieben von damilchmann
                      3DMax: auch so neugierig, speichern deshalb, weil ich, wenn ich es schaffe natürlich auch das ergebnis haben will. deine idee hört sich gut und logisch an aber mit deinem script kann ich so noch nix anfangen, kannst du dazu noch erklärende worte loslassen? und was ist ein csv?
                      neugierig eher nicht, ich wollte lediglich den sinn hinterfragen, aber du schreibst ja selbst, dass der tiefere sinn dahinter nicht existiert

                      naja, was soll ich da erklären?
                      angenommen, du möchtest alle lotto-kombinationen von 2 aus 2 ermitteln

                      script1:
                      PHP-Code:
                      for($n1=1$n1<3$n1++)
                       for(
                      $n2=1$n2<3$n2++)
                        echo 
                      $n1.' '.$n2.'<br />'
                      ausgabe:
                      1 1
                      1 2
                      2 1
                      2 2

                      (1,1) und (2,2) scheidet aus, da identische ziffern.
                      (1,2) und (2,1) sind redundant, da die reihenfolge keine rolle spielt.

                      darum script2, die zweite schliefe beginnt hierbei einen zähler höher ($n2=$n1+1):
                      PHP-Code:
                      for($n1=1$n1<3$n1++)
                       for(
                      $n2=$n1+1$n2<3$n2++)
                        echo 
                      $n1.' '.$n2.'<br />'
                      ausgabe:
                      1 2 - die einzige kombination - bingo

                      tja, und für 6 aus x benötigst du halt 6 geschachtelte schleifen, anstelle von zwei.
                      (kann aber bestimmt noch eleganter programmiert werden - die geschachtelten schleifen finde ich auch nicht so schön)

                      und zu csv - guckst du hier

                      ps: bei den schleifen habe ich die geschweiften klammern für die anweisungen weggelassen - mach ich immer, da ich faul bin daran solltest du dir kein vorbild nehmen und falls mehrere anweisungen erforderlich sind, sind sie auch zwingend nötig.

                      Kommentar


                      • #12
                        okay, also mit dem script bekomme ich bei jedem durchlauf doch nur 6 zahlen oder?

                        wenn ich das beispiel mit den zwei zahlen nehme, oder versteh ich das falsch, weil ich es noch nicht durchschaut habe? oder an welcher stelle leifert das aller erste script von dir alle möglichen kombis?

                        so wie es im moment sehe liefert das eine der vielen 6er-mögichkeiten die dann auch wieder abgespeichert werden müssen und es kann passieren, dass mal später die gleiche bei rum kommt. oder?...

                        nachtrag, okay, hab es gerade mal probiert, er liefert alle möglichen kombis.

                        wie bekomme ich die dann in so ein csv oder könnte ich die doch nach jedem durchgang in die db speichern. früher oder später muss ich es ja machen.
                        Zuletzt geändert von damilchmann; 30.04.2007, 22:07.

                        Kommentar


                        • #13
                          closure:
                          Ich habe die obere grenze der schleifen, hier also 50
                          als eingabe genommen.
                          6 über 49 ist nun mal keine eingabe, sondern die konstante aus einem realen bezug (lotto ziehung). wenn du schon behauptest, die werte sollen flexibel bleiben und als eingabe angesehen werden, so musst du die sechs dazunehmen. dann wird 3dmax's code aber nicht mehr hinreichend korrekt, da die anzahl der schleifen fest ist. dann wird die laufzeit auch tatsächlich exponentiell

                          damilchmann: dann machs einfacher: sag erst mal _ganz konkret_, was dein ziel ist.

                          Kommentar


                          • #14
                            Original geschrieben von damilchmann
                            wie bekomme ich die dann in so ein csv oder könnte ich die doch nach jedem durchgang in die db speichern. früher oder später muss ich es ja machen.
                            csv - fwrite($fp, $n1.','.$n2. ... .$n6."\n")
                            oder db
                            insert into ...
                            dass das 13983816 inserts werden, wurde glaube ich, schon erwähnt

                            was du so alles machen "musst" - bedauernswert

                            Kommentar


                            • #15
                              alle der möglichen kombinationen von lottozahlen in einer datenbank. ganz einfach nur das

                              also ansich funzt max´s script doch, gibt dir nen riesen haufen zahlen aus, die es dann irgendwie zu organisieren gilt

                              Kommentar

                              Lädt...
                              X