private function find_routes($org, $dest, &$flights)
 {
     $result = array();
     $queue = new SplPriorityQueue();
     foreach ($flights as $flight) {
         if ($flight['org_id'] == $org) {
             $route = new Route($this->route_opts);
             $route->add_flight($flight);
             array_push($this->id, $flight['flight_id']);
             $queue->insert($route, $route->get_joy());
         }
     }
     //BFS to find all routes that take < 10 hours
     $count = 0;
     while ($queue->count() > 0 && $count < $this->opts['max_results']) {
         $cur_route = $queue->extract();
         if ($cur_route->get_dest() == $dest) {
             $result[] = $cur_route;
             $count++;
             continue;
         }
         foreach ($flights as $flight) {
             if ($flight['org_id'] == $cur_route->get_dest() && $flight['e_depart_time'] > 30 * 60 + $cur_route->get_arrival_time()) {
                 $new_route = $cur_route->copy();
                 $new_route->add_flight($flight);
                 array_push($this->id, $flight['flight_id']);
                 if ($new_route->get_trip_time() < 24 * 60 * 60) {
                     $queue->insert($new_route, $new_route->get_joy());
                 }
             }
         }
     }
     return $result;
 }
Ejemplo n.º 2
1
 private function find_routes($org, $dest, &$flights)
 {
     $result = array();
     $queue = new SplPriorityQueue();
     foreach ($flights as $flight) {
         if ($flight['org_id'] == $org) {
             $route = new Route($this->route_opts);
             $num_seats = Flight::get_open_seats_on_flight($flight['flight_id'], $this->user);
             $route->add_flight($flight, $num_seats);
             $queue->insert($route, $route->get_joy());
         }
     }
     //BFS to find all routes that take < 10 hours
     $count = 0;
     while ($queue->count() > 0 && $count < $this->opts['max_results']) {
         $cur_route = $queue->extract();
         if ($cur_route->get_dest() == $dest) {
             $result[] = $cur_route;
             $count++;
             continue;
         }
         foreach ($flights as $flight) {
             if (!array_key_exists($flight['dest_id'], $cur_route->visited) && $flight['org_id'] == $cur_route->get_dest() && $flight['e_depart_time'] > 30 * 60 + $cur_route->get_arrival_time()) {
                 $new_route = $cur_route->copy();
                 $num_seats = Flight::get_open_seats_on_flight($flight['flight_id'], $this->user);
                 $new_route->add_flight($flight, $num_seats);
                 if ($new_route->get_trip_time() < 24 * 60 * 60 && $new_route->seats >= $this->opts['passengers']) {
                     $queue->insert($new_route, $new_route->get_joy());
                 }
             }
         }
     }
     return $result;
 }
Ejemplo n.º 3
0
function encode($symb2freq)
{
    $heap = new SplPriorityQueue();
    // Instancia fila de prioridades utilizando max heap.
    $heap->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
    // define o modo de extração no caso extrai array com a prioridade
    foreach ($symb2freq as $sym => $wt) {
        $heap->insert(array($sym => ''), -$wt);
    }
    while ($heap->count() > 1) {
        $lo = $heap->extract();
        // extraio o minimo
        $hi = $heap->extract();
        // extraio o minimo
        foreach ($lo['data'] as &$x) {
            $x = '0' . $x;
        }
        foreach ($hi['data'] as &$x) {
            $x = '1' . $x;
        }
        $heap->insert($lo['data'] + $hi['data'], $lo['priority'] + $hi['priority']);
    }
    $result = $heap->extract();
    return $result['data'];
}
Ejemplo n.º 4
0
    public function __construct()
    {
        $this->queue = new \SplPriorityQueue();

        $this->timer = Loop\periodic(1, function () {
            $time = time();
            while (!$this->queue->isEmpty()) {
                $key = $this->queue->top();

                if (isset($this->expire[$key])) {
                    if ($time <= $this->expire[$key]) {
                        break;
                    }

                    unset($this->data[$key], $this->expire[$key], $this->ttl[$key]);
                }

                $this->queue->extract();
            }

            if ($this->queue->isEmpty()) {
                $this->timer->stop();
            }
        });

        $this->timer->stop();
        $this->timer->unreference();
    }
Ejemplo n.º 5
0
 /**
  * @see QueueInterface::pop()
  */
 public function pop()
 {
     if (!$this->innerQueue->isEmpty()) {
         $eta = $this->innerQueue->top()->getEta();
         if (!$eta || $eta->getTimestamp() <= time()) {
             return $this->innerQueue->extract();
         }
     }
     return false;
 }
