简体   繁体   中英

A 500 error has occurred - Executing long loop within PHP

A 500 error has occurred - executing long loop with PHP.

I am currently working on a scheduling system to schedule nurses on a hospital ward, I am using a genetic algorithm to carry this out.

so I randomly allocate each nurses to a shift. and then work out how fit they are for the shift. I then kill off any allocation which do not meet my fitness level.

I then randomly allocate a new timetable. Assess that for fitness kill off any allocation which do not meet my fitness level.

Merge the two timetables, keeping the fitness allocations

I loop through generating random timetable, accessing its fitness and merging the timetables

This works fine while looping through 30 - 100 times

Once I go past the 100 mark it sometimes fails - a 500 error has occurred This always occurs when it takes over 2:30mins to complete the script

So I'm making the assumption at some point my server times out for taking too long?

I have added <?php set_time_limit(3600);

This is at the top of my file, not inside the constructor, or the class. Is it in the right place?
it still times out at 2 and a half minute,

Here is my code, the loop is the 200 loop Still need to refractor my code so don't be too judgmental

<?php
set_time_limit(3600);

 * Description of scheduler
 *
 * @author Dela
 */

include ("randomTtAllocation.php");
include ("fittness.php");
class scheduler {

private $randomTimetable;
private $timetable;
private $weight;
private $newTimetable ;
private $newWeight;

    function __construct($labs,$students) {

        echo "helloworld";

        // create random timetable and print it 
         $r = new randomTtAllocation();
         $this->randomTimetable = $r->__randomAllocation($labs, $students); 
         //echo "<br>" . " ............initial Time Table............." . "<br>" ;

         echo "<br>";
          echo "<br>";
           echo "<br>";


         $this->__printTt($this->randomTimetable, $this->randomTimetable);

         // work out fittness for the timetable, return fit results and print 
         $fit = new fittness( $this->randomTimetable, $labs, $students , $r->__getNumOfSessions());



         $this->newWeight = $fit->__getnewWeight();
         $this->newTimetable = $fit->__getnewTimetable();;


         //echo "<br>" . " ............newTimetable.........newWeight...." . "<br>" ;
         //$this->__printTt($this->newTimetable, $this->newWeight );

         // sort 
         $this->__sortTtByWeight();
         $this->timetable = $this->newTimetable;
         $this->weight =  $this->newWeight;


      for ($i = 0; $i < 200; $i++) {
         // create second time table 
         $this->randomTimetable = $r->__randomAllocation($labs, $students); 

        // echo "<br>" . " ............initial Time Table............." . "<br>" ;
        // $this->__printTt($this->randomTimetable, $this->randomTimetable);

         // work out fittness for the timetable, return fit results and print 
         $fit = new fittness( $this->randomTimetable, $labs, $students , $r->__getNumOfSessions());

         $this->newWeight = $fit->__getnewWeight();
         $this->newTimetable = $fit->__getnewTimetable();
         //echo "<br>" . " ............tempTimetable.........tempWeight...." . "<br>" ;
         //$this->__printTt($this->newTimetable, $this->timetable );
         $this->__sortTtByWeight();

         // merge timetables 
         echo "<br>" . " ......old...........new." . "<br>" ;
         $this->__printTt($this->timetable,$this->newTimetable );
         $this->__mergeTimetables($this->newTimetable, $this->newWeight );      

         //echo "<br>" . " ........... mergedTimetable.........newWeight...." . "<br>" ;
        //$this->__printTt($this->timetable,$this->weight );



         // fittness of new timetable
         $fit = new fittness( $this->timetable, $labs, $students , $r->__getNumOfSessions());
          echo "<br>" . " ......merged.......kulled" . "<br>" ;
         $this->__printTt($this->timetable,$fit->__getnewTimetable() );

         $this->weight = $fit->__getnewWeight();
         $this->timetable = $fit->__getnewTimetable();

           $c[$i] = $this->__countSlotsAllocated();

         echo "<br> ". $i;
     }

  print_r($c);

    }
     // sorts the re allocated time table by weight
     function __sortTtByWeight() {
                // for each slot
            foreach($this->newTimetable as $l => $i_value) {
            $size = 0;
            // see how many sessions they are taking
            while ($this->newTimetable[$l][$size] != "null") {
                if ($this->newTimetable[$l][$size] == "0") {
                    break;
                }
                $size++;
            }
            for ($i = 1; $i < $size; $i++) {
                $key = $this->newWeight[$l][$i];
                $key1 = $this->newTimetable[$l][$i];

                $k = $i - 1;
                while ($k >= 0 && $this->newWeight[$l][$k] < $key) {
                    $this->newWeight[$l][$k + 1] = $this->newWeight[$l][$k];
                    $this->newTimetable[$l][$k + 1] = $this->newTimetable[$l][$k];
                    $k--;
                }
                $this->newTimetable[$l][$k + 1] = $key1;
                $this->newWeight[$l][$k + 1] = $key;
            }
        }    
     }  
       function __countSlotsAllocated() {
           $count = 0;
           foreach($this->timetable as $i => $x_value) {
               $j = 0;
             while (($this->timetable[$i][$j] != "null") && ($this->timetable[$i][$j] != "0")){
                $count++;
                $j++;
             }
           }
           echo "count " . $count;
           return $count;
       }

     function __mergeTimetables($tempTimeTable,$tempWeight) {

        // for each session
         foreach($this->newTimetable as $i => $i_value) {
            $j = 0;
            $k = 0;
            // while there are still students

            while (($tempTimeTable[$i][$j] != "null") && ($tempTimeTable[$i][$j] != "0")) {
                            //echo $tempTimeTable[$i][$j];
                // System.out.println(timeTable[i][k]);
                // see if there is a free gap
                while ($this->timetable[$i][$k] != "null") {
                    // if student is already taking that session
                    if ($tempTimeTable[$i][$j] == $this->timetable[$i][$k]) {
                        break;
                    }
                    if ($this->timetable[$i][$k] == "0") {
                        $this->timetable[$i][$k] = $tempTimeTable[$i][$j];
                        $this->weight[$i][$k] = $tempWeight[$i][$j];
                        break;
                    }
                    $k++;
                }
                if ($this->timetable[$i][$k] == "null") {
                    if ($tempWeight[$i][$j] < $this->weight[$i][0]) {
                        $this->timetable[$i][0] = $tempTimeTable[$i][$j];
                        $this->weight[$i][0] = $tempWeight[$i][$j];

                    }
                }

                $j++;
            }
        }
     }
      function __returnTimetable() {
          return $this->timetable;
      }


      function __printTt($timetable, $weight) {

           foreach($timetable as $x => $x_value) {
             for ($i = 0; $i < 5; $i++) {
                echo $timetable[$x][$i] . " ";
             }
             echo " . . . . .";
             for ($i = 0; $i < 5; $i++) {
                echo $weight[$x][$i] . " ";
             }

             echo "<br>";
             }
         }
}

Normally you shouldn't do all this work within the http request. Instead you should start a background task and have the web page show progress on the job.

The php configuration has a time limit per request which you can adjust, but it's not expected by users to take so long.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM