michaeltryl Seniormester
07. december 2017 - 14:25 Der er 4 kommentarer

Fatal error: Allowed memory size

Jeg har nedstående kode, som
1. finder korteste rute mellem x antal adresser
2. slår op på google maps hvor lang køretid der er fra sted til sted
Jeg får denne fejl
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 128 bytes) in

Har forsøgt at sætte memory op til 512, som er mit maks, men det hjælper ikke.
Kan jeg korte koden ned, eller på nogen måde dele processerne op på en smart måde.
Det er først når der skal hentes fra google map det går galt, da det virker fint hvis jeg kun skal lave den korteste rute.

//Finder korteste rute
class TSP {


    private $locations     = array();        // all locations to visit
    private $longitudes = array();
    private $latitudes     = array();
    private $shortest_route = array();    // holds the shortest route
    private $shortest_routes = array();    // any matching shortest routes
    private $shortest_distance = 0;        // holds the shortest distance
    private $all_routes = array();        // array of all the possible combinations and there distances


    // add a location
    public function add($name,$longitude,$latitude){
        $this->locations[$name] = array('longitude'=>$longitude,'latitude'=>$latitude);
    }
    // the main function that des the calculations
    public function compute(){
        $locations = $this->locations;


        foreach ($locations as $location=>$coords){
            $this->longitudes[$location] = $coords['longitude'];
            $this->latitudes[$location] = $coords['latitude'];
        }
        $locations = array_keys($locations);


        $this->all_routes = $this->array_permutations($locations);


        foreach ($this->all_routes as $key=>$perms){
            $i=0;
            $total = 0;
            foreach ($perms as $value){
                if ($i<count($this->locations)-1){
                    $total+=$this->distance($this->latitudes[$perms[$i]],$this->longitudes[$perms[$i]],$this->latitudes[$perms[$i+1]],$this->longitudes[$perms[$i+1]]);
                }
                $i++;
            }
            $this->all_routes[$key]['distance'] = $total;
            if ($total<$this->shortest_distance || $this->shortest_distance ==0){
                $this->shortest_distance = $total;
                $this->shortest_route = $perms;
                $this->shortest_routes = array();
            }
            if ($total == $this->shortest_distance){
                $this->shortest_routes[] = $perms;
            }
        }
    }
    // work out the distance between 2 longitude and latitude pairs
    function distance($lat1, $lon1, $lat2, $lon2) {
        if ($lat1 == $lat2 && $lon1 == $lon2) return 0;
        $unit = 'M';    // miles please!
        $theta = $lon1 - $lon2;
        $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
        $dist = acos($dist);
        $dist = rad2deg($dist);
        $miles = $dist * 60 * 1.1515;
        $unit = strtoupper($unit);


        if ($unit == "K") {
            return ($miles * 1.609344);
        } else if ($unit == "N") {
            return ($miles * 0.8684);
        } else {
            return $miles;
        }
    }
    // work out all the possible different permutations of an array of data
    private function array_permutations($items, $perms = array( )) {
        static $all_permutations;
        if (empty($items)) {
            $all_permutations[] = $perms;
        }  else {
            for ($i = count($items) - 1; $i >= 0; --$i) {
                $newitems = $items;
                $newperms = $perms;
                list($foo) = array_splice($newitems, $i, 1);
                array_unshift($newperms, $foo);
                $this->array_permutations($newitems, $newperms);
            }
        }
        return $all_permutations;
    }
    // return an array of the shortest possible route
    public function shortest_route(){
        return $this->shortest_route;
    }
    // returns an array of any routes that are exactly the same distance as the shortest (ie the shortest backwards normally)
    public function matching_shortest_routes(){
        return $this->shortest_routes;
    }
    // the shortest possible distance to travel
    public function shortest_distance(){
        return $this->shortest_distance;
    }
    // returns an array of all the possible routes
    public function routes(){
        return $this->all_routes;
    }
}


<?php
session_start();
chdir('../../layout/');
include '../settings/connect.php';
include '../julemand/funktioner.php';

echo"<h1>Rute hvis alle ture godkendes</h1>";
$tsp = new TSP;
$kund = mysql_query("SELECT * FROM julemand WHERE aar= '$aar' AND godkendt='ja'") or die(mysql_error());
$ned_number = mysql_num_rows($kund);
while ( $a = mysql_fetch_array($kund))
{
$hvor = $a[hvor];
$postnr = $a[postnr];
$lat = $a[latitude];
$long = $a[longitude];   

$adresse = "$hvor $postnr";
$tsp->add("$adresse",$lat,$long);
}

$tsp->compute();

