Example #1
0
        public static void Run(
            string puzzle = "SQ1~P5", int min  = 0, int sec = 0,
            string solver = "fr!", string pool = PoolDefault,
            double minR   = 0, double maxR     = 2000)
        {
            if (min == 0 && sec == 0)
            {
                min = 3;
            }

            var pathHelper = new PathHelper();
            var compLib    = new LibraryComponent(pathHelper.GetRelDataPath("Lib"));

            var selection = compLib.GetPuzzlesWithCachingUsingRegex(puzzle).ToArray();

            if (!selection.Any())
            {
                throw new Exception($"Not puzzles found '{puzzle}', should be SQ1~P5 or SQ1, etc");
            }

            var solverRun = new SolverRun();

            solverRun.Init();
            solverRun.AddRange(
                selection
                .OrderBy(x => x.Rating)
                .Where(x => x.Rating >= minR && x.Rating <= maxR)
                );

            SolverRun(puzzle, min, sec, solver, pool, minR, maxR, solverRun);
        }
Example #2
0
        public void Run(
            string puzzle = "SQ1~P13", int min = 0, int sec = 0,
            string solver = "fr!", string pool = BatchSolveComponent.PoolDefault,
            double minR   = 0, double maxR     = 2000, string save = null)
        {
            if (min == 0 && sec == 0)
            {
                min = 3;
            }

            var pathHelper = new PathHelper();
            var compLib    = new LibraryComponent(pathHelper.GetRelDataPath("Lib"));

            var selection = compLib.GetPuzzlesWithCachingUsingRegex(puzzle).ToArray();

            if (!selection.Any())
            {
                throw new Exception($"Not puzzles found '{puzzle}', should be SQ1~P5 or SQ1, etc");
            }

            var solverRun = new SolverRun();

            solverRun.Init();
            solverRun.AddRange(
                selection
                .OrderBy(x => x.Rating)
                .Where(x => x.Rating >= minR && x.Rating <= maxR)
                );

            var batch = new BatchSolveComponent();

            batch.SolverRun(new BatchSolveComponent.BatchArgs(puzzle, min, sec, solver, pool, minR, maxR, save)
            {
                Console = new TextWriterAdapter(System.Console.Out)
            }, solverRun);
        }
