function calcShortestPaths(vertex $start, &$adjLists) { // define an empty queue $q = new PriorityQueue(); // push the starting vertex into the queue $q->insert($start, 0); $q->rewind(); // mark the distance to it 0 $start->distance = 0; // the path to the starting vertex $start->path = array($start->key); while ($q->valid()) { $vertex = $q->extract(); $vertex->visited = 1; $list = $adjLists[$vertex->key]; while ($list->valid()) { $item = $list->current(); if (!$item['vertex']->visited) { if ($item['vertex']->distance > $vertex->distance + $item['distance']) { $item['vertex']->distance = $vertex->distance + $item['distance']; $item['vertex']->parent = $vertex; } $item['vertex']->path = array_merge($vertex->path, array($item['vertex']->key)); $q->insert($item["vertex"], $item["vertex"]->distance); } $list->next(); } $q->recoverFromCorruption(); $q->rewind(); } }
function Find($NodeStart, $NodeEnd) { $Queue = new PriorityQueue(); // Open Nodes ordered based on F cost $Queue->setExtractFlags(PriorityQueue::EXTR_DATA); $Closed = 0; $Found = FALSE; $this->Debug = ''; $this->Cache = array($NodeStart => array('G' => 0, 'F' => 0, 'Parent' => $NodeStart, 'Status' => STATUS_OPEN)); $Queue->insert($NodeStart, $this->Cache[$NodeStart]['F']); while (!$Queue->isEmpty()) { $Node = $Queue->extract(); if ($this->Cache[$Node]['Status'] == STATUS_CLOSED) { continue; } if ($Node == $NodeEnd) { $this->Cache[$Node]['Status'] = STATUS_CLOSED; $Found = TRUE; break; } if ($Closed > $this->Limit) { $this->Debug = 'Hit limit. (' . $this->Limit . ')'; return NULL; } $Neighbours = $this->Graph->Neighbours($Node); foreach ($Neighbours as $Neighbour) { $G = $this->Cache[$Node]['G'] + $this->Graph->G($Node, $Neighbour); if (isset($this->Cache[$Neighbour]) && $this->Cache[$Neighbour]['Status'] && $this->Cache[$Neighbour]['G'] <= $G) { continue; } $F = $G + $this->Graph->H($Neighbour, $NodeEnd); $this->Cache[$Neighbour] = array('G' => $G, 'F' => $F, 'Parent' => $Node, 'Status' => STATUS_OPEN); $Queue->insert($Neighbour, $F); } ++$Closed; $this->Cache[$Node]['Status'] = STATUS_CLOSED; } if ($Found) { $Path = array(); $Node = $NodeEnd; while ($NodeStart != $Node) { $Path[] = $Node; $Node = $this->Cache[$Node]['Parent']; } $Path[] = $Node; return array_reverse($Path); } $this->Debug = 'Path not found, ran out of open nodes.'; return NULL; }
} function toString() { $retStr = ""; $cnt = count($this->dataStore); for ($i = 0; $i < $cnt; ++$i) { $retStr .= $this->dataStore[$i]->name . " номер: " . $this->dataStore[$i]->priority . "\n"; } return $retStr . "\n"; } } $bank = new PriorityQueue(); $clients = ["Пупкин", "Сумкин", "Корзинкина", "Морковкин", "Зайцев"]; shuffle($clients); foreach ($clients as $p => $client) { $bank->insert(new Client($client, $p + 1), $p + 1); } print $bank->toString(); $current = $bank->extract(); print "Обслуживается: " . $current->name . "\n"; print "Ожидают очереди:\n"; print $bank->toString(); exit; $current = $bank->extract(); print "Обслуживается: " . $current->name . "\n"; print "Ожидают очереди:\n"; print $bank->toString(); $current = $bank->extract(); print "Обслуживается: " . $current->name . "\n"; print "Ожидают очереди:\n"; print $bank->toString();
function calcDistances($start) { // define an empty queue $q = new PriorityQueue(); // push the starting vertex into the queue $q->insert($start, 0); $q->rewind(); // mark the distance to it 0 $start->distance = 0; while ($q->valid()) { $t = $q->extract(); $t->visited = 1; foreach ($t->getRelations() as $key => $relation) { foreach ($relation as $object) { if (!$object->visited) { if ($object->distance > $t->distance + 1) { $object->distance = $t->distance + 1; $object->parent = $t; } $q->insert($object, $object->distance); } } } $q->recoverFromCorruption(); $q->rewind(); } }