public Edge_Distance Get_Min()
        {
            Edge_Distance edge = Edges_Sort.First();

            Delete_Min();
            return(edge);
        }
        public void Add_To_Heap(Edge_Distance edge)
        {
            if (Edges_Sort.Count == 0)
            {
                Edges_Sort.Add(edge);
                return;
            }

            Edges_Sort.Add(edge);
            Edge_Distance pointer = edge;

            int index_pointer = Edges_Sort.Count - 1;
            int index_prev_node;

            while (true)
            {
                index_prev_node = (index_pointer - 1) / 2;
                if (pointer.Distance < Edges_Sort[index_prev_node].Distance)
                {
                    Edges_Sort[index_pointer]   = Edges_Sort[index_prev_node];
                    Edges_Sort[index_prev_node] = pointer;
                    index_pointer = index_prev_node;
                }
                else
                {
                    break;
                }
            }
        }
        public void Delete_Min()
        {
            if (Edges_Sort.Count == 1 || Edges_Sort.Count == 2)
            {
                Edges_Sort.RemoveAt(0);
                return;
            }

            Edges_Sort[0] = Edges_Sort.Last();
            Edges_Sort.RemoveAt(Edges_Sort.Count - 1);

            Edge_Distance pointer = Edges_Sort[0];
            Edge_Distance minimum_pointer;
            int           index_pointer = 0;
            int           index_minimum_pointer;
            int           index_follow_left  = 1;
            int           index_follow_right = 2;

            while (true)
            {
                if (index_pointer != (Edges_Sort.Count - 1) / 2)
                {
                    if (index_pointer < (Edges_Sort.Count - 1) / 2)
                    {
                        minimum_pointer       = Min_Of_Three(pointer, Edges_Sort[index_follow_left], Edges_Sort[index_follow_right]);
                        index_minimum_pointer = Edges_Sort.IndexOf(minimum_pointer);
                        if (pointer == minimum_pointer)
                        {
                            return;
                        }
                        //if (pointer != minimum_pointer)
                        //{
                        Edges_Sort[index_minimum_pointer] = pointer;
                        Edges_Sort[index_pointer]         = minimum_pointer;
                        index_pointer      = index_minimum_pointer;
                        index_follow_left  = index_pointer * 2 + 1;
                        index_follow_right = index_follow_left + 1;
                        //}
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    minimum_pointer       = pointer.Distance > Edges_Sort.Last().Distance ? Edges_Sort.Last() : pointer;
                    index_minimum_pointer = Edges_Sort.IndexOf(minimum_pointer);
                    if (pointer != minimum_pointer)
                    {
                        Edges_Sort[index_minimum_pointer] = pointer;
                        Edges_Sort[index_pointer]         = minimum_pointer;
                    }
                    return;
                }
            }
        }
Beispiel #4
0
        public void Algo(Vertex start, Vertex end, double max_distance, int min_diaposon)
        {
            Reset_Label();

            bool check;


            BinaryHeap Heap_Priority  = new BinaryHeap();
            Vertex     pointer_vertex = start;
            var        edge_start     = new Edge(start, start, All_Slots);
            var        pointer_heap   = new Edge_Distance(edge_start, 0);

            Heap_Priority.Add_To_Heap(pointer_heap);
            List <int[]> list_range = new List <int[]>();

            start.Labels.Add(new Label(0, edge_start, All_Slots));
            while (Heap_Priority.Edges_Sort.Count != 0)
            {
                pointer_heap   = Heap_Priority.Get_Min();
                pointer_vertex = pointer_heap.Edge.To;

                list_range = new List <int[]>();

                foreach (var label in pointer_vertex.Labels)
                {
                    if (label.Distance == pointer_heap.Distance && label.Previous_Edge.From == pointer_heap.Edge.From && label.Previous_Edge.To == pointer_heap.Edge.To)
                    {
                        list_range.Add(label.Slots);
                    }
                }

                foreach (var range in list_range)
                {
                    foreach (var outedge in pointer_vertex.OutEdge)
                    {
                        if (outedge.Slots.Length == 0)
                        {
                            continue;
                        }
                        int[]  cross    = Cross_Range(range, outedge.Slots);
                        double distance = pointer_heap.Distance + outedge.Weight;

                        if (distance < max_distance && Max_Diaposon(cross).Length >= min_diaposon)
                        {
                            var vertex    = outedge.To;
                            var label_add = new Label(distance, outedge, cross);

                            var remove_label = new List <Label>();

                            check = true;
                            foreach (var label_vertex in vertex.Labels)
                            {
                                if (distance >= label_vertex.Distance && Comparison_Mas(cross, Cross_Range(cross, label_vertex.Slots)) == true)
                                {
                                    check = false;
                                    break;
                                }
                                if (distance <= label_vertex.Distance && Comparison_Mas(label_vertex.Slots, Cross_Range(cross, label_vertex.Slots)) == true)
                                {
                                    remove_label.Add(label_vertex);
                                }
                            }

                            if (check)
                            {
                                foreach (var label_del in remove_label)
                                {
                                    vertex.Labels.Remove(label_del);
                                }
                                vertex.Labels.Add(label_add);
                                Heap_Priority.Add_To_Heap(new Edge_Distance(outedge, distance));
                            }
                        }
                    }
                }
            }
        }
 Edge_Distance Min_Of_Three(Edge_Distance e1, Edge_Distance e2, Edge_Distance e3)
 {
     return(e1.Distance > e2.Distance ? (e2.Distance > e3.Distance ? e3 : e2) : (e1.Distance > e3.Distance ? e3 : e1));
 }