Example #3
0
 public void CanLoadAll()
 {
     var res = new SolverRun();
     res.Load("SolverRun-Default.tff");
 }
        public List<Result> Run(SolverRun run, SolverCommand baseCommand, ISolver solver = null)
        {
            if (solver == null)
            {
                solver = new SingleThreadedForwardSolver();
            }

            Report.WriteLine("Puzzle Exit Conditions: {0}", run.PuzzleExit);
            Report.WriteLine("Batch Exit Conditions : {0}", run.BatchExit);
            Report.WriteLine("Solver                : {0}", SolverHelper.Describe(solver));
            Report.WriteLine("CPU                   : {0}", DebugHelper.GetCPUDescription());
            Report.WriteLine("Machine               : {0} {1}", Environment.MachineName, Environment.Is64BitProcess ? "x64" : "x32");

            Report.WriteLine();

            var res = new List<Result>();
            var start = new SolverStatistics()
            {
                Started = DateTime.Now
            };
            SolverCommandResult result = null;
            int pp = 0;
            int consecutiveFails = 0;
            foreach (var puzzle in run)
            {
                if (baseCommand.CheckAbort(baseCommand))
                {
                    Progress.WriteLine("EXITING...");
                    break;
                }
                try
                {
                    pp++;
                    Progress.WriteLine("Attempting: {0} ({2}/{3}); Rating: {1}", PuzzleHelper.GetName(puzzle), StaticAnalysis.CalculateRating(puzzle), pp, run.Count);

                    var libPuzzle = puzzle as LibraryPuzzle;
                    Report.WriteLine("           Name: {0}", PuzzleHelper.GetName(puzzle));
                    Report.WriteLine("          Ident: {0}", libPuzzle != null ? libPuzzle.Ident : null);
                    Report.WriteLine("         Rating: {0}", StaticAnalysis.CalculateRating(puzzle));
                    Report.WriteLine("Starting Memory: {0}", Environment.WorkingSet);
                    Report.WriteLine(puzzle.ToString());

                    PuzzleDTO dto = null;
                    if (Repository != null)
                    {
                        dto = Repository.Get(puzzle);
                        if (dto == null)
                        {
                            dto = Repository.ToDTO(puzzle);
                            Repository.Store(dto);
                        }
                        dto.Solutions = Repository.GetSolutions(dto.PuzzleId);
                    }

                    if (SkipPuzzlesWithSolutions)
                    {
                        if (dto != null &&
                            dto.Solutions.Exists(x=>x.HostMachine == Environment.MachineName && x.SolverType == solver.GetType().Name))
                        {
                            Progress.WriteLine("Skipping... (SkipPuzzlesWithSolutions)");
                            continue;
                        }
                    }

                    Report.WriteLine();

                    result = solver.Init(new SolverCommand(baseCommand)
                    {
                        Report = Report,
                        ExitConditions = run.PuzzleExit,
                        Puzzle = puzzle,

                    });
                    if (Tracking != null) Tracking.Begin(result);

                    solver.Solve(result);
                    var r = new Result()
                    {
                        Summary = SolverHelper.Summary(result),
                        Exited = result.Exit,
                        Solutions = result.GetSolutions()
                    };
                    res.Add(r);

                    start.TotalNodes += result.Statistics.TotalNodes;
                    start.TotalDead += result.Statistics.TotalDead;

                    if (r.Solutions.Any())
                    {
                        int cc = 0;
                        foreach (var p in r.Solutions.ToArray())
                        {
                            string error = null;
                            var check = SolverHelper.CheckSolution(puzzle, p, out error);
                            Report.WriteLine("Solution #{0} [{1}] =>\n{2}", cc++, check ? "Valid":"INVALID!"+error, p);
                            if (!check)
                            {
                                r.Solutions.Remove(p);
                                r.Summary += " (INVALID SOLUTION)";
                            }
                        }
                        // Write to DB?
                        if (dto != null)
                        {
                            if (Repository != null)
                            {
                                StoreSolution(solver, dto, r.Solutions);
                            }
                        }
                    }

                    if (r.Solutions.Any()) // May have been removed above
                    {
                        consecutiveFails = 0;
                    }
                    else
                    {
                        consecutiveFails++;
                        if (StopOnConsecutiveFails != 0 && consecutiveFails > StopOnConsecutiveFails)
                        {
                            Progress.WriteLine("ABORTING... StopOnConsecutiveFails");
                            break;
                        }
                    }

                    var finalStats = solver.Statistics;
                    if (finalStats != null)
                    {
                        foreach (var fs in finalStats)
                        {
                            Report.WriteLine("Statistics | {0}", fs);
                        }
                    }

                    if (Tracking != null) Tracking.End(result);

                    Report.WriteLine("[DONE] {0}", r.Summary);
                    if (result.Exception != null)
                    {
                        Report.WriteLine("[EXCEPTION]");
                        WriteException(Report, result.Exception);
                    }

                    Progress.WriteLine();
                    Progress.WriteLine("Completed: {0} ==> {1}", PuzzleHelper.GetName(puzzle), r.Summary);
                    Progress.WriteLine();

                    if (result.Exit == ExitConditions.Conditions.Aborted)
                    {
                        Progress.WriteLine("ABORTING...");
                        WriteSummary(res, start);
                        return res;
                    }

                    if (start.DurationInSec > run.BatchExit.Duration.TotalSeconds)
                    {
                        Progress.WriteLine("BATCH TIMEOUT...");
                        WriteSummary(res, start);
                        return res;
                    }

                    Progress.WriteLine();
                }
                catch (Exception ex)
                {
                    if (result != null) result.Exception = ex;
                    Progress.WriteLine("ERROR: "+ex.Message);
                    WriteException(Report, ex);
                }
                finally
                {
                    result = null;
                    Report.WriteLine("Ending Memory: {0}", Environment.WorkingSet);
                    GC.Collect();
                    Report.WriteLine("Post-GC Memory: {0}", Environment.WorkingSet);
                    Report.WriteLine("===================================");
                    Report.WriteLine();
                }

                Report.Flush();
            }
            WriteSummary(res, start);
            return res;
        }
