@@ -97,13 +97,14 @@ private bool IsWeightFromTo(Vertex v1, int x1, int y1, Vertex v2, int x2, int y2
97
97
}
98
98
99
99
/// <summary>
100
- /// Возвращает наикратчайший путь между двумя заданными вершинами графа
100
+ /// Возвращает кратчайший путь между двумя заданными вершинами графа
101
101
/// </summary>
102
102
/// <param name="v1">Вершина из которой необходимо найти наикратчайший путь</param>
103
103
/// <param name="v2">Вершина до которой необходимо найти наикратчайший путь</param>
104
104
/// <returns></returns>
105
- public void FindShortestPath ( Vertex start , Vertex goal )
105
+ public List < Point2D > FindShortestPathAndLength ( Vertex start , Vertex goal , out double shortestPathLength )
106
106
{
107
+ shortestPathLength = 0.0 ;
107
108
// Вершине из которой будем искать путь присваиваем нулевую метку
108
109
start . Label = 0.0 ;
109
110
goal . IsGoal = true ;
@@ -134,8 +135,37 @@ public void FindShortestPath(Vertex start, Vertex goal)
134
135
// Используем этот список посещенных вершин для поиска новой текущей вершины
135
136
current = GetCurrent ( visitedVertices ) ;
136
137
}
138
+
139
+ shortestPathLength = goal . Label ;
140
+ return GetShortestPath ( goal ) ;
137
141
}
138
142
143
+ /// <summary>
144
+ /// Возвращает кратчайший путь
145
+ /// </summary>
146
+ /// <param name="goal">целевая вершина</param>
147
+ /// <returns></returns>
148
+ private List < Point2D > GetShortestPath ( Vertex goal )
149
+ {
150
+ List < Point2D > path = new List < Point2D > ( ) ;
151
+
152
+ path . Add ( goal . Coordinate ) ;
153
+ Point2D cameFrom = goal . CameFrom ;
154
+
155
+ while ( cameFrom != null )
156
+ {
157
+ Vertex vertex = Vertices [ cameFrom . i , cameFrom . j ] ;
158
+ path . Add ( vertex . Coordinate ) ;
159
+ cameFrom = vertex . CameFrom ;
160
+ }
161
+
162
+ return path ;
163
+ }
164
+ /// <summary>
165
+ /// Возвращает текущую вершину используя список посещенных вершин
166
+ /// </summary>
167
+ /// <param name="visitedVertices">список посещенных вершин</param>
168
+ /// <returns></returns>
139
169
private Vertex GetCurrent ( List < Vertex > visitedVertices )
140
170
{
141
171
List < Vertex > unvisitedAndNotGoalNeighbors = new List < Vertex > ( ) ;
@@ -144,22 +174,34 @@ private Vertex GetCurrent(List<Vertex> visitedVertices)
144
174
if ( HasUnvisitedAndNotGoalNeighbors ( v , out unvisitedAndNotGoalNeighbors ) )
145
175
break ;
146
176
177
+ // Если не нашлось ни одного подходящего соседа, значит мы дошли до финальной вершины
147
178
if ( ! unvisitedAndNotGoalNeighbors . Any ( ) )
148
179
return null ;
149
180
181
+ // Находим и возвращаем соседа с минимальной меткой
150
182
double minLabel = unvisitedAndNotGoalNeighbors . Min ( v => v . Label ) ;
151
183
Vertex newCurrent = unvisitedAndNotGoalNeighbors . First ( v => v . Label == minLabel ) ;
152
184
153
185
return newCurrent ;
154
186
}
155
187
188
+ /// <summary>
189
+ /// Возвращает true, если у текущей вершины имеются непосещенные соседи (среди которых нет целевой вершины), иначе false,
190
+ /// а также сам список непосещенных соседей
191
+ /// </summary>
192
+ /// <param name="vertex">текущая вершина</param>
193
+ /// <param name="unvisitedAndNotGoalNeighbors">список непосещенных соседей</param>
194
+ /// <returns></returns>
156
195
private bool HasUnvisitedAndNotGoalNeighbors ( Vertex vertex , out List < Vertex > unvisitedAndNotGoalNeighbors )
157
196
{
158
197
unvisitedAndNotGoalNeighbors = GetUnvisitedNeighbors ( vertex ) . Where ( v => ! v . IsGoal ) . ToList ( ) ;
159
-
160
198
return unvisitedAndNotGoalNeighbors . Any ( ) ;
161
199
}
162
-
200
+ /// <summary>
201
+ /// Возвращает все смежные вершины для текущей, которые не посещены
202
+ /// </summary>
203
+ /// <param name="current">текущая вершина</param>
204
+ /// <returns></returns>
163
205
private List < Vertex > GetUnvisitedNeighbors ( Vertex current ) => GetAllAdjacentVertices ( current ) . Where ( v => ! v . IsVisited ) . ToList ( ) ;
164
206
165
207
#region Методы для поиска соседней вершины в зависимости от направления
0 commit comments