Ejemplo n.º 6
0
 /**
  * {@inheritdoc}
  */
 public function pop()
 {
     if (!$this->queue->isEmpty()) {
         $this->queue->setExtractFlags(\SplPriorityQueue::EXTR_PRIORITY);
         $priority = $this->queue->top();
         if (time() + $priority[0] >= 0) {
             $this->queue->setExtractFlags(\SplPriorityQueue::EXTR_DATA);
             return $this->queue->extract();
         }
     }
     throw new NoItemAvailableException($this);
 }
Ejemplo n.º 7
0
 /**
  * {@inheritdoc}
  */
 public function pop()
 {
     if ($this->queue->isEmpty()) {
         return;
     }
     $this->queue->setExtractFlags(\SplPriorityQueue::EXTR_PRIORITY);
     $priority = $this->queue->top();
     if (time() + $priority[0] >= 0) {
         $this->queue->setExtractFlags(\SplPriorityQueue::EXTR_DATA);
         return $this->queue->extract();
     }
 }
Ejemplo n.º 8
0
 /**
  * 检查是否有可执行的定时任务,有的话执行
  * @return void
  */
 protected function tick()
 {
     while (!$this->_scheduler->isEmpty()) {
         $scheduler_data = $this->_scheduler->top();
         $timer_id = $scheduler_data['data'];
         $next_run_time = -$scheduler_data['priority'];
         $time_now = microtime(true);
         if ($time_now >= $next_run_time) {
             $this->_scheduler->extract();
             // 如果任务不存在,则是对应的定时器已经删除
             if (!isset($this->_task[$timer_id])) {
                 continue;
             }
             // 任务数据[func, args, flag, timer_interval]
             $task_data = $this->_task[$timer_id];
             // 如果是持续的定时任务,再把任务加到定时队列
             if ($task_data[2] === self::EV_TIMER) {
                 $next_run_time = $time_now + $task_data[3];
                 $this->_scheduler->insert($timer_id, -$next_run_time);
             }
             // 尝试执行任务
             try {
                 call_user_func_array($task_data[0], $task_data[1]);
             } catch (\Exception $e) {
                 echo $e;
             }
             continue;
         } else {
             // 设定超时时间
             $this->_selectTimeout = ($next_run_time - $time_now) * 1000000;
             return;
         }
     }
     $this->_selectTimeout = 100000000;
 }
Ejemplo n.º 9
0
 /**
  * Executes any pending timers. Returns the number of timers executed.
  *
  * @return int
  *
  * @internal
  */
 public function tick() : int
 {
     $count = 0;
     $time = microtime(true);
     while (!$this->queue->isEmpty()) {
         list($timer, $timeout) = $this->queue->top();
         if (!$this->timers->contains($timer) || $timeout !== $this->timers[$timer]) {
             $this->queue->extract();
             // Timer was removed from queue.
             continue;
         }
         if ($this->timers[$timer] > $time) {
             // Timer at top of queue has not expired.
             return $count;
         }
         // Remove and execute timer. Replace timer if persistent.
         $this->queue->extract();
         if ($timer->isPeriodic()) {
             $timeout = $time + $timer->getInterval();
             $this->queue->insert([$timer, $timeout], -$timeout);
             $this->timers[$timer] = $timeout;
         } else {
             $this->timers->detach($timer);
         }
         // Execute the timer.
         $timer->call();
         ++$count;
     }
     return $count;
 }
Ejemplo n.º 10
0
 /**
  * Tick for timer.
  * @return void
  */
 protected function tick()
 {
     while (!$this->_scheduler->isEmpty()) {
         $scheduler_data = $this->_scheduler->top();
         $timer_id = $scheduler_data['data'];
         $next_run_time = -$scheduler_data['priority'];
         $time_now = microtime(true);
         if ($time_now >= $next_run_time) {
             $this->_scheduler->extract();
             if (!isset($this->_task[$timer_id])) {
                 continue;
             }
             // [func, args, flag, timer_interval]
             $task_data = $this->_task[$timer_id];
             if ($task_data[2] === self::EV_TIMER) {
                 $next_run_time = $time_now + $task_data[3];
                 $this->_scheduler->insert($timer_id, -$next_run_time);
             }
             call_user_func_array($task_data[0], $task_data[1]);
             if (isset($this->_task[$timer_id]) && $task_data[2] === self::EV_TIMER_ONCE) {
                 $this->del($timer_id, self::EV_TIMER_ONCE);
             }
             continue;
         } else {
             $this->_selectTimeout = ($next_run_time - $time_now) * 1000000;
             return;
         }
     }
     $this->_selectTimeout = 100000000;
 }
