SHOW:
|
|
- or go back to the newest paste.
1 | class MetroGraph { | |
2 | - | constructor() { |
2 | + | constructor() { |
3 | - | this.stations = {}; |
3 | + | this.stations = {}; |
4 | - | } |
4 | + | |
5 | ||
6 | - | addStation(stationName) { |
6 | + | addStation(stationName) { |
7 | - | this.stations[stationName] = {}; |
7 | + | this.stations[stationName] = {}; |
8 | - | } |
8 | + | |
9 | ||
10 | - | addConnection(stationA, stationB, time) { |
10 | + | addConnection(stationA, stationB, time) { |
11 | - | this.stations[stationA][stationB] = time; |
11 | + | this.stations[stationA][stationB] = time; |
12 | - | this.stations[stationB][stationA] = time; |
12 | + | this.stations[stationB][stationA] = time; |
13 | - | } |
13 | + | |
14 | ||
15 | - | dijkstra(startStation, endStation) { |
15 | + | dijkstraWithMultiplePaths(startStation, endStation, numberOfPaths = 3) { |
16 | - | const distances = {}; |
16 | + | const paths = []; |
17 | - | const visited = {}; |
17 | + | |
18 | - | const path = {}; |
18 | + | for (let pathNumber = 0; pathNumber < numberOfPaths; pathNumber++) { |
19 | const distances = {}; | |
20 | - | // Инициализация начальных расстояний и пути |
20 | + | const visited = {}; |
21 | - | for (const station in this.stations) { |
21 | + | const path = {}; |
22 | - | distances[station] = Infinity; |
22 | + | |
23 | - | visited[station] = false; |
23 | + | // Инициализация начальных расстояний и пути |
24 | - | path[station] = null; |
24 | + | for (const station in this.stations) { |
25 | distances[station] = Infinity; | |
26 | visited[station] = false; | |
27 | - | distances[startStation] = 0; |
27 | + | path[station] = null; |
28 | } | |
29 | - | // Шаги алгоритма Дейкстры |
29 | + | |
30 | - | while (true) { |
30 | + | distances[startStation] = 0; |
31 | - | let currentStation = null; |
31 | + | |
32 | - | let currentDistance = Infinity; |
32 | + | // Шаги алгоритма Дейкстры |
33 | while (true) { | |
34 | - | // Находим ближайшую непосещенную станцию |
34 | + | let currentStation = null; |
35 | - | for (const station in this.stations) { |
35 | + | let currentDistance = Infinity; |
36 | - | if (!visited[station] && distances[station] < currentDistance) { |
36 | + | |
37 | - | currentStation = station; |
37 | + | // Находим ближайшую непосещенную станцию |
38 | - | currentDistance = distances[station]; |
38 | + | for (const station in this.stations) { |
39 | if (!visited[station] && distances[station] < currentDistance) { | |
40 | - | } |
40 | + | currentStation = station; |
41 | currentDistance = distances[station]; | |
42 | - | // Если все станции посещены, выходим из цикла |
42 | + | } |
43 | - | if (currentStation === null) break; |
43 | + | } |
44 | ||
45 | - | // Посещаем текущую станцию |
45 | + | // Если все станции посещены, выходим из цикла |
46 | - | visited[currentStation] = true; |
46 | + | if (currentStation === null) break; |
47 | ||
48 | - | // Обновляем расстояния до соседних станций |
48 | + | // Посещаем текущую станцию |
49 | - | for (const neighborStation in this.stations[currentStation]) { |
49 | + | visited[currentStation] = true; |
50 | - | const timeToNeighbor = this.stations[currentStation][neighborStation]; |
50 | + | |
51 | - | const totalDistance = distances[currentStation] + timeToNeighbor; |
51 | + | // Обновляем расстояния до соседних станций |
52 | for (const neighborStation in this.stations[currentStation]) { | |
53 | - | if (totalDistance < distances[neighborStation]) { |
53 | + | const timeToNeighbor = this.stations[currentStation][neighborStation]; |
54 | - | distances[neighborStation] = totalDistance; |
54 | + | const totalDistance = distances[currentStation] + timeToNeighbor; |
55 | - | path[neighborStation] = currentStation; |
55 | + | |
56 | if (totalDistance < distances[neighborStation]) { | |
57 | - | } |
57 | + | distances[neighborStation] = totalDistance; |
58 | path[neighborStation] = currentStation; | |
59 | } | |
60 | - | // Восстановление пути |
60 | + | } |
61 | - | const pathResult = [endStation]; |
61 | + | } |
62 | - | let current = endStation; |
62 | + | |
63 | // Восстановление пути | |
64 | - | while (current !== startStation) { |
64 | + | const pathResult = [endStation]; |
65 | - | const prevStation = path[current]; |
65 | + | let current = endStation; |
66 | - | pathResult.unshift(prevStation); |
66 | + | |
67 | - | current = prevStation; |
67 | + | while (current !== startStation) { |
68 | const prevStation = path[current]; | |
69 | pathResult.unshift(prevStation); | |
70 | - | return { |
70 | + | current = prevStation; |
71 | - | distance: distances[endStation], |
71 | + | } |
72 | - | path: pathResult, |
72 | + | |
73 | - | }; |
73 | + | paths.push({ |
74 | - | } |
74 | + | distance: distances[endStation], |
75 | path: pathResult, | |
76 | }); | |
77 | } | |
78 | ||
79 | // Сортировка путей по длине | |
80 | paths.sort((a, b) => a.distance - b.distance); | |
81 | ||
82 | return paths; | |
83 | } | |
84 | ||
85 | dijkstra(startStation, endStation) { | |
86 | const distances = {}; | |
87 | const visited = {}; | |
88 | const path = {}; | |
89 | ||
90 | - | const result = metro.dijkstra("A", "D"); |
90 | + | // Инициализация начальных расстояний и пути |
91 | for (const station in this.stations) { | |
92 | - | console.log("Минимальное расстояние:", result.distance); |
92 | + | distances[station] = Infinity; |
93 | - | console.log("Путь:", result.path.join(" -> ")); |
93 | + | visited[station] = false; |
94 | path[station] = null; | |
95 | } | |
96 | ||
97 | distances[startStation] = 0; | |
98 | ||
99 | // Шаги алгоритма Дейкстры | |
100 | while (true) { | |
101 | let currentStation = null; | |
102 | let currentDistance = Infinity; | |
103 | ||
104 | // Находим ближайшую непосещенную станцию | |
105 | for (const station in this.stations) { | |
106 | if (!visited[station] && distances[station] < currentDistance) { | |
107 | currentStation = station; | |
108 | currentDistance = distances[station]; | |
109 | } | |
110 | } | |
111 | ||
112 | // Если все станции посещены, выходим из цикла | |
113 | if (currentStation === null) break; | |
114 | ||
115 | // Посещаем текущую станцию | |
116 | visited[currentStation] = true; | |
117 | ||
118 | // Обновляем расстояния до соседних станций | |
119 | for (const neighborStation in this.stations[currentStation]) { | |
120 | const timeToNeighbor = this.stations[currentStation][neighborStation]; | |
121 | const totalDistance = distances[currentStation] + timeToNeighbor; | |
122 | ||
123 | if (totalDistance < distances[neighborStation]) { | |
124 | distances[neighborStation] = totalDistance; | |
125 | path[neighborStation] = currentStation; | |
126 | } | |
127 | } | |
128 | } | |
129 | ||
130 | // Восстановление пути | |
131 | const pathResult = [endStation]; | |
132 | let current = endStation; | |
133 | ||
134 | while (current !== startStation) { | |
135 | const prevStation = path[current]; | |
136 | pathResult.unshift(prevStation); | |
137 | current = prevStation; | |
138 | } | |
139 | ||
140 | return { | |
141 | distance: distances[endStation], | |
142 | path: pathResult, | |
143 | }; | |
144 | } | |
145 | } | |
146 | ||
147 | ||
148 | // Пример использования | |
149 | const metro = new MetroGraph(); | |
150 | ||
151 | metro.addStation("A"); | |
152 | metro.addStation("B"); | |
153 | metro.addStation("C"); | |
154 | metro.addStation("D"); | |
155 | ||
156 | metro.addConnection("A", "B", 5); | |
157 | metro.addConnection("B", "C", 3); | |
158 | metro.addConnection("C", "D", 7); | |
159 | metro.addConnection("A", "D", 20); | |
160 | ||
161 | const result = metro.dijkstraWithMultiplePaths("A", "D"); | |
162 | ||
163 | console.log("Result:", result); | |
164 |