Example #5
0
        public static int SolverRun(string puzzle,
                                    int min, int sec,
                                    string solver, string pool,
                                    double minR, double maxR,
                                    SolverRun solverRun)
        {
            var args =
                new FluentString(" ")
                .Append(puzzle).Sep()
                .Append($"--solver {solver}").Sep()
                .Append($"--pool {pool}").Sep()
                .If(min > 0, $"--min {min}").Sep()
                .If(sec > 0, $"--sec {sec}").Sep()
                .If(minR > 0, $"--min-rating {minR}").Sep()
                .If(maxR < 2000, $"--min-rating {maxR}");

            System.Console.WriteLine($"Arguments: {args}");

            var           exitRequested = false;
            SolverCommand?executing     = null;

            // Setup: Report and cancellation
            var benchId   = DateTime.Now.ToString("s").Replace(':', '-');
            var outFile   = $"./benchmark--{benchId}.txt";
            var outTele   = $"./telemetry--{benchId}.csv";
            var outFolder = "./results/";

            if (!Directory.Exists(outFolder))
            {
                Directory.CreateDirectory(outFolder);
            }
            var info = new FileInfo(Path.Combine(outFolder, outFile));
            var tele = new FileInfo(Path.Combine(outFolder, outTele));

            using var report  = File.CreateText(info.FullName);
            using var repTele = File.CreateText(tele.FullName);

            System.Console.CancelKeyPress += (o, e) =>
            {
                report.Flush();
                System.Console.WriteLine("Ctrl+C detected; cancel requested");

                if (executing != null)
                {
                    executing.ExitConditions.ExitRequested = true;
                }

                exitRequested = true;
            };

            ISokobanSolutionRepository?solutionRepo = File.Exists("./solutions.json") && !DevHelper.IsDebug()
                ? new JsonSokobanSolutionRepository("./solutions.json")
                : null;
            ISolverRunTracking?runTracking = null;

            var results    = new List <(Strategy, List <SolverResultSummary>)>();
            var perm       = GetPermutations(solver, pool).ToList();
            var countStrat = 0;

            foreach (var strat in perm)
            {
                countStrat++;
                System.Console.WriteLine($"(Strategy {countStrat}/{perm.Count}) {strat}");

                var ioc = new SolverContainerByType(new Dictionary <Type, Func <Type, object> >()
                {
                    { typeof(ISolverPool), _ => PoolFactory(strat.Pool) },
                    { typeof(ISolverQueue), _ => new SolverQueueConcurrent() },
                    { typeof(ISolverRunTracking), _ => runTracking },
                    { typeof(ISokobanSolutionRepository), _ => solutionRepo },
                });
                var solverCommand = new SolverCommand
                {
                    ServiceProvider = ioc,
                    ExitConditions  = new ExitConditions()
                    {
                        Duration       = TimeSpan.FromMinutes(min).Add(TimeSpan.FromSeconds(sec)),
                        MemAvail       = DevHelper.GiB_1, // Stops the machine hanging / swapping to death
                        StopOnSolution = true,
                    },
                    AggProgress = new ConsoleProgressNotifier(repTele),
                    CheckAbort  = x => exitRequested,
                };

                var runner = new BatchSolveComponent(
                    report,
                    System.Console.Out,
                    solutionRepo,
                    runTracking,
                    5,
                    false);

                var solverInstance = SolverFactory(strat.Solver, ioc);
                var summary        = runner.Run(solverRun, solverCommand, solverInstance, false);
                results.Add((strat, summary));
            }

            // Header
            var extras = new Dictionary <string, string>()
            {
                { "Args", args },
                { "Report", info.FullName }
            };

            DevHelper.WriteFullDevelopmentContext(report, extras);
            DevHelper.WriteFullDevelopmentContext(System.Console.Out, extras);

            // Body
            var reportRow = GenerateReport(results).ToList();

            MapToReporting.Create <SummaryLine>()
            .AddColumn("Solver", x => x.Strategy.Solver)
            .AddColumn("Pool", x => x.Strategy.Pool)
            .AddColumn("Puzzle", x => x.Result.Puzzle.Ident)
            .AddColumn("State", x => x.Result.Exited)
            .AddColumn("Solutions", x => (x.Result.Solutions?.Count ?? 0) == 0 ? null : (int?)x.Result.Solutions.Count)
            .AddColumn("Statistics", x =>
                       x.Result.Exited == ExitConditions.Conditions.Error
                        ? x.Result.Exited.ToString()
                        : x.Result.Statistics?.ToString(false, true)
                       )
            .RenderTo(reportRow, new MapToReportingRendererText(), report)
            .RenderTo(reportRow, new MapToReportingRendererText(), System.Console.Out);

            return(results.Any(x => x.Item2.Any(y => y.Exited == ExitConditions.Conditions.Error)) ? -1 : 0); // All exceptions
        }