Ejemplo n.º 11
0
 public function extract()
 {
     $data = parent::extract();
     $return = ["timer" => $data["data"], "time" => round(abs($data["priority"]) - microtime(true), 6), "tickAt" => abs($data["priority"])];
     $return["time"] = $return["time"] >= 0 ? $return["time"] : 0;
     return (object) $return;
 }
function calculate_score()
{
    global $score_board;
    global $TOTAL_P_SCORE;
    global $score_P_ratio;
    $qCur = new SplPriorityQueue();
    $qExpire = new SplPriorityQueue();
    $total_p_score = $TOTAL_P_SCORE;
    $multiplier = 0.01;
    $qCur->setExtractFlags(SplPriorityQueue::EXTR_DATA);
    $qExpire->setExtractFlags(SplPriorityQueue::EXTR_DATA);
    foreach ($score_board as $k => $r) {
        ///// f_score
        if (IsValidScoreboardEntry($k)) {
            $score_board[$k]["func"] = $score_board[$k]["check_pattern"] * pow(0.9, $score_board[$k]["mem_error"]);
            if ($score_board[$k]["mem_heap"] > 0) {
                $score_board[$k]["func"] *= ($score_board[$k]["mem_heap"] - $score_board[$k]["heap_lost"]) / $score_board[$k]["mem_heap"];
            }
            if ($r["priority"] > 0) {
                $qCur->insert($k, $r["priority"]);
            }
        } else {
            $score_board[$k]["func"] = 0;
        }
        ////// init p_score
        $score_board[$k]["p_score"] = 0;
    }
    while ($qCur->valid() && $total_p_score > 0) {
        while ($qCur->valid()) {
            $idx = $qCur->extract();
            $s = $score_board[$idx]["priority"] * $multiplier;
            // alloted score in the scheduling cycle
            if ($s > 100 - $score_board[$idx]["p_score"]) {
                $s = 100 - $score_board[$idx]["p_score"];
            }
            $score_board[$idx]["p_score"] += $s;
            $total_p_score -= $s;
            if ($score_board[$idx]["p_score"] < 100) {
                $qExpire->insert($idx, $score_board[$idx]["priority"]);
            }
        }
        $qCur = $qExpire;
        $qExpire = new SplPriorityQueue();
        $qExpire->setExtractFlags(SplPriorityQueue::EXTR_DATA);
    }
    foreach ($score_board as $k => $r) {
        $score_board[$k]["score"] = 100 * $score_board[$k]["func"] * (1 - $score_P_ratio + $score_board[$k]["p_score"] * $score_P_ratio / 100);
    }
    ////////sort by score
    $tmp = array();
    foreach ($score_board as &$ma) {
        $tmp[] =& $ma["score"];
    }
    array_multisort($tmp, SORT_DESC, $score_board);
}
Ejemplo n.º 13
0
function encode($symb2freq)
{
    $heap = new SplPriorityQueue();
    $heap->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
    foreach ($symb2freq as $sym => $wt) {
        $heap->insert(array($sym => ''), -$wt);
    }
    while ($heap->count() > 1) {
        $lo = $heap->extract();
        $hi = $heap->extract();
        foreach ($lo['data'] as &$x) {
            $x = '0' . $x;
        }
        foreach ($hi['data'] as &$x) {
            $x = '1' . $x;
        }
        $heap->insert($lo['data'] + $hi['data'], $lo['priority'] + $hi['priority']);
    }
    $result = $heap->extract();
    return $result['data'];
}
Ejemplo n.º 14
0
/**
 * Поиск самого дешёвого пути между двумя локациями
 * Для поиска используется алгоритм Дейкстры
 *
 * @see http://www.sitepoint.com/data-structures-4/
 *
 * @param array  $data   Массив с локациями и ценой проезда между ними [][src, dst, cost]
 * @param string $source Название исходного пункта
 * @param string $target Название конечного пункта
 *
 * @return SplStack
 */
