예제 #1
0
        public virtual IEnumerable<MoveToAction> Search( Problem problem )
        {
            List<Node> frontier = new List<Node>();
            HashSet<Node> explored = new HashSet<Node>();

            Node root = new Node( problem.InitialState );
            frontier.Add( root );
            while( frontier.Count > 0 ) {
                Node nodeToExpand = frontier.First();
                frontier.Remove( nodeToExpand );

                //Console.WriteLine( nodeToExpand.State );

                var newNodes = ExpandNode(
                    nodeToExpand,
                    explored,
                    problem
                );

                foreach( Node fn in newNodes ) {
                    var test = fn.Equals( newNodes.First() );
                    if( IsGoalState( fn.State, problem.GoalTest ) ) {

                        return ActionsFromNodes( fn.GetPathFromRoot() );
                    }

                    frontier.Add( fn );
                }

                // This could be costly.  Find better alternative later
                frontier = frontier
                    .OrderByDescending( n => n.PathCost + n.EstimateCost )
                    .Distinct()
                    .ToList();
            }

            return new List<MoveToAction>();
        }
예제 #2
0
        private IEnumerable<Node> ExpandNode( 
			Node node, 
			HashSet<Node> explored, 
			Problem problem 
		)
        {
            explored.Add( node );

            var childNodes = new List<Node>();
            var actionsFunction = problem.ActionsFunction;
            var resultFunction = problem.ResultFunction;
            var stepCostFunction = problem.StepCostFunction;

            foreach( var action in actionsFunction.GetActions( node.State ) ) {
                string successorState = resultFunction.Result(
                    node.State,
                    action
                );

                int stepCost = stepCostFunction.Cost(
                    node.State,
                    action,
                    successorState
                );
                int estimateCost = m_heuristic.Calculate( successorState );
                var child = new Node(
                    successorState,
                    node,
                    action,
                    stepCost,
                    estimateCost
                );
                if( !explored.Contains( child ) ) {
                    childNodes.Add( child );
                }
            }

            return childNodes;
        }
예제 #3
0
 public AStarSearch( Problem problem, IHeuristicFunction heuristic )
 {
     this.m_problem = problem;
     this.m_heuristic = heuristic;
 }
예제 #4
0
        public static int Main( string[] args )
        {
            if( args.Length != 1 ) {
                ShowParams();
                Console.WriteLine( "Press any key to exit." );
                System.Console.ReadKey();
                return -1;
            }
            var path = args[0];
            if( !File.Exists( path ) ) {
                ShowParams();
                ShowFileSetup();
                Console.WriteLine( "Press any key to exit." );
                System.Console.ReadKey();
                return -2;
            }
            execWatch = Stopwatch.StartNew();
            Console.WriteLine( "building map..." );

            string[] lines = File.ReadAllLines( path );
            if( lines.Length < 6 ) {
                ShowFileSetup();
                return -3;
            }
            // first line has the x and then y size
            SetRoomDimensions( lines[0] );

            SetRobots( lines );

            // 2 + Robots.Count lines appear before the rendevous point
            SetRendevousPoint( lines[2 + Robots.Count] );

            // where the floor plan starts in the text file
            int depth = 3 + Robots.Count();

            for( int j = DimY - 1; j >= 0; j-- ) {
                char[] line = lines[depth].ToCharArray();

                for( int i = 0; i < DimX; i++ ) {
                    int pointValue = ( int )Char.GetNumericValue( line[i] );

                    if( pointValue == 1 ) {
                        continue;
                    }

                    var label = i + "," + j;
                    ProblemMap.AddVertex( label, i, j );

                    AddLinks( i, j, label );
                }
                depth++;
            }

            Console.WriteLine( "Finished building." );

            var fileNameStore = new ConcurrentBag<string>();
            Parallel.ForEach( Robots, Robot => {

                var start = string.Format(
                    "{0},{1}",
                    Robot.XCoord,
                    Robot.YCoord
                );
                Problem problem = new Problem(
                    start,
                    new ActionsFunction( ProblemMap ),
                    new ResultFunction(),
                    new GoalTest( Rendezvous ),
                    new SimpleStepCostFunction()
                );

                IHeuristicFunction hf =
                    new DirectPathHeuristicFunction( Rendezvous );
                ISearch search = new AStarSearch( problem, hf );

                stopWatch = Stopwatch.StartNew();
                var fileName = string.Format(
                    "robot-Guid.-{0}.txt",
                    Guid.NewGuid()
                );
                fileNameStore.Add( fileName );
                File.WriteAllText(
                    fileName,
                    string.Format(
                        "Robot starting at x: {0} and y: {1} ...\n",
                        Robot.XCoord,
                        Robot.YCoord
                    )
                );
                Console.WriteLine( string.Format(
                        "Robot starting at x: {0} and y: {1} ...\n",
                        Robot.XCoord,
                        Robot.YCoord
                    ) );
                File.AppendAllText(
                    fileName,
                    string.Format(
                        "Solution path for robot starting at ({0},{1}):\n",
                        Robot.XCoord,
                        Robot.YCoord
                    )
                );
                Console.WriteLine( string.Format(
                        "Solution path for robot starting at ({0},{1}):\n",
                        Robot.XCoord,
                        Robot.YCoord
                    ) );
                if( Robot.Equals( Rendezvous ) ) {
                    File.AppendAllText(
                        fileName,
                        "This robot is starting at the goal state."
                    );
                } else {

                    var results = search.Search( problem );

                    if( results.Any() ) {
                        File.AppendAllText(
                            fileName,
                            string.Format(
                                "({0},{1}) -> ({2})\n",
                                Robot.XCoord,
                                Robot.YCoord,
                                string.Join(
                                    ") -> (",
                                    results.Select(
                                        m => m.TargetLocation
                                    )
                                )
                            )
                        );
                        Console.WriteLine( "finished for robot starting at: " + Robot.XCoord + ", " + Robot.YCoord );
                    } else {
                        File.AppendAllText(
                            fileName,
                            "A path could not be found for this robot. " +
                            "It must be trapped!"
                        );
                    }
                }

                stopWatch.Stop();
                // Get the elapsed time as a TimeSpan value.
                TimeSpan ts = stopWatch.Elapsed;

                // Format and display the TimeSpan value.
                string elapsedTime = string.Format(
                    "{0:00}:{1:00}:{2:00}.{3:00}",
                    ts.Hours,
                    ts.Minutes,
                    ts.Seconds,
                    ts.Milliseconds
                );
                File.AppendAllText(
                    fileName,
                    string.Format( "RunTime: {0}\n", elapsedTime )
                );

            } );

            MergeAndDeleteFiles( fileNameStore );

            execWatch.Stop();
            // Get the elapsed time as a TimeSpan value.
            TimeSpan t = execWatch.Elapsed;

            // Format and display the TimeSpan value.
            string elapsed = string.Format(
                "{0:00}:{1:00}:{2:00}.{3:00}",
                t.Hours,
                t.Minutes,
                t.Seconds,
                t.Milliseconds
            );
            Console.WriteLine(
                string.Format( "Total runtime: {0}", elapsed )
            );
            #if DEBUG
            Console.WriteLine( "Press any key to exit." );
            System.Console.ReadKey();
            #endif

            return 0;
        }