/// <summary>
 ///
 /// </summary>
 /// <param name="id">ID ребра</param>
 /// <param name="node_out">Ссылка на старт</param>
 /// <param name="node_in">Ссылка на конец</param>
 /// <param name="weight">Вес ребра</param>
 public EdgeInWork(int id, NodeInWork node_out, NodeInWork node_in, double weight)
 {
     this.id       = id;
     this.node_out = node_out;
     this.node_in  = node_in;
     this.weight   = weight;
 }
Example #2
0
 public bool TryGetValue(int id, out NodeInWork value)
 {
     return(nodes.TryGetValue(id, out value));
 }
 public OpenListValue(NodeInWork Node)
 {
     RealWeight      = new double();
     HeuristicWeight = new double();
     this.Node       = Node;
 }
 public OpenListValue(NodeInWork Node, double RealWeight, double HeuristicWeight)
 {
     this.RealWeight      = RealWeight;
     this.HeuristicWeight = HeuristicWeight;
     this.Node            = Node;
 }
Example #5
0
        /// <summary>
        /// Нахождение кратчайшего пути между двумя вершинами в графе по ССЫЛКАМ на вершины
        /// </summary>
        /// <param name="node_start">Ссылка на стартовую вершину</param>
        /// <param name="node_finish">Ссылка на конечную вершину</param>
        /// <returns>Возвращает список ребер из которых строится маршут из node_start к node_finish, при невозможности его построения - Null</returns>
        public Path MakePath(NodeInWork node_strart_link, NodeInWork node_finish_link)
        {
            if (node_strart_link == node_finish_link || node_strart_link == null || node_finish_link == null)
            {
                return(null);
            }

            //Инициализация коллекций для алгоритма А*

            //Открытый список
            Dictionary <NodeInWork, OpenListValue> open = new Dictionary <NodeInWork, OpenListValue>();
            //Сортированный список эвритических фукнций открытого списка
            List <OpenListValue> open_sorted = new List <OpenListValue>();
            //Маршрутный список
            Dictionary <NodeInWork, RoadInfo> road_map = new Dictionary <NodeInWork, RoadInfo>();


            //Стартовая инициализация алгоритма
            //Сохранения ключевых ссылок графа
            var opn_start = new OpenListValue(node_strart_link, 0, 0);

            open.Add(node_strart_link, opn_start);
            open_sorted.Add(opn_start);
            road_map.Add(node_strart_link, new RoadInfo(null, null));
            NodeInWork curr = null;

            //Проход алгоритма А*
            do
            {
                var opn_curr_weight = open_sorted[open_sorted.Count - 1];
                curr = opn_curr_weight.Node;

                //Если финальная нода была признана самой "легкой", то лучше маршрута уже не будет. Конец алгоритма.
                if (curr == node_finish_link)
                {
                    break;
                }

                open.Remove(curr);
                road_map[curr].close = true;

                open_sorted.RemoveAt(open_sorted.Count - 1);

                //Проверка всех соседей пограничной вершины на предмет веса их маршрута + эвристики
                foreach (EdgeInWork edge in curr.edge)
                {
                    RoadInfo rdm;
                    road_map.TryGetValue(edge.Node_in, out rdm);

                    if (rdm == null || !rdm.close) //Проверка на вхожение вершины в закрытый список
                    {
                        OpenListValue olv;
                        bool          flag = false;
                        if (rdm == null) //(!open.ContainsKey(edge.node_in)) -- Если записи данной вершины нет, создать её с параметрами по-умолчанию
                        {
                            olv                 = new OpenListValue(edge.Node_in);
                            olv.RealWeight      = opn_curr_weight.RealWeight + edge.weight;
                            olv.HeuristicWeight = olv.RealWeight + functionSet.heuristic_between_point(edge.Node_in, node_finish_link);

                            open.Add(edge.Node_in, olv);
                            road_map.Add(edge.Node_in, new RoadInfo(curr, edge));
                            flag = true;
                        }
                        else
                        {
                            olv = open[edge.Node_in];
                            if (olv.RealWeight > opn_curr_weight.RealWeight + edge.weight) //Если вес записанный в вершине больше чем новополученный
                            //Сохраняем новые реальные и эвристические веса
                            {                                                              //Параметры по-умолчанию безусловно входят в эту ветвь
                                                                                           //Удаляем старую эвристу из сортированного списка
                                int index = open_sorted.BinarySearch(olv);
                                while (open_sorted[index] != olv)
                                {
                                    index++;
                                }
                                open_sorted.RemoveAt(index);

                                olv.RealWeight      = opn_curr_weight.RealWeight + edge.weight;
                                olv.HeuristicWeight = olv.RealWeight + functionSet.heuristic_between_point(edge.Node_in, node_finish_link);
                                rdm.prev            = curr;
                                rdm.edge            = edge;
                                flag = true;
                            }
                        }

                        //Добавляем еще одну запись в сортированный список с сохранением сортировки
                        if (flag)
                        {
                            int findex = open_sorted.BinarySearch(olv);
                            if (findex < 0)
                            {
                                open_sorted.Insert(~findex, olv);
                            }
                            else
                            {
                                open_sorted.Insert(findex, olv);
                            }
                        }
                    }
                }
            }
            //Если открытый список пуст, то конец алгоритма
            while (!(open.Count == 0));


            //Ecли в маршрутном списке небыла создана запись под финальную точку или она соотве
            if ((road_map.ContainsKey(node_finish_link) == false))
            {
                return(null);
            }
            else
            {
                List <EdgeInWork> result = new List <EdgeInWork>();
                do
                {
                    if (road_map[curr].prev == null)
                    {
                        break;
                    }
                    else
                    {
                        result.Add(road_map[curr].edge);
                        curr = road_map[curr].prev;
                    }
                }while (true);

                result.Reverse();

                return(new Path(result));
            }
        }