function find_path(array $data, $source, $target)
{
    $graph = build_graph($data);
    // массив лучших цен кратчайшего пути для каждой локации
    $best_cost = [];
    // массив предыдущих локаций для каждой локации
    $prev_loc = array();
    // очередь из необработанных локаций
    $queue = new SplPriorityQueue();
    foreach ($graph as $src => $dst) {
        $best_cost[$src] = INF;
        // изначальные значения цен бесконечны
        $prev_loc[$src] = null;
        // предыдущие локации неизвестны
        foreach ($dst as $name => $cost) {
            // используем цену как приоритет в очереди
            $queue->insert($name, $cost);
        }
    }
    // цена поездки в исходный пункт = 0
    $best_cost[$source] = 0;
    while (!$queue->isEmpty()) {
        // получаем минимальную цену
        $u = $queue->extract();
        if (empty($graph[$u])) {
            continue;
        }
        // обрабатываем доступные маршруты для локации
        foreach ($graph[$u] as $v => $cost) {
            // альтернативная цена для маршрута
            $alt = $best_cost[$u] + $cost;
            if ($alt < $best_cost[$v]) {
                // обновляем минимальную цену для локации
                $best_cost[$v] = $alt;
                // добавляем локацию в массив предыдущих локаций
                $prev_loc[$v] = $u;
            }
        }
    }
    // ищем дешёвый путь и складываем его в стек
    $stack = new SplStack();
    $u = $target;
    $final_cost = 0;
    // проходим в обратном порядке от пункта назначения к исходному пункту
    while (isset($prev_loc[$u]) && $prev_loc[$u]) {
        $stack->push($u);
        $final_cost += $graph[$u][$prev_loc[$u]];
        $u = $prev_loc[$u];
    }
    $stack->push($source);
    return [$stack, $final_cost];
}
Ejemplo n.º 15
0
Archivo: App.php Proyecto: koolkode/k1
 /**
  * {@inheritdoc}
  */
 public final function compileRoutes(RouteCompiler $compiler, RoutingContext $context) : array
 {
     $parsed = new \SplPriorityQueue();
     foreach ($this->routes as $route) {
         foreach ($route->compile($compiler) as list($priority, $depth, $route, $regex, $mapping)) {
             $parsed->insert(\array_merge([$regex, $depth, $priority, $route], $mapping), $priority);
         }
     }
     $result = [];
     while (!$parsed->isEmpty()) {
         $result[] = $parsed->extract();
     }
     return $result;
 }
Ejemplo n.º 16
0
 /**
  * Поиск кратчайшего пути
  * @see https://www.youtube.com/watch?v=UA6aV1XJCGg
  */
 private function _shortestPath()
 {
     while (!$this->_nodeQueue->isEmpty()) {
         $u = $this->_nodeQueue->extract();
         if (!empty($this->_routes[$u])) {
             foreach ($this->_routes[$u] as $v => $cost) {
                 $newCost = $this->_destinations[$u] + $cost;
                 if ($newCost < $this->_destinations[$v]) {
                     $this->_destinations[$v] = $newCost;
                     $this->_predecessors[$v] = $u;
                 }
             }
         }
     }
 }
Ejemplo n.º 17
0
 /**
  * {@inheritdoc}
  */
 protected function dispatch(int $level)
 {
     $time = \microtime(true);
     while (!$this->scheduler->isEmpty()) {
         list($watcher, $scheduled) = $this->scheduler->top();
         if (!$watcher->enabled || $scheduled !== $watcher->scheduled) {
             $this->scheduler->extract();
             continue;
         }
         if ($watcher->due > $time) {
             break;
         }
         $this->scheduler->extract();
         if ($watcher->type === Watcher::TYPE_REPEAT) {
             $watcher->scheduled = $watcher->scheduled > 1 ? 1 : $watcher->scheduled + 1;
             $watcher->due += $watcher->delay;
             $this->scheduler->insert([$watcher, $watcher->scheduled], -$watcher->due);
         } else {
             $this->info[Watcher::TYPE_DELAY]--;
             unset($this->watchers[$watcher->id], $this->enable[$watcher->id]);
             if ($watcher->referenced) {
                 $this->watchersReferenced--;
             }
             $watcher->scheduled++;
         }
         ($watcher->callback)($watcher->id, $watcher->data);
     }
     $timeout = $this->deferred || $this->enable || $this->running <= $level ? 0 : $this->nextTimeout();
     if ($this->readStreams || $this->writeStreams) {
         $read = $this->readStreams;
         $write = $this->writeStreams;
         $except = null;
         if (0 !== @\stream_select($read, $write, $except, $timeout === null ? null : 0, (int) $timeout)) {
             if ($read) {
                 $this->notifyPolls($read, $this->readWatchers);
             }
             if ($write) {
                 $this->notifyPolls($write, $this->writeWatchers);
             }
         }
     } elseif ($timeout) {
         \usleep($timeout);
     }
     if (static::$signalsEnabled) {
         \pcntl_signal_dispatch();
     }
 }
