Ejemplo n.º 1
0
        public void Setup()
        {
            _initialState = new VacuumWorldState(2);
            _initialState.MakeSquareDirty(0, 0);
            _initialState.MakeSquareDirty(0, 1);

            _problem = new VacuumWorldSearchProblem(_initialState,
                                                    VacuumWorldActionHandler.CreateDeterministicActionHandler());
        }
Ejemplo n.º 2
0
        private static void InteractivelyDisplaySolution(
            VacuumWorldState initialState,
            IEnumerable <VacuumWorldAction> solution)
        {
            var renderer = new Renderer();
            var machine  = new VacuumWorld(initialState,
                                           VacuumWorldActionHandler.CreateDeterministicActionHandler());

            foreach (var action in solution)
            {
                renderer.Render(machine.State);
                var key = Console.ReadKey();
                if (key.Key == ConsoleKey.Escape)
                {
                    break;
                }
                machine.DoAction(action);
            }

            renderer.Render(machine.State);
        }
Ejemplo n.º 3
0
 public ErraticVacuumWorldSearchProblem()
 {
     _actionHandler = VacuumWorldActionHandler.CreateErraticWorldActionHandler();
 }
Ejemplo n.º 4
0
 public static VacuumWorld CreateErraticVacuumWorld(VacuumWorldState state)
 {
     return(new VacuumWorld(state, VacuumWorldActionHandler.CreateErraticWorldActionHandler()));
 }
Ejemplo n.º 5
0
 public static VacuumWorld CreateDeterministicVacuumWorld(VacuumWorldState state)
 {
     return(new VacuumWorld(state, VacuumWorldActionHandler.CreateDeterministicActionHandler()));
 }
Ejemplo n.º 6
0
        public static void Run(string[] args)
        {
            var size         = int.Parse(args[0]);
            var initialState = VacuumWorldGenerator.CreateWorldWithRandomlyDirtySquares(size);
            var problem      = new VacuumWorldSearchProblem(initialState,
                                                            VacuumWorldActionHandler.CreateDeterministicActionHandler());

            var solvers = new List <SearchAlgorithmWithLabel>
            {
                // BFS
                // bfs is too inefficient to solve more than ~5x5 worlds. For 5x5 world with all dirty squares, the number
                // of possible states =
                //       2    (square is dirty or clean)
                //    ^ 25    (25 squares)
                //    * 25    (25 possible vacuum locations)
                //    = 838 860 800
                new SearchAlgorithmWithLabel("BFS",
                                             new BreadthFirstSearch <VacuumWorldState, VacuumWorldAction>(problem)
                                             ),

                // Greedy best first
                // greedy best first is much more efficient, but won't find an optimal solution, ie. number of
                // moves to clean all squares may be more than the minimum possible
                new SearchAlgorithmWithLabel("Greedy best first, heuristic: number of dirty squares",
                                             new GreedyBestFirstSearch <VacuumWorldState, VacuumWorldAction>(problem, s => s.NumberOfDirtySquares())
                                             ),

                // A*
                // A* is optimal and optimally efficient, given the heuristic is admissible (always
                // underestimates) and consistent (monotonic decreasing).

                // h = number of dirty squares
                // - admissible & consistent
                // - too much of an underestimate, results in searching too many states
                new SearchAlgorithmWithLabel("A*, heuristic: number of dirty squares",
                                             new AStarSearch <VacuumWorldState, VacuumWorldAction>(problem, s => s.NumberOfDirtySquares())
                                             ),

                // h = 2 * number of dirty squares
                // - closer to the truth - need to move to each square, and clean it (2 moves per square)
                // - admissible & consistent
                // - a closer underestimate, searches fewer than the above h
                new SearchAlgorithmWithLabel("A*, heuristic: 2 x number of dirty squares",
                                             new AStarSearch <VacuumWorldState, VacuumWorldAction>(problem, s => 2 * s.NumberOfDirtySquares())
                                             ),

                // h = 5 * number of dirty squares
                // - an overestimate to improve solution time
                // - not admissible, is it consistent?
                new SearchAlgorithmWithLabel("A*, heuristic: 5 x number of dirty squares",
                                             new AStarSearch <VacuumWorldState, VacuumWorldAction>(problem, s => 5 * s.NumberOfDirtySquares())
                                             ),

                // h = 2 * number of dirty squares + number of moves to closest dirty square - 1
                // This seems like a pretty accurate guess
                // - Admissible and consistent (I think)
                // - Calculating number of moves to dirty square is inefficient
                new SearchAlgorithmWithLabel("A*, heuristic: 2 x number of dirty squares + distance to closest dirty square - 1",
                                             new AStarSearch <VacuumWorldState, VacuumWorldAction>(problem, state =>
                                                                                                   state.MinNumberOfMovesToDirtySquare() + 2 * state.NumberOfDirtySquares() - 1)
                                             ),
            };

            var numDirtySquares = initialState.NumberOfDirtySquares();

            Console.WriteLine($"Comparing search algorithms for {size}x{size} world with {numDirtySquares} dirty squares...");

            foreach (var solver in solvers)
            {
                Console.WriteLine($"Running solver: {solver.Label}");

                var stats = SolveAndRecordStats(solver.Algorithm);

                PrintStats(stats);

                Console.WriteLine($"---------");
            }
        }