fork download
  1. <?php // вычисление кратчайшего маршрута алгоритмом Дейкстры
  2.  
  3.  
  4. define('SUBWAY', 'sub');
  5. define('FOOT', 'foot');
  6. define('BUS', 'bus');
  7.  
  8. $transportName = array(
  9. SUBWAY => 'едешь на метро',
  10. FOOT => 'идешь пешком',
  11. BUS => 'едешь на автобусе'
  12. );
  13.  
  14.  
  15.  
  16. $startPoint = 'pet'; // начало маршрута
  17. $endPoint = 'teh'; // конец маршрута
  18. $infinity = 1000000; //вес маршрута соответствующий бесконечности
  19.  
  20.  
  21. $pointNames = array(
  22. 'pet' => 'ст. м. Петроградская',
  23. 'chk' => 'ст. м. Чкаловская',
  24. 'gor' => 'ст. м. Горьковская',
  25. 'spo' => 'ст. м. Спортивная',
  26. 'vas' => 'ст. м. Василеостровская',
  27. 'kre' => 'Петропавловская крепость',
  28. 'let' => 'Летний сад',
  29. 'dvo' => 'Дворцовая площадь',
  30. 'isa' => 'Исакиевский собор',
  31. 'nov' => 'Новая Голландия',
  32. 'ras' => 'Дом Раскольникова',
  33. 'gos' => 'Гостиный Двор',
  34. 'sen' => 'Сенная Площадь',
  35. 'vla' => 'ст. м. Владимирская',
  36. 'vit' => 'Витебский вокзал',
  37. 'teh' => 'Технологический Институт'
  38. );
  39.  
  40. $paths = array(
  41. 'pet' => array(
  42. 'chk' => canGet(10, BUS),
  43. 'gor' => canGet(3, SUBWAY)
  44. ),
  45.  
  46. 'chk' => array(
  47. 'pet' => canGet(10, BUS),
  48. 'spo' => canGet(3, SUBWAY)
  49. ),
  50.  
  51. 'gor' => array(
  52. 'pet' => canGet(3, BUS),
  53. 'kre' => canGet(5, FOOT),
  54. 'gos' => canGet(6, SUBWAY)
  55. ),
  56.  
  57. 'spo' => array(
  58. 'chk' => canGet(3, SUBWAY),
  59. 'vas' => canGet(10, BUS),
  60. 'sen' => canGet(7, SUBWAY)
  61. ),
  62.  
  63. 'vas' => array(
  64. 'spo' => canGet(10, BUS),
  65. 'gos' => canGet(7, SUBWAY),
  66. 'nov' => canGet(11, FOOT)
  67. ),
  68.  
  69. 'kre' => array(
  70. 'gor' => canGet(5, FOOT)
  71. ),
  72.  
  73. 'let' => array(
  74. 'dvo' => canGet(6, FOOT),
  75. 'gos' => canGet(7, FOOT)
  76. ),
  77.  
  78. 'dvo' => array(
  79. 'isa' => canGet(6, FOOT),
  80. 'gos' => canGet(6, FOOT),
  81. 'let' => canGet(6, FOOT)
  82. ),
  83.  
  84. 'isa' => array(
  85. 'dvo' => canGet(6, FOOT),
  86. 'nov' => canGet(5, FOOT)
  87. ),
  88.  
  89. 'nov' => array(
  90. 'vas' => canGet(11, FOOT),
  91. 'isa' => canGet(5, FOOT),
  92. 'ras' => canGet(7, BUS)
  93. ),
  94.  
  95. 'ras' => array(
  96. 'nov' => canGet(7, BUS),
  97. 'sen' => canGet(3, FOOT)
  98. ),
  99.  
  100. 'gos' => array(
  101. 'vas' => canGet(7, SUBWAY),
  102. 'sen' => canGet(3, SUBWAY),
  103. 'dvo' => canGet(6, FOOT),
  104. 'gor' => canGet(6, SUBWAY),
  105. 'let' => canGet(7, FOOT),
  106. 'vla' => canGet(7, FOOT)
  107. ),
  108.  
  109. 'sen' => array(
  110. 'ras' => canGet(3, FOOT),
  111. 'spo' => canGet(7, SUBWAY),
  112. 'gos' => canGet(3, SUBWAY),
  113. 'vla' => canGet(4, SUBWAY),
  114. 'vit' => canGet(2, SUBWAY),
  115. 'teh' => canGet(3, SUBWAY)
  116. ),
  117.  
  118. 'vla' => array(
  119. 'sen' => canGet(4, SUBWAY),
  120. 'gos' => canGet(7, FOOT),
  121. 'vit' => canGet(3, SUBWAY)
  122. ),
  123.  
  124. 'vit' => array(
  125. 'sen' => canGet(2, SUBWAY),
  126. 'teh' => canGet(2, SUBWAY),
  127. 'vla' => canGet(3, SUBWAY)
  128. ),
  129.  
  130. 'teh' => array(
  131. 'sen' => canGet(3, SUBWAY),
  132. 'vit' => canGet(2, SUBWAY)
  133. )
  134. );
  135.  
  136. /* Чтобы не писать много раз array('time' => ..., 'by' => ...), используем функцию.
  137.   «canGet» переводится как «можно попасть» */
  138. function canGet($time, $byWhat) {
  139. return array('time' => $time, 'by' => $byWhat);
  140. }
  141.  
  142. function initialTime($pointName,$paths,$pointNames,$infinity){ //задаём время маршрутов, от выбраной точки до остальных, равным бесконечности
  143. foreach($pointNames as $name=>$nameLong){ //время движения от точки до неё самой равно 0
  144. if (array_key_exists($name,$paths[$pointName])){
  145. $pathArray[$name] = array('totalTime'=>$paths[$pointName][$name]['time'],'listOfRouts'=>array(1=>array($name,$paths[$pointName][$name]['time'],$paths[$pointName][$name]['by'])));
  146. }
  147. elseif($name == $pointName){
  148. $pathArray[$name] = array('totalTime'=>0,'listOfRouts'=>array(1=>array($name,0,'Ты уже здесь.')));
  149. }
  150. else{
  151. $pathArray[$name] = array('totalTime'=>$infinity,'listOfRouts'=>array());
  152. }
  153. }
  154. return $pathArray;
  155. }
  156. function findLocalPointsTime($routs,$paths,$pointName){ //ищем время маршрутов от точки до её соседей
  157. $pathArrayInPoint = $routs;
  158. $pointContacts = $paths[$pointName];
  159. $pointTime = $routs[$pointName]['totalTime'];
  160. foreach($pointContacts as $name=>$routStat){
  161. $newTime = $pointTime + $routStat['time'];
  162. $oldTime = $routs[$name]['totalTime'];
  163. if($newTime<$oldTime){
  164. $pathArrayInPoint[$name]['totalTime'] = $newTime;
  165. $pathArrayInPoint[$name]['listOfRouts'] = $pathArrayInPoint[$pointName]['listOfRouts'];
  166. $pathArrayInPoint[$name]['listOfRouts'][] = array($name,$routStat['time'],$routStat['by']);
  167. }
  168. }
  169. return $pathArrayInPoint;
  170. }
  171.  
  172. function printRout($startPoint,$fastRout,$pointNames){ //вывод информации о маршруте
  173. $start = $startPoint;
  174. foreach($fastRout as $i=>$routStat){
  175. switch ($routStat[2]){
  176. case "sub":
  177. $byWith = "на метро";
  178. break;
  179. case "foot":
  180. $byWith = "пешком";
  181. break;
  182. case "bus":
  183. $byWith = "на автобусе";
  184. break;
  185. }
  186. $end = $routStat[0];
  187. echo "От $pointNames[$start] до $pointNames[$end] $routStat[1] мин. $byWith\n";
  188. $start = $end;
  189. }
  190. }
  191.  
  192. //выбираем начальную точку
  193. //задаём время движения до всех остальных точек бесконечным
  194. //обходим все соседние точки и считаем время движения до них
  195. //от каждой соседней точки обходим их соседние точки и считаем обзее время движения до них из первой точки
  196.  
  197. $listOfPoints = array($startPoint);
  198. $listOfPoints2 = array();
  199. $listOfCheckedPoint = array();
  200.  
  201. $routs = initialTime($startPoint,$paths,$pointNames,$infinity);
  202. $n = 0;
  203. while (isset($listOfPoints2)&&$n<10){
  204. foreach($listOfPoints as $i=>$name){
  205. if (!in_array($name,$listOfCheckedPoint)){
  206. $routs = findLocalPointsTime($routs,$paths,$name);
  207. $listOfCheckedPoint[] = $name;
  208. $b = $paths[$name];
  209. foreach($b as $name2=>$longName){
  210. $listOfPoints2[] = $name2;
  211. }
  212. }
  213. }
  214. $listOfPoints = $listOfPoints2;
  215. $listOfPoints2 = array();
  216. $n++;
  217. }
  218. echo "Путь от $pointNames[$startPoint] до $pointNames[$endPoint] займёт {$routs[$endPoint]['totalTime']} мин.\n";
  219. echo "Маршрут:\n";
  220. printRout($startPoint,$routs[$endPoint]['listOfRouts'],$pointNames);
  221. echo "Приятной поездки!\n";
  222.  
  223.  
  224.  
  225.  
  226.  
Success #stdin #stdout 0.03s 52480KB
stdin
Standard input is empty
stdout
Путь от ст. м. Петроградская до Технологический Институт займёт 15 мин.
Маршрут:
От ст. м. Петроградская до ст. м. Горьковская 3 мин. на метро
От ст. м. Горьковская до Гостиный Двор 6 мин. на метро
От Гостиный Двор до Сенная Площадь 3 мин. на метро
От Сенная Площадь до Технологический Институт 3 мин. на метро
Приятной поездки!