Ejemplo n.º 18
0
 private function findNeighbors($type, $keywords, $id)
 {
     $queue = new SplPriorityQueue();
     $queue->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
     $cursor = $this->m->websites->find([]);
     foreach ($cursor as $doc) {
         if ($doc['_id'] != new MongoId($id)) {
             $d = $this->distance($type, $keywords, $doc['type'], $doc['keywords']);
             $queue->insert($doc, $d);
         }
     }
     $res = [];
     for ($i = 0; $i < 20 && !$queue->isEmpty(); $i++) {
         $res[] = $queue->extract();
     }
     return $res;
 }
Ejemplo n.º 19
0
 /**
  * Manages the queue. Dispatches processes, kills timed out processes, etc.
  */
 public function manageQueue()
 {
     //Checks if there is a SIGTERM present.
     if ($this->checkSigterm()) {
         return true;
     }
     $this->clearIdleWorkers();
     foreach ($this->workers as $index => $worker) {
         if (!$worker && count($this->queue) > 0) {
             $processName = $this->queue->extract();
             $this->workers[$index] = new Process($this->phpPath . ' app/console foreman:dispatch ' . $processName . ' --env=' . $this->kernel->getEnvironment());
             $this->workers[$index]->setTimeout($this->timeout);
             $this->workers[$index]->start();
             $this->eventDispatcher->dispatch('foreman.process.started', new ProcessStartedEvent($processName));
         }
     }
 }
Ejemplo n.º 20
0
 /**
  * @return int Milliseconds until next timer expires or -1 if there are no pending times.
  */
 private function getTimeout()
 {
     while (!$this->timerQueue->isEmpty()) {
         list($watcher, $expiration) = $this->timerQueue->top();
         $id = $watcher->id;
         if (!isset($this->timerExpires[$id]) || $expiration !== $this->timerExpires[$id]) {
             $this->timerQueue->extract();
             // Timer was removed from queue.
             continue;
         }
         $expiration -= (int) (\microtime(true) * self::MILLISEC_PER_SEC);
         if ($expiration < 0) {
             return 0;
         }
         return $expiration;
     }
     return -1;
 }
Ejemplo n.º 21
0
 private function findNearestAttributesBruteForce(ElementInterface $query, array $dataSet, $count = 1)
 {
     $smallestDistance = INF;
     $nearestElement = NULL;
     $cycles = 0;
     $nearestElsQueue = new \SplPriorityQueue();
     $nearestElements = array();
     foreach ($dataSet as $element) {
         $distance = $this->node->distance($query, $element);
         if ($distance < $smallestDistance) {
             $smallestDistance = $distance;
             $nearestElement = $element;
         }
         $priority = 1 / (1 + $distance);
         $nearestElsQueue->insert($element, $priority);
         $cycles++;
     }
     while ($count > 0 && $nearestElsQueue->count() > 0) {
         $nearestElements[] = $nearestElsQueue->extract();
         $count--;
     }
     return new \ArrayObject(array('distance' => $smallestDistance, 'element' => $nearestElement, 'elements' => $nearestElements, 'cycles' => $cycles));
 }
Ejemplo n.º 22
0
 /**
  * {@inheritdoc}
  */
 public final function compileRoutes(RouteCompiler $compiler, RoutingContext $context) : array
 {
     $ref = new \ReflectionClass(static::class);
     $parsed = new \SplPriorityQueue();
     foreach ($ref->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
         if ($method->isStatic() || !$method->hasReturnType()) {
             continue;
         }
         $type = (string) $method->getReturnType();
         if ($type !== Route::class && !\is_subclass_of($type, Route::class)) {
             continue;
         }
         $args = $context->container->populateArguments($method, [], new InjectionPoint(static::class));
         $route = $this->{$method->name}(...$args);
         foreach ($route->compile($compiler) as list($priority, $depth, $route, $regex, $mapping)) {
             $parsed->insert(\array_merge([$regex, $depth, $priority, $route], $mapping), $priority);
         }
     }
     $result = [];
     while (!$parsed->isEmpty()) {
         $result[] = $parsed->extract();
     }
     return $result;
 }
