예제 #1
0
		/// <summary>
		/// AStar Constructor.
		/// </summary>
		/// <param name="G">The graph on which AStar will perform the search.</param>
		public AStar(Graph G)
		{
			_Graph = G;
			_Open = new SortableList();
			_Closed = new SortableList();
			ChoosenHeuristic = EuclidianHeuristic;
			DijkstraHeuristicBalance = 0.5;
		}
예제 #2
0
파일: TestAStar.cs 프로젝트: snmslavk/AStar
 private static string ListNodesAndArcs(Graph GraphToDescribe)
 {
     StringBuilder SB = new StringBuilder("Description of the Graph:\n\tNodes> ");
     foreach (Node N in GraphToDescribe.Nodes) SB.Append( N.ToString()+"; " );
     SB.Append("\n\tArcs> ");
     foreach (Arc A in GraphToDescribe.Arcs) SB.Append( A.ToString()+"; " );
     return SB.ToString();
 }
예제 #3
0
파일: TestAStar.cs 프로젝트: snmslavk/AStar
        //   0  1  2  3  4
        // 0 __ __ __ N6 __
        // 1 N3 __ N5 __ __
        // 2 __ N2 __ N4 __
        // 3 __ __ N1 __ __
        // 4 __ __ __ __ __
        //
        // Begin:N1
        // Goal:N6
        // Links of Nodes: N3<-N2<-N1->N4->N5->N6
        // Result way:N1->N4->N5->N6
        public static void Main()
        {
            try
            {

                var G = new Graph();

                Node N1 = G.AddNode(2,3,0);
                Node N2 = G.AddNode(1,2,0);
                Node N3 = G.AddNode(0,1,0);
                Node N4 = G.AddNode(3,2,0);
                Node N5 = G.AddNode(2, 1, 0);
                Node N6 = G.AddNode(3, 0, 0);

                G.AddArc(N1,N2,1);
                G.AddArc(N2,N3,1);
                G.AddArc(N1,N4,1);
                G.AddArc(N4,N5,1);
                G.AddArc(N5, N6, 1);

                Console.WriteLine( ListNodesAndArcs(G) );
                Console.WriteLine("Start:"+N1.ToString());
                Console.WriteLine("Goal:" + N6.ToString());

                AStar AS = new AStar(G);
                if (AS.SearchPath(N1, N6))
                {
                    foreach (Arc A in AS.PathByArcs)
                        Console.WriteLine(A.ToString());
                }
                else
                {
                    Console.WriteLine("No result !");
                }

            }
            catch(Exception e)
            {
                Console.Write( "Error :\n\n"+e.ToString() );
            }
            Console.ReadLine();
        }
        private void Route(string s1, string s2, float maxrange, int mode)
        {
            Stopwatch sw = new Stopwatch();

            if (lastJumprange != maxrange)
            {
                G = new Graph();
                PrepareNodes(G, out nodes, maxrange, mode);
                //Console.WriteLine("Prepare nodes time: {0}", sw.Elapsed);
                lastJumprange = maxrange;
            }

            AStar AS = new AStar(G);

            Node start, stop;

            start = nodes.FirstOrDefault(x => x.System.SearchName == s1.ToLower());
            stop = nodes.FirstOrDefault(x => x.System.SearchName == s2.ToLower());
            bool res;

            if (start == null)
            {
                AppendText("Start system:  " + s1 + " unknown");
                return;
            }
            if (stop == null)
            {
                AppendText("Destination system:  " + s2 + " unknown");
                return;
            }

            sw = new Stopwatch();

            sw.Start();
            res = AS.SearchPath(start, stop);
            sw.Stop();

            AppendText("Searching route from " + s1 + " to " + s2 + Environment.NewLine);
            AppendText("Find route Time: " + sw.Elapsed.TotalSeconds.ToString("0.000s") + Environment.NewLine);
            AppendText("Total distance: " + SystemData.Distance(s1, s2).ToString("0.00") + Environment.NewLine);
            AppendText("Max jumprange:" + maxrange + Environment.NewLine);

            double totdist = 0;
            int jumps = 0;

            if (res)
            {
                foreach (Arc A in AS.PathByArcs)
                {
                    double dist = SystemData.Distance(A.StartNode.System.name, A.EndNode.System.name);
                    AppendText(A.EndNode.System.name + " \tDist: " + dist.ToString("0.00") + " ly" + Environment.NewLine);
                    totdist += dist;
                    jumps++;

                    Console.WriteLine(A.ToString());
                }

               // JArray ja = Path2JSON(AS);
            }
            else Console.WriteLine("No result !");

            AppendText("Total distance: " + totdist.ToString("0.00") + Environment.NewLine);
            AppendText("Jumps: " + jumps + Environment.NewLine);
        }
        private void PrepareNodes(Graph G, out List<Node> nodes, float maxrange, int mode)
        {
            List<SystemClass> systems = SystemData.SystemList;
            nodes = new List<Node>();
            SystemClass arcsystem;
            float distance, maxrangex2 = maxrange * maxrange;
            Node N2;
            float weight = 1;
            float dx, dy, dz;

            Stopwatch sw = new Stopwatch();

            sw.Start();

            SystemClass system;
            Node N1;

            for (int ii = 0; ii < systems.Count; ii++)
            {
                system = systems[ii];
                N1 = new Node(system.x, system.y, system.z, system);

                G.AddNodeWithNoChk(N1);
                nodes.Add(N1);
            }

            sw.Stop();

            AppendText("Add stars: " + sw.Elapsed.TotalSeconds.ToString("0.000s") + Environment.NewLine);

            sw.Restart();
            for (int ii = 0; ii < systems.Count; ii++)
            {
                system = systems[ii];
                N1 = nodes[ii];

                for (int jj = ii; jj < systems.Count; jj++)
                {
                    arcsystem = systems[jj];

                    dx = (float)(system.x - arcsystem.x);
                    dy = (float)(system.y - arcsystem.y);
                    dz = (float)(system.z - arcsystem.z);
                    distance = dx * dx + dy * dy + dz * dz;

                    //distance = (float)((system.x - arcsystem.x) * (system.x - arcsystem.x) + (system.y - arcsystem.y) * (system.y - arcsystem.y) + (system.z - arcsystem.z) * (system.z - arcsystem.z));

                    if (distance > 0 && distance <= maxrangex2)
                    {
                        N2 = nodes[jj];

                        if (mode == 1)
                            weight = (float)(1 / distance);

                        G.AddArcWithNoChk(N1, N2, weight);
                        G.AddArcWithNoChk(N2, N1, weight);
                    }
                }
            }

            sw.Stop();
            //Console.WriteLine("Create arcs: {0}", sw.Elapsed);
            AppendText("Create arcs: " + sw.Elapsed.TotalSeconds.ToString("0.000s") + Environment.NewLine);
        }