$ruten = $tsp->shortest_route();
$antal_adresser = count($ruten);
//laver tidsplan
echo"<table><tr><td>Fra</td><td>Til</td><td>køretid</td><td>Ankomst</td><td>Afgang</td><td>Ankomst mellem</td></tr>";
$start = "Sjællandsgade 28 1 th 8900 Randers C";
$i = 0;
foreach($ruten as $adresser) {
    if($i == 0)
    {
        $from = $start;
        $to = $adresser;   
    }
    else
    {
        $to = $adresser;
    }
   
$from1 = urlencode($from);
$to1 = urlencode($to);

$data = file_get_contents("https://maps.googleapis.com/maps/api/distancematrix/json?origins=$from1&destinations=$to1&language=en-EN&sensor=false&key=AIzaSyADTqc-gkCiQH7CAt0l1y8y5kOtYVOL8G0");
$data = json_decode($data);

$time = 0;
$distance = 0;

foreach($data->rows[0]->elements as $road) {
    $time += $road->duration->value;
    $distance += $road->distance->value;
}
    $init = $time;
$hours = floor($init / 3600);
$minutes = floor(($init / 60) % 60);
$seconds = $init % 60;

if($i == 0)
{
    $ankomst = $start_tid;
    $time = strtotime($ankomst);
    $besogs_tid_sekunder = $besogs_tid * 60;
   
}
else
{
    $ankomst = date( "H:i:s", strtotime($afgang)+ $init);
}

$afgang =  date( "H:i:s", strtotime($ankomst)+ $besogs_tid_sekunder );
if($i != 0)
{
    $ankomst_fra = blockMinutesRound($ankomst);
    $ankomst_til = date( "H:i:s", strtotime($ankomst_fra)+ 1800 ); //lægger 30 minutter til tiden
}
echo"<tr><td>$from</td><td>$to</td><td>$hours:$minutes:$seconds</td><td>$ankomst</td><td>$afgang</td><td>$ankomst_fra - $ankomst_til</td></tr>";
    $i++;

$from = $to;

}
echo"</table>";
?>
acore Guru
07. december 2017 - 15:22 #1
Din memory_limit her er ifølge fejludsjkriften kun 128 Mb = 128*1024*1024 = 134217728 bytes.

Så start med at se på hvordan du forsøger at forøge den. Og check om det lykkes med

echo(ini_get("memory_limit"));  // Bør pt udskrive 128M (og ikke 500M), hvis jeg har ret. Du kan checke aktuelt forbrug ved at indsætte

echo(memory_get_usage());

strategiske steder i koden.

Ændringen af memory_limit kan gøres i php.ini, .htaccess og måske i din php kode. Hvordan gør du?
michaeltryl Seniormester
07. december 2017 - 18:36 #2
Ja jeg har 128 nu og har via php. Initiativet forsøgt at øge til 512 uden held.
Har dog fundet ud af st det er TSP script som laver fejlen, så jeg må nok indse at jeg ikke kan gøre det jeg ønsker :)
acore Guru
08. december 2017 - 11:48 #3
Har du opgivet?

Så vidt jeg kan se, er pkt 1 at få forøget meory_limit fra 128 til 512M.

Du kunne også starte med at se, om det kører med færre adresser og hvor den nuværende limit er. Hvor mange prøver du med?
michaeltryl Seniormester
08. december 2017 - 20:29 #4
Ja har fundet en anden løsning. Limit var Maks 8 adresse og jeg skal i hvert fald op på 20+.
Nu får jeg et script til at generere et google kort hvor alle adresser er plottet ind. Og ud fra det laver jeg selv ruten. :)
Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links

Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester





Premium
Martin Thorborg vil hænge dårlige betalere ud - men persondataloven volder problemer: "Det er min ultimative våde drøm"
Interview: Martin Thorborg mener, at Dineros brugere har krav på at få at vide, hvis de er ved sende en regning til en dårlig betaler. Men den ambition kan persondataloven spænde ben for.
Computerworld
Fona-ejer skal betale million-beløb tilbage: Hævede 22 millioner kroner lige inden krak
Fona-ejeren Elkjøp Nordic trak uretmæssigt 22 millioner kroner ud af selskabet lige inden salget af den kendte kæde gik ned med flaget.
CIO
Her er tre vigtige spørgsmål, som du altid bør stille til sælgere af it-systemer
Klumme: Softwareudviklere elsker at hade sælgere, der generelt er lidt for glatte, lidt for smilende, lidt for hjertelige og også dygtige til at undvige eller parere, når man fagligt argumenterer for sine forbehold overfor det system, man lige har fået præsenteret og lynhurtigt har spottet ikke vil fungere.
Job & Karriere
Regeringen vil gøre it-undervisning obligatorisk i folkeskolen: "Planen er, at alle danske børn skal lære at kode," siger undervisningsministeren
Interview: Regeringen indfører obligatorisk undervisning i it i folkeskolen på alle klassetrin og præsenterer fredag ny plan. Ny forsøgsordning i op til 50 skoler skal bane vejen. “Visionen for planen er, at alle danske børn skal lære at kode,” siger undervisningsminister Merete Riisager (LA).
White paper
Er cloud godt eller skidt for GDPR?
Er cloud en hjælp eller en forhindring i bestræbelserne på at overholde EU’s persondataforordning? Det er det interessante spørgsmål, dette whitepaper fra IDC sponsoreret af Oracle søger at give et svar på. På baggrund af samtaler med en række europæiske CIO’er peger whitepaper’et på fordele og ulemper og på de særlige forhold, man som it-ansvarlig skal være opmærksom på. Desuden giver whitepaper’et en grundig introduktion og redegørelse for IDC’s ’GDPR Technology Framework’. IDC Whitepaper fra november 2017. 7 sider på engelsk. Få samtidig whitepaper’et ’Helping Address Your GDPR Needs Using Oracle IT Infrastructure’ - 8 sider på engelsk.