Ejemplo n.º 23
0
<?php

$queue = new SplPriorityQueue();
$queue->insert('first', 1);
$queue->insert('second', 2);
$queue->insert('third', 3);
$clone = clone $queue;
echo "Queue items: " . $queue->count() . PHP_EOL;
echo "Clone items: " . $clone->count() . PHP_EOL;
echo "Queue:" . PHP_EOL;
for ($i = 0; $i < 3; $i++) {
    echo ' ' . $queue->extract() . PHP_EOL;
}
echo "Queue items: " . $queue->count() . PHP_EOL;
echo "Clone items: " . $clone->count() . PHP_EOL;
echo "Clone:" . PHP_EOL;
for ($i = 0; $i < 3; $i++) {
    echo ' ' . $clone->extract() . PHP_EOL;
}
Ejemplo n.º 24
0
 function extract()
 {
     array_shift($this->dataStore);
     return parent::extract();
 }
Ejemplo n.º 25
0
 public function tokenize(string $input) : array
 {
     if (!$this->initialized) {
         $this->initialized = true;
         $this->initialize();
     }
     $types = [];
     $parts = [];
     $transform = [];
     foreach ($this->tokens as $k => list($v, $t)) {
         $types[] = $k;
         $parts[] = '(' . $v . ')';
         $transform[] = $t;
     }
     $sorter = new \SplPriorityQueue();
     foreach ($this->terminals as $k => list(, $terminal)) {
         $sorter->insert([$k, $terminal], strlen($terminal));
     }
     while (!$sorter->isEmpty()) {
         list($k, $terminal) = $sorter->extract();
         $types[] = $k;
         $parts[] = '(' . $terminal . ')';
         $transform[] = NULL;
     }
     $types[] = 'T_IDENTIFIER';
     $parts[] = '(' . $this->identifierPattern . ')';
     $transform[] = NULL;
     $regex = "~" . implode('|', $parts) . "~AS";
     $len = strlen($input);
     $offset = 0;
     $tokens = [];
     $line = 1;
     $pos = 1;
     $m = NULL;
     while (true) {
         if ($offset >= $len) {
             break;
         }
         if (!preg_match($regex, $input, $m, NULL, $offset)) {
             throw new \RuntimeException(sprintf('No matching token found at position: "%s"', substr($input, $offset, 10)));
         }
         $i = count($m) - 2;
         $type = $types[$i];
         $tlen = strlen($m[0]);
         if ($type === 'T_IDENTIFIER') {
             $key = strtolower($m[0]);
             if (isset($this->keywords[$key])) {
                 $keyword = $this->keywords[$key];
                 if (!$keyword[1] || $m[0] == $keyword[2]) {
                     $type = $keyword[0];
                     $m[0] = $keyword[2];
                 }
             }
         }
         if (empty($this->skip[$type])) {
             $tokens[] = $this->createToken($type, isset($transform[$i]) ? $transform[$i]($m[0]) : $m[0], $line, $pos, $offset + 1);
         }
         $offset += $tlen;
         $pos += $tlen;
         if (false !== strpos($m[0], "\n")) {
             $line += substr_count($m[0], "\n");
             $pos = strlen(substr($m[0], strrpos($m[0], "\n"))) + 1;
         }
     }
     return $tokens;
 }
 public function shortestPath($source, $target)
 {
     // initialize Q, d and pi for all vertices
     $d = array();
     // array of best estimates of shortest path to each vertex
     $pi = array();
     // array of predecessors for each vertex
     $Q = new SplPriorityQueue();
     // queue of all unoptimized vertices
     foreach ($this->graph as $v => $adj) {
         $d[$v] = INF;
         // set initial distance to "infinity"
         $pi[$v] = null;
         // no known predecessors yet
         foreach ($adj as $w => $cost) {
             // use the edge cost as the priority
             $Q->insert($w, $cost);
         }
     }
     // initial distance at source is 0
     $d[$source] = 0;
     while (!$Q->isEmpty()) {
         // extract min cost
         $u = $Q->extract();
         if (!empty($this->graph[$u])) {
             // "relax" each adjacent vertex
             foreach ($this->graph[$u] as $v => $cost) {
                 // alternate route length to adjacent neighbor
                 $alt = $d[$u] + $cost;
                 // if alternate route is shorter
                 if ($alt < $d[$v]) {
                     $d[$v] = $alt;
                     // update minimum length to vertex
                     $pi[$v] = $u;
                     // add neighbor to predecessors for vertex
                 }
             }
         }
     }
     // we can now find the shortest path using reverse iteration
     $S = new SplStack();
     // construct the shortest path with a stack S
     $u = $target;
     $dist = 0;
     // traverse from target to source
     while (isset($pi[$u]) && $pi[$u]) {
         $S->push($u);
         $dist += $this->graph[$u][$pi[$u]];
         // add distance to next predecessor
         $u = $pi[$u];
     }
     // stack will be empty if there is no route back
     if ($S->isEmpty()) {
         echo "No route from {$source} to {$target}\n";
     } else {
         // add the source node and print the path in reverse (LIFO) order
         $S->push($source);
         echo "{$dist}:";
         $sep = '';
         foreach ($S as $v) {
             echo $sep, $v;
             $sep = '->';
         }
         echo "\n";
     }
 }