예제 #6
0
        private static void ParseDataIntoGraph()
        {
            g = new Graph();

            // LOAD NODES
            for (int y = 0; y <= squareSize_1; y++)
            {
                for (int x = 0; x <= squareSize_1; x++)
                {
                    g.AddNode(nodes[x, y]);
                }

            }

            // LOAD ARCS
            for (int y = 0; y <= squareSize_1; y++)
            {
                for (int x = 0; x <= squareSize_1; x++)
                {
                    // check up
                    if (y > 0)
                    {
                        g.AddArc(nodes[x, y], nodes[x, y - 1], fileNodes[x, y - 1]);
                    }

                    // check down
                    if (y < squareSize_1)
                    {
                        g.AddArc(nodes[x, y], nodes[x, y + 1], fileNodes[x, y + 1]);
                    }

                    // check left
                    if (x >0)
                    {
                        g.AddArc(nodes[x, y], nodes[x - 1, y], fileNodes[x - 1, y]);
                    }

                    // check right
                    if (x < squareSize_1)
                    {
                        g.AddArc(nodes[x, y], nodes[x + 1, y], fileNodes[x + 1, y]);
                    }
                }

            }
        }
예제 #7
0
        /// <summary>
        /// Build level graph
        /// </summary>
        /// <param name="l"></param>
        public void LoadData(LevelMapData l)
        {
            level = l;
            //make graph based on map

            try
            {
                MapGraph = new Graph();

                MapNodes = new Node[level.Height * level.Width];

                // put nodes in graph and array
                for (int i = 0; i < level.Height * level.Width; i++)
                {
                    if (level.GetSquareAt(i % level.Width, i / level.Width).type == MapSquareType.Open)
                    {
                        MapNodes[i] = MapGraph.AddNode((i % level.Width) * 16 -8, (i / level.Width) * 16 -8, 0);
                    }
                }

                for (int i = 0; i < level.Height * level.Width; i++)
                {
                    //updown
                    if (i / level.Width > 0)
                    {
                        if (MapNodes[i - level.Width] != null && MapNodes[i] != null)
                            MapGraph.Add2Arcs(MapNodes[i], MapNodes[i - level.Width], 1);
                    }
                    //leftright
                    if (i % level.Width > 0)
                    {
                        if (MapNodes[i - 1] != null && MapNodes[i] != null)
                            MapGraph.Add2Arcs(MapNodes[i], MapNodes[i - 1], 1);
                    }
                    //top left diag
                    if (i % level.Width > 0 && i / level.Width > 0)
                    {
                        if (MapNodes[i - level.Width - 1] != null && MapNodes[i] != null && MapNodes[i - level.Width] != null && MapNodes[i - 1] != null)
                            MapGraph.Add2Arcs(MapNodes[i], MapNodes[i - level.Width - 1], 1);
                    }
                    //top right diag
                    if (i % level.Width < level.Width - 1 && i / level.Width > 0)
                    {
                        if (MapNodes[i - level.Width + 1] != null && MapNodes[i] != null && MapNodes[i + 1] != null && MapNodes[i - level.Width] != null)
                            MapGraph.Add2Arcs(MapNodes[i], MapNodes[i - level.Width + 1], 1);
                    }
                }
            }
            catch (Exception e) { throw e; }
        }
