/// <summary> /// Минимальный F(x) из колекции вершин /// </summary> /// <param name="array">Колекция вершин</param> /// <returns>Следующий узел для выбора</returns> private static NavigationWays GetMin(Dictionary <long, List <NavigationWays> > array, out long index) { index = -1; NavigationWays return_value = new NavigationWays(); double min = 40076001; foreach (var parent_item in array) { foreach (var item in parent_item.Value) { if (item.cost < min) { index = parent_item.Key; min = item.cost; return_value = item; } } } return(return_value); }
/// <summary> /// Нахождение пути по алгоритму А* /// </summary> /// <param name="tree">Граф</param> /// <param name="start">Начальная вершина</param> /// <param name="end">Конечная вершина</param> /// <param name="distans">Пройденный путь</param> /// <returns>Колекция вершин, что нужно пройти</returns> public List <long> getWay_A(long start, long end, out double distans, ref Dictionary <long, List <NavigationWays> > Not_Look, ref Dictionary <long, List <NavigationWays> > Look, bool reverse = false) { List <long> way = new List <long>(); distans = 0; char new_flag = 'f'; char other_flag = 's'; if (reverse) { new_flag = 's'; other_flag = 'f'; } Not_Look = new Dictionary <long, List <NavigationWays> >(); Look = new Dictionary <long, List <NavigationWays> >(); AddOutData(ref Not_Look, start, -1, end); long index; NavigationWays temp = GetMin(Not_Look, out index); tree[temp.destination_index].temp_path_crossed = tree[start][temp.destination_index]; /*if (distans < tree[index].temp_path_crossed) * NotLook*/ if (!Look.ContainsKey(index)) { Look.Add(index, new List <NavigationWays>()); } Look[index].Add(temp); Not_Look[index].Remove(temp); long root_index; while (index != end) { if (reverse_A_breaker) { return(way); } if (!blocker) { if (index_intersection == -1) { foreach (var item in Look[index]) { AddOutData(ref Not_Look, item.destination_index, index, end); } if (Not_Look.Count == 0) { reverse_A_breaker = true; return(way); } root_index = index; temp = GetMin(Not_Look, out index); if (!Look.ContainsKey(index)) { Look.Add(index, new List <NavigationWays>()); } Look[index].Add(temp); Not_Look[index].Remove(temp); if (Not_Look[index].Count == 0) { Not_Look.Remove(index); } //distans += tree[root_index][index]; tree[temp.destination_index].temp_path_crossed = tree[index].temp_path_crossed + tree[index][temp.destination_index]; if (tree[index].flag == other_flag) { index_intersection = index; //distans = tree[root_index].temp_path_crossed+tree[root_index][index]; break; } tree[index].flag = new_flag; } else { break; } } else { block_suc = true; } } if (index_intersection == -1) { reverse_A_breaker = true; way.Add(end); } else { way.Add(index_intersection); } distans = tree[way[0]].temp_path_crossed; getNextIndex_A(Look, way[0], ref way); way.Reverse(); return(way); }