Ejemplo n.º 27
0
 /**
  * Получить самый дешевый маршрут
  *
  * @param string $from Начало маршрута
  * @param string $to Конец маршрута
  *
  * @throws \Exception
  *
  * @return array
  */
 public function getPath($from, $to)
 {
     /**
      * Массив с результатом
      */
     $result = [];
     /**
      * Массив кратчайших путей к каждому узлу
      */
     $d = [];
     /**
      * Массив "предшественников" для каждого узла
      */
     $pi = [];
     /**
      * Очередь всех неоптимизированных узлов
      */
     $queue = new SplPriorityQueue();
     foreach ($this->graph as $v => $adj) {
         /**
          * Устанавливаем изначальные расстояния как бесконечность
          */
         $d[$v] = INF;
         /**
          * Никаких узлов позади нет
          */
         $pi[$v] = null;
         foreach ($adj as $w => $cost) {
             /**
              * Воспользуемся ценой связи как приоритетом
              */
             $queue->insert($w, $cost);
         }
     }
     /**
      * Начальная дистанция на стартовом узле - 0
      */
     $d[$from] = 0;
     while (!$queue->isEmpty()) {
         /**
          * Извлечем минимальную цену
          */
         $u = $queue->extract();
         if (!empty($this->graph[$u])) {
             /**
              * Пройдемся по всем соседним узлам
              */
             foreach ($this->graph[$u] as $v => $cost) {
                 /**
                  * Установим новую длину пути для соседнего узла
                  */
                 $alt = $d[$u] + $cost;
                 /**
                  * Если он оказался короче
                  *   update minimum length to vertex установим как минимальное расстояние до этого узла
                  *   добавим соседа как предшествующий этому узла
                  */
                 if ($alt < $d[$v]) {
                     $d[$v] = $alt;
                     $pi[$v] = $u;
                 }
             }
         }
     }
     /**
      * Теперь мы можем найти минимальный путь используя обратный проход
      */
     $stack = new SplStack();
     $u = $to;
     $result['sum'] = 0;
     /**
      * Проход от целевого узла до стартового
      */
     while (isset($pi[$u]) && $pi[$u]) {
         $stack->push($u);
         /**
          * Добавим стоимость для предшествующих
          */
         $result['sum'] += $this->graph[$u][$pi[$u]];
         $u = $pi[$u];
     }
     /**
      * Стек будет пустой, если нет пути назад
      */
     if ($stack->isEmpty()) {
         throw new Exception('Нет пути из ' . $from . ' в ' . $to);
     } else {
         /**
          * Добавим стартовый узел и покажем весь путь в обратном (LIFO) порядке
          */
         $stack->push($from);
         foreach ($stack as $v) {
             $result['path'][] = $v;
         }
     }
     return $result;
 }
<?php