예제 #8
0
        private void Route(string s1, string s2, float maxrange, int mode)
        {
            EDDiscovery2.DB.ISystem ds1 = SystemData.GetSystem(s1);
            EDDiscovery2.DB.ISystem ds2 = SystemData.GetSystem(s2);

            if (ds1 == null)          // warn here, quicker to complain than waiting for nodes to populate.
            {
                AppendText("Start system:  " + s1 + " unknown");
                return;
            }
            if (ds2 == null)
            {
                AppendText("Destination system:  " + s2 + " unknown");
                return;
            }

            double earea = 10.0;            // add a little to the box for first/end points allowing out of box systems
            Point3D minpos = new EMK.LightGeometry.Point3D(
                    Math.Min(ds1.x, ds2.x) - earea,
                    Math.Min(ds1.y, ds2.y) - earea,
                    Math.Min(ds1.z, ds2.z) - earea );
            Point3D maxpos = new EMK.LightGeometry.Point3D(
                    Math.Max(ds1.x, ds2.x) + earea,
                    Math.Max(ds1.y, ds2.y)+ earea,
                    Math.Max(ds1.z, ds2.z) + earea );

            AppendText("Bounding Box " + minpos.X + "," + minpos.Y + "," + minpos.Z + " to " + maxpos.X + "," + maxpos.Y + "," + maxpos.Z + Environment.NewLine);

            Stopwatch sw = new Stopwatch();

            G = new Graph();                    // need to compute each time as systems in range changes each time
            PrepareNodes(G, maxrange, mode,minpos,maxpos);

            AStar AS = new AStar(G);

            Node start, stop;

            start = G.GetNodes.FirstOrDefault(x => x.System.SearchName == s1.ToLower());
            stop = G.GetNodes.FirstOrDefault(x => x.System.SearchName == s2.ToLower());

            bool res;

            sw = new Stopwatch();

            sw.Start();
            res = AS.SearchPath(start, stop);
            sw.Stop();

            AppendText("Searching route from " + ds1.name + " to " + ds2.name + Environment.NewLine);
            AppendText("Find route Time: " + sw.Elapsed.TotalSeconds.ToString("0.000s") + Environment.NewLine);
            AppendText("Total distance: " + SystemData.Distance(s1, s2).ToString("0.00") + Environment.NewLine);
            AppendText("Max jumprange:" + maxrange + Environment.NewLine);

            if (res)
            {
                AppendText(Environment.NewLine + "Depart " + ds1.name + Environment.NewLine);

                double totdist = 0;
                int jumps = 0;

                foreach (Arc A in AS.PathByArcs)
                {
                    double dist = SystemData.Distance(A.StartNode.System.name, A.EndNode.System.name);
                    AppendText(string.Format("{0,-30}Dist: {1:0.00} ly" + Environment.NewLine, A.EndNode.System.name, dist));

                    totdist += dist;
                    jumps++;

                    Console.WriteLine(A.ToString());
                }

                AppendText(Environment.NewLine + "Total distance: " + totdist.ToString("0.00") + Environment.NewLine);
                AppendText("Jumps: " + jumps + Environment.NewLine);

                // JArray ja = Path2JSON(AS);
            }
            else
                AppendText(Environment.NewLine + "NO Solution found - jump distance is too small or not enough star data between systems" + Environment.NewLine);
        }
