Esempio n. 1
0
 /**
  * @param $departure <p>Название города отправления</p>
  * @param $destination <p>Название города прибытия</p>
  * @param $map <p>Матрица городов.
  * На пересечении столбцов и строк - стоимость
  * проезда</p>
  * @param bool $strict <p>Режим работы: если true, то матрица городов
  * используется как есть.
  * Если false - матрица городов дополняется обратными
  * маршрутами со такой же стоимостью как прямой</p>
  * @return string Сообещние о выполнение данной функции
  */
 public static function getCheapestRoute($departure, $destination, $map, $strict = true)
 {
     if (!Dijkstra::checkFormat($map)) {
         return Dijkstra::FORMAT_ERROR;
     }
     if (!$strict) {
         $map = Dijkstra::extendMap($map);
     }
     $vertices = Dijkstra::getAllVertices($map);
     if (!in_array($departure, $vertices) || !in_array($destination, $vertices)) {
         return sprintf(Dijkstra::FOUND_NO_WAY, $departure, $destination);
     }
     $wayPoint = [];
     $weight = array_fill_keys($vertices, PHP_INT_MAX);
     $weight[$departure] = 0;
     while ($weight) {
         $current = array_search(min($weight), $weight);
         if ($current == $destination) {
             break;
         }
         if (!empty($map[$current])) {
             foreach ($map[$current] as $related => $cost) {
                 if (!empty($weight[$related]) && $weight[$current] + $cost < $weight[$related]) {
                     $weight[$related] = $weight[$current] + $cost;
                     $wayPoint[$related] = array('neighbor' => $current, 'cost' => $weight[$related]);
                 }
             }
         }
         unset($weight[$current]);
     }
     if (!array_key_exists($destination, $wayPoint)) {
         return sprintf(Dijkstra::FOUND_NO_WAY, $departure, $destination);
     }
     $path = [];
     $current = $destination;
     while ($current != $departure) {
         $path[] = $current;
         $current = $wayPoint[$current]['neighbor'];
     }
     $path[] = $departure;
     $path = array_reverse($path);
     return sprintf(Dijkstra::ROUTE, $departure, $destination, implode('-->', $path), $wayPoint[$destination]['cost']);
 }