fork download
  1. <?php
  2.  
  3. /* http://d...content-available-to-author-only...2.net/ */
  4.  
  5. define('SUBWAY', "едешь на метро");
  6. define('FOOT', "идешь пешком");
  7. define('BUS', "едешь на автобусе");
  8.  
  9. /*Функция построения кратчайшего пути.
  10. Возвращает NULL, если кратчайший путь не содержит промежуточных нодов.
  11. Иначе, возвращает массив промежуточных нодов.
  12. */
  13. function getPath($start, $end, $interimStep){
  14. if ($interimStep[$start][$end] == INF) {
  15. return NULL;
  16. }
  17. $shortestPath = array();
  18. $temp = $end;
  19. while ($temp != INF) {
  20. echo "Route from $start to $temp\n";
  21. $temp = $interimStep[$start][$temp];
  22. var_dump($temp);
  23. array_unshift($shortestPath, $temp);
  24. }
  25.  
  26. var_dump($shortestPath);
  27. unset($shortestPath[0]);
  28. return $shortestPath;
  29. }
  30.  
  31. /*Функция вывода пути.
  32. */
  33. function printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames){
  34.  
  35. $pathTransport = array(
  36. 0 => array(
  37. 1 => BUS,
  38. 2 => SUBWAY
  39. ),
  40.  
  41. 1 => array(
  42. 0 => BUS,
  43. 3 => SUBWAY
  44. ),
  45.  
  46. 2 => array(
  47. 0 => BUS,
  48. 5 => FOOT,
  49. 11 => SUBWAY
  50. ),
  51.  
  52. 3 => array(
  53. 1 => SUBWAY,
  54. 4 => BUS,
  55. 12 => SUBWAY
  56. ),
  57.  
  58. 4 => array(
  59. 3 => BUS,
  60. 11 => SUBWAY,
  61. 9 => FOOT
  62. ),
  63.  
  64. 5 => array(
  65. 2 => FOOT
  66. ),
  67.  
  68. 6 => array(
  69. 7 => FOOT,
  70. 11 => FOOT
  71. ),
  72.  
  73. 7 => array(
  74. 8 => FOOT,
  75. 11 => FOOT,
  76. 6 => FOOT
  77. ),
  78.  
  79. 8 => array(
  80. 7 => FOOT,
  81. 9 => FOOT
  82. ),
  83.  
  84. 9 => array(
  85. 4 => FOOT,
  86. 8 => FOOT,
  87. 10 => BUS
  88. ),
  89.  
  90. 10 => array(
  91. 9 => BUS,
  92. 12 => FOOT
  93. ),
  94.  
  95. 11 => array(
  96. 4 => SUBWAY,
  97. 12 => SUBWAY,
  98. 7 => FOOT,
  99. 2 => SUBWAY,
  100. 6 => FOOT,
  101. 13 => FOOT
  102. ),
  103.  
  104. 12 => array(
  105. 10 => FOOT,
  106. 3 => SUBWAY,
  107. 11 => SUBWAY,
  108. 13 => SUBWAY,
  109. 14 => SUBWAY,
  110. 15 => SUBWAY
  111. ),
  112.  
  113. 13 => array(
  114. 12 => SUBWAY,
  115. 11 => FOOT,
  116. 14 => SUBWAY
  117. ),
  118.  
  119. 14 => array(
  120. 12 => SUBWAY,
  121. 15 => SUBWAY,
  122. 13 => SUBWAY
  123. ),
  124.  
  125. 15 => array(
  126. 12 => SUBWAY,
  127. 14 => SUBWAY
  128. )
  129. );
  130. echo "Начальная точка: \"{$pointNames[$startPoint]}\"\n";
  131. $temp = $startPoint;
  132. if ($shortestPath != NULL) {
  133. $temp = $startPoint;
  134. foreach ($shortestPath as $node) {
  135. echo "Из нее {$pathTransport[$temp][$node]} до точки \"{$pointNames[$node]}\" {$paths[$temp][$node]} мин.\n";
  136. $temp = $node;
  137. }
  138. }
  139.  
  140. if (empty($pathTransport[$temp][$endPoint])) {
  141. var_dump('pt', $temp, $endPoint);
  142. }
  143. if (empty($pointNames[$endPoint])) {
  144. var_dump('pn', $temp, $endPoint);
  145. }
  146. if (empty($paths[$temp][$endPoint])) {
  147. var_dump($temp, $endPoint);
  148. }
  149.  
  150. echo "Из нее {$pathTransport[$temp][$endPoint]} до точки \"{$pointNames[$endPoint]}\" {$paths[$temp][$endPoint]} мин.\n";
  151. echo "В итоге ты попадешь в точку \"{$pointNames[$endPoint]}\" за {$paths[$startPoint][$endPoint]} мин. Приятной поездки!\n\n";
  152. }
  153.  
  154. $pointNames = array(
  155. 0 => 'ст. м. Петроградская',
  156. 1 => 'ст. м. Чкаловская',
  157. 2 => 'ст. м. Горьковская',
  158. 3 => 'ст. м. Спортивная',
  159. 4 => 'ст. м. Василеостровская',
  160. 5 => 'Петропавловская крепость',
  161. 6 => 'Летний сад',
  162. 7 => 'Дворцовая площадь',
  163. 8 => 'Исакиевский собор',
  164. 9 => 'Новая Голландия',
  165. 10 => 'Дом Раскольникова',
  166. 11 => 'Гостиный Двор',
  167. 12 => 'Сенная Площадь',
  168. 13 => 'ст. м. Владимирская',
  169. 14 => 'Витебский вокзал',
  170. 15 => 'Технологический Институт'
  171. );
  172.  
  173. $paths = array(
  174. 0 => array(
  175. 1 => 10,
  176. 2 => 3
  177. ),
  178.  
  179. 1 => array(
  180. 0 => 10,
  181. 3 => 3
  182. ),
  183.  
  184. 2 => array(
  185. 0 => 3,
  186. 5 => 5,
  187. 11 => 6
  188. ),
  189.  
  190. 3 => array(
  191. 1 => 3,
  192. 4 => 10,
  193. 12 => 7
  194. ),
  195.  
  196. 4 => array(
  197. 3 => 10,
  198. 11 => 7,
  199. 9 => 11
  200. ),
  201.  
  202. 5 => array(
  203. 2 => 5
  204. ),
  205.  
  206. 6 => array(
  207. 7 => 6,
  208. 11 => 7
  209. ),
  210.  
  211. 7 => array(
  212. 8 => 6,
  213. 11 => 6,
  214. 6 => 6
  215. ),
  216.  
  217. 8 => array(
  218. 7 => 6,
  219. 9 => 5
  220. ),
  221.  
  222. 9 => array(
  223. 4 => 11,
  224. 8 => 5,
  225. 10 => 7
  226. ),
  227.  
  228. 10 => array(
  229. 9 => 7,
  230. 12 => 3
  231. ),
  232.  
  233. 11 => array(
  234. 4 => 7,
  235. 12 => 3,
  236. 7 => 6,
  237. 2 => 6,
  238. 6 => 7,
  239. 13 => 7
  240. ),
  241.  
  242. 12 => array(
  243. 10 => 3,
  244. 3 => 7,
  245. 11 => 3,
  246. 13 => 4,
  247. 14 => 2,
  248. 15 => 3
  249. ),
  250.  
  251. 13 => array(
  252. 12 => 4,
  253. 11 => 7,
  254. 14 => 3
  255. ),
  256.  
  257. 14 => array(
  258. 12 => 2,
  259. 15 => 2,
  260. 13 => 3
  261. ),
  262.  
  263. 15 => array(
  264. 12 => 3,
  265. 14 => 2
  266. )
  267. );
  268.  
  269.  
  270.  
  271. $numberOfNodes = count($pointNames);
  272.  
  273. /*Делаем квадратную матрицу путей размера $numberOfNodes, которая будет содержать время кратчайшего пути.
  274. Если путь не существует, то присваиваем ему значение бесконечности.
  275. */
  276. foreach ($paths as $i => $array) {
  277. for ($j = 0; $j < $numberOfNodes; $j++) {
  278. if (!isset($paths[$i][$j])) {
  279. $paths[$i][$j] = INF;
  280. }
  281. }
  282. }
  283.  
  284. //Массив, который будет содержать предпоследний шаг кратчайшего пути.
  285. $interimStep = array();
  286. for ($i = 0; $i < $numberOfNodes; $i++) {
  287. $interimStep[$i] = array_fill(0, $numberOfNodes, INF);
  288. }
  289.  
  290.  
  291. //Алгоритм Флойда-Уоршелла.
  292.  
  293. for ($k = 0; $k < $numberOfNodes; $k++) {
  294. for ($i = 0; $i < $numberOfNodes; $i++) {
  295. for ($j = 0; $j < $numberOfNodes; $j++) {
  296. if (($paths[$i][$k] + $paths[$k][$j]) < $paths[$i][$j]) {
  297. $paths[$i][$j] = $paths[$i][$k] + $paths[$k][$j];
  298. $interimStep[$i][$j] = $k;
  299. }
  300. }
  301. }
  302. }
  303. //var_dump($interimStep);
  304.  
  305.  
  306. //Тут вылетает предпоследняя нода (дом Раскольникова), но время всего пути выводится корректно.
  307. $startPoint = 0; // Петроградская
  308. $endPoint = 9; // Новая Голландия
  309. $shortestPath = getPath($startPoint, $endPoint, $interimStep);
  310. var_dump($shortestPath);
  311. printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames);
  312.  
  313. //ст. м. Петроградская -> Петропавловская крепость
  314. #$endPoint = 5;
  315. #$shortestPath = getPath($startPoint, $endPoint, $interimStep);
  316. #var_dump($shortestPath);
  317. #printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames);
  318.  
  319. /*Сенная Площадь -> Новая Голландия
  320. Тут все выводится корректно.
  321. */
  322. #$startPoint = 12;
  323. #$endPoint = 9;
  324. #$shortestPath = getPath($startPoint, $endPoint, $interimStep);
  325. #printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames);
  326. #
  327. #//Летний сад -> ст. м. Спортивная
  328. #$startPoint = 6;
  329. #$endPoint = 3;
  330. #$shortestPath = getPath($startPoint, $endPoint, $interimStep);
  331. #printPath($startPoint, $endPoint, $shortestPath, $paths, $pointNames);
  332.  
Success #stdin #stdout #stderr 0.01s 20520KB
stdin
Standard input is empty
stdout
Route from 0 to 9
int(12)
Route from 0 to 12
int(11)
Route from 0 to 11
int(2)
Route from 0 to 2
float(INF)
array(4) {
  [0]=>
  float(INF)
  [1]=>
  int(2)
  [2]=>
  int(11)
  [3]=>
  int(12)
}
array(3) {
  [1]=>
  int(2)
  [2]=>
  int(11)
  [3]=>
  int(12)
}
Начальная точка: "ст. м. Петроградская"
Из нее едешь на метро до точки "ст. м. Горьковская" 3 мин.
Из нее едешь на метро до точки "Гостиный Двор" 6 мин.
Из нее едешь на метро до точки "Сенная Площадь" 3 мин.
string(2) "pt"
int(12)
int(9)
Из нее  до точки "Новая Голландия" 10 мин.
В итоге ты попадешь в точку "Новая Голландия" за 22 мин. Приятной поездки!

stderr
PHP Notice:  Undefined offset: 9 in /home/R5S9gF/prog.php on line 151