예제 #9
0
        private void PrepareNodes(Graph G, float maxrange, int mode, Point3D minpos , Point3D maxpos)
        {
            List<SystemClass> systems = SystemData.SystemList;
            float distance, maxrangex2 = maxrange * maxrange;
            Node N1,N2;
            float weight = 1;
            float dx, dy, dz;

            Stopwatch sw = new Stopwatch();

            sw.Start();

            SystemClass system;

            for (int ii = 0; ii < systems.Count; ii++)
            {
                system = systems[ii];
                                                    // screening out stars reduces number and makes the arc calculator much quicker.
                if (system.x >= minpos.X && system.x <= maxpos.X &&
                    system.y >= minpos.Y && system.y <= maxpos.Y &&
                    system.z >= minpos.Z && system.z <= maxpos.Z )
                {
                    N1 = new Node(system.x, system.y, system.z, system);
                    G.AddNodeWithNoChk(N1);
                }
            }

            sw.Stop();

            AppendText("Add stars: " + sw.Elapsed.TotalSeconds.ToString("0.000s") + Environment.NewLine);
            AppendText("No stars within bounds " + G.Count + Environment.NewLine);

            sw.Restart();
            for (int ii = 0; ii < G.Count; ii++)
            {
                N1 = G.GetN(ii);

                for (int jj = ii; jj < G.Count; jj++)
                {
                    N2 = G.GetN(jj);

                    dx = (float)(N1.X - N2.X);
                    dy = (float)(N1.Y - N2.Y);
                    dz = (float)(N1.Z - N2.Z);
                    distance = dx * dx + dy * dy + dz * dz;

                    if (distance > 0 && distance <= maxrangex2)
                    {
                        if (mode == 1)
                            weight = (float)(1 / distance);

                        G.AddArcWithNoChk(N1, N2, weight);
                        G.AddArcWithNoChk(N2, N1, weight);
                    }
                }
            }

            sw.Stop();
            //Console.WriteLine("Create arcs: {0}", sw.Elapsed);
            AppendText("Create arcs: " + sw.Elapsed.TotalSeconds.ToString("0.000s") + Environment.NewLine);
        }