Esempio n. 1
0
        public RecursionVertexInfo(RecursionVertexInfo recursionPointInfo)
        {
            Turns    = recursionPointInfo.Turns;
            Distance = recursionPointInfo.Distance;
            Angle    = recursionPointInfo.Angle;

            ListOfPriorPoints = recursionPointInfo.ListOfPriorPoints.ToList();
        }
        public static Vertex[] FindRecommendedPath(double Percent)
        {
            stopwatch.Restart();

            //Set boundaries
            MaxPathLength     = Dijkstra.GetMinPathLength() * (1 + Percent / 100);
            BestPathLength    = MaxPathLength * (1 + Epsilon);
            MaxTurns          = Data.CalculateMaxTurns();
            StartPoint        = Data.ArrayVertices[0];
            EndPoint          = Data.ArrayVertices[1];
            StatisticsPercent = Percent;

            //Prepare datastructure for recursion
            Vertex NeighboorPoint;
            RecursionVertexInfo PriorPointInfo = new RecursionVertexInfo();

            PriorPointInfo.ListOfPriorPoints = new List <int>();
            PriorPointInfo.ListOfPriorPoints.Add(0);
            Data.ArrayVertices[0].Visited = true;
            Statistics = new long[150];

            //Start RecursionMethod
            for (int i = 0; i < StartPoint.NeighboorsIndices.Count; i++)
            {
                Statistics[0]++;
                NeighboorPoint       = Data.ArrayVertices[StartPoint.NeighboorsIndices[i]];
                PriorPointInfo.Angle = Data.CalculateAngle(StartPoint, NeighboorPoint);
                RecursionMethod(PriorPointInfo, StartPoint, NeighboorPoint, 1);
            }

            stopwatch.Stop();
            SaveStatistics();

            //Create recommended path
            List <Vertex> ListRecommendedPath = new List <Vertex>();

            for (int i = 0; i < RecommendedPathInfo.ListOfPriorPoints.Count; i++)
            {
                ListRecommendedPath.Add(Data.ArrayVertices[RecommendedPathInfo.ListOfPriorPoints[i]]);
            }
            return(ListRecommendedPath.ToArray());
        }
        private static void RecursionMethod(RecursionVertexInfo PriorPointInfo, Vertex PriorPoint, Vertex CurrentPoint, int Depth)
        {
            if (Depth >= 20)
            {
                return;
            }

            //Get data from PriorPoint
            int    Turns    = PriorPointInfo.Turns;
            double Distance = PriorPointInfo.Distance;
            double AngleOld = PriorPointInfo.Angle;

            //Check new distance
            Distance += Data.CalculateLength(PriorPoint, CurrentPoint);
            if (Distance > MaxPathLength)
            {
                return;
            }

            //Check angle and may adjust turns
            double AngleNew = Data.CalculateAngle(PriorPoint, CurrentPoint);

            //if (AngleNew != AngleOld)
            //{
            //    Turns++;
            //}
            if (Math.Abs(AngleNew - AngleOld) > Epsilon && ++Turns > MaxTurns)
            {
                return;
            }

            //Set current point
            PriorPointInfo.ListOfPriorPoints.Add(CurrentPoint.ElementNumber);
            PriorPointInfo.Distance = Distance;
            PriorPointInfo.Turns    = Turns;
            PriorPointInfo.Angle    = AngleNew;

            //May update recommended path
            if (Distance < MaxPathLength * (1 + Epsilon))
            {
                if ((CurrentPoint == EndPoint) && (Turns < MaxTurns || (Turns == MaxTurns && Distance < BestPathLength)))
                {
                    MaxTurns            = Turns;
                    BestPathLength      = Distance;
                    RecommendedPathInfo = new RecursionVertexInfo(PriorPointInfo);
                }
            }


            //Mark current point as visited
            Data.ArrayVertices[CurrentPoint.ElementNumber].Visited = true;

            //Calls itself if unvisited neighboors exist
            for (int i = 0; i < CurrentPoint.NeighboorsIndices.Count; i++)
            {
                int    IndexNeighboor = CurrentPoint.NeighboorsIndices[i];
                Vertex Neighboor      = Data.ArrayVertices[IndexNeighboor];
                if (!Neighboor.Visited)
                {
                    Statistics[Depth]++;
                    RecursionMethod(PriorPointInfo, CurrentPoint, Neighboor, ++Depth);
                    Depth--;
                }
            }

            //Reset referance changes
            PriorPointInfo.ListOfPriorPoints.Remove(CurrentPoint.ElementNumber);
            Data.ArrayVertices[CurrentPoint.ElementNumber].Visited = false;
        }