$pq = new SplPriorityQueue();
// errors
try {
    $pq->extract();
} catch (RuntimeException $e) {
    echo "Exception: " . $e->getMessage() . "\n";
}
$pq->insert("a", 1);
$pq->insert("b", 2);
$pq->insert("c", 0);
foreach ($pq as $k => $v) {
    echo "{$k}=>" . print_r($v, 1) . "\n";
}
echo "EXTR_BOTH\n";
$pq1 = new SplPriorityQueue();
$pq1->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
$pq1->insert("a", 1);
$pq1->insert("b", 2);
$pq1->insert("c", 0);
foreach ($pq1 as $k => $v) {
    echo "{$k}=>" . print_r($v, 1) . "\n";
}
echo "EXTR_DATA\n";
$pq2 = new SplPriorityQueue();
$pq2->setExtractFlags(SplPriorityQueue::EXTR_DATA);
$pq2->insert("a", 1);
$pq2->insert("b", 2);
$pq2->insert("c", 0);
foreach ($pq2 as $k => $v) {
Ejemplo n.º 29
0
<?php

$sp = new SplPriorityQueue();
$sp->insert("1", 1);
$sp->extract(1);
// Should throw a warning as extract expects NO arguments
Ejemplo n.º 30
0
 protected function cleanup(OutputInterface $output)
 {
     // Recursive directory iterator
     $dir_it = function ($dir) {
         return new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST);
     };
     // Recursive directory deletion
     $rmdir = function ($dir) use(&$dir_it) {
         foreach ($dir_it($dir) as $file) {
             if ($file->isLink()) {
                 unlink($file->getPathname());
             } elseif ($file->isDir()) {
                 rmdir($file->getPathname());
             } else {
                 unlink($file->getPathname());
             }
         }
         rmdir($dir);
     };
     $further_cleanup_required = FALSE;
     $release_folder = $this->getReleaseDirectory();
     $distributions = array_keys($this->getConfig('distribution_info'));
     // First, release directory cleanup
     foreach (new \DirectoryIterator($release_folder) as $file) {
         if ($file->isDot() || !$file->isDir() || $file->isLink()) {
             continue;
         }
         // Remove distributions which no longer exist (have been removed from the config file).
         if (!in_array($file->getBasename(), $distributions)) {
             $rmdir($file->getPathname());
             $further_cleanup_required = TRUE;
         } else {
             // Clean up timestamped release directories within each distribution.
             // The number to keep is specified by --dirs
             $directories = new \SplPriorityQueue();
             foreach (new \DirectoryIterator($file->getPathname()) as $dir) {
                 if ($dir->isDot() || !$dir->isDir() || $dir->isLink()) {
                     continue;
                 }
                 // Store directories keeping the last modified at the top.
                 $directories->insert($dir->getPathname(), $dir->getCTime());
             }
             // No further action is required for this directory.
             if ($directories->count() <= $this->dirs) {
                 continue;
             }
             $further_cleanup_required = TRUE;
             // Timestamped release directories we want to keep
             for ($i = 0; $i < $this->dirs; $i++) {
                 $directories->extract();
             }
             // Delete all the others
             $directories->top();
             while ($directories->valid()) {
                 $dir = $directories->current();
                 $rmdir($dir);
                 $directories->next();
             }
         }
     }
     // No release directories were removed so no need to do any further cleanup.
     // (all other assets should be in use)
     if (FALSE == $further_cleanup_required) {
         return FALSE;
     }
     // Get a list of all assets that are in use (in use counts as being linked to
     // from a releases directory).
     $find_symlinks = function ($dir) use(&$dir_it) {
         $active_symlinks = [];
         foreach ($dir_it($dir) as $file) {
             // Ignore latest folder symlink
             if ($file->getBasename() != 'latest' && $file->isLink()) {
                 $active_symlinks[] = basename($file->getRealPath());
             }
         }
         return array_unique($active_symlinks);
     };
     // Find all assets that are in use
     $active_symlinks = $find_symlinks($release_folder);
     // Get a list of all assets that are downloaded
     $downloads = [];
     $base_download_dir = $this->getBaseDownloadDirectory();
     $d_it = new \DirectoryIterator($base_download_dir);
     foreach ($d_it as $file) {
         if (!$file->isDot() && $file->isDir()) {
             $downloads[] = $file->getBasename();
         }
     }
     // Calculate which asset folders need to be removed from the downloads directory.
     $to_delete = array_diff($downloads, $active_symlinks);
     if (!empty($to_delete)) {
         $assets = [];
         foreach ($to_delete as $dir) {
             $rmdir($base_download_dir . '/' . $dir);
             $parts = explode('-', $dir);
             if (count($parts) == 5) {
                 $assets[] = $parts[1] . '-' . $parts[2] . '-' . $parts[3];
             } else {
                 $assets[] = $parts[1] . '-' . $parts[2];
             }
             $hash = array_pop($parts);
             $this->removeState($parts[0], $parts[1], $hash);
         }
         $this->saveAssetsDownloadState();
         $output->writeln("<comment>Removed the following assets: " . join(',', $assets) . "</comment>");
     }
     return TRUE;
 }