private SolverState PerformStandardTest( Puzzle puzzle, ExitConditions exit = null, Func <SolverNode, bool>?inspector = null ) { exit = exit ?? new ExitConditions { Duration = TimeSpan.FromSeconds(60), StopOnSolution = true, TotalNodes = int.MaxValue, TotalDead = int.MaxValue }; // arrange var solver = new SingleThreadedForwardReverseSolver(new SolverNodeFactoryTrivial()); var command = new SolverCommand { Puzzle = puzzle.Clone(), Report = new XUnitOutput(outp), ExitConditions = exit, Inspector = inspector }; // act var result = solver.Init(command); solver.Solve(result); Console.WriteLine(result.ExitDescription); Console.WriteLine(SolverHelper.GenerateSummary(result)); result.ThrowErrors(); // assert Assert.NotNull(result); Assert.True(result.HasSolution); Assert.NotNull(result.Solutions); Assert.NotEmpty(result.Solutions); foreach (var sol in result.Solutions) { Console.WriteLine("Path: {0}", sol); string error = null; Assert.True(SolverHelper.CheckSolution(command.Puzzle, sol, out error), "Solution is INVALID! " + error); } return(result); }
public void Assemble() { var exit = new ExitConditions { Duration = TimeSpan.FromSeconds(1), StopOnSolution = true, TotalNodes = int.MaxValue, TotalDead = int.MaxValue }; var command = new SolverCommand { Puzzle = Puzzle.Builder.DefaultTestPuzzle(), ExitConditions = exit }; // act var solver = new SingleThreadedForwardSolver(new SolverNodeFactoryTrivial()); var result = solver.Init(command); solver.Solve(result); result.ThrowErrors(); var root = ((SolverBaseState)result).Root; var allNodes = root.Recurse().ToArray(); var mem = new MemoryStream(); var writer = new BinaryNodeSerializer(); using (var sw = new BinaryWriter(mem, Encoding.Unicode, true)) { writer.Write(sw, allNodes); } outp.WriteLine($"Memory Stream Size = {allNodes.Length}nodes => {mem.Length}b"); Assert.Equal(allNodes.Length, root.CountRecursive()); mem.Seek(0, SeekOrigin.Begin); using (var sr = new BinaryReader(mem)) { var t = writer.AssembleTree(sr); Assert.True(t.RecursiveAll().Any(x => x.Status != SolverNodeStatus.UnEval)); Assert.Equal(root.CountRecursive(), t.CountRecursive()); } }
public void ForwardReverseSingle() { var solverCommand = new SolverCommand() { Puzzle = Puzzle.Builder.DefaultTestPuzzle(), ExitConditions = ExitConditions.Default3Min(), }; var solver = new SingleThreadedForwardReverseSolver(new SolverNodeFactoryTrivial()); var solverState = solver.Init(solverCommand); solver.Solve(solverState); if (!solverState.HasSolution) { throw new Exception(); } }
private void PuzzleShouldHaveSolution(ISolver solver, Puzzle puzzle, ExitConditions exit = null, bool verbose = false) { if (exit == null) { exit = new ExitConditions { Duration = TimeSpan.FromSeconds(60), StopOnSolution = true, TotalNodes = int.MaxValue, TotalDead = int.MaxValue } } ; var command = new SolverCommand { Puzzle = puzzle, Report = new XUnitOutput(outp), ExitConditions = exit }; // act var result = solver.Init(command); solver.Solve(result); Console.WriteLine(result.ExitDescription); Console.WriteLine(SolverHelper.GenerateSummary(result)); result.ThrowErrors(); // assert Assert.NotNull(result); Assert.NotNull(result.Solutions); Assert.True(result.HasSolution); foreach (var sol in result.Solutions) { string error = null; Assert.True(SolverHelper.CheckSolution(command.Puzzle, sol, out error), "Solution is INVALID! " + error); } }
public void WriteDefaultForwardSolution() { var exit = new ExitConditions { Duration = TimeSpan.FromSeconds(10), StopOnSolution = true, TotalNodes = int.MaxValue, TotalDead = int.MaxValue }; var command = new SolverCommand { Puzzle = Puzzle.Builder.DefaultTestPuzzle(), ExitConditions = exit, Inspector = (s) => { if (s.GetHashCode() == 30759) { outp.WriteLine(s.ToString()); return(true); } return(false); } }; // act var solver = new SingleThreadedForwardSolver(new SolverNodeFactoryTrivial()); var result = solver.Init(command); solver.Solve(result); result.ThrowErrors(); Assert.True(result.HasSolution); var root = ((SolverBaseState)result).Root; using (var f = File.Create(Path.Combine(TestHelper.GetDataPath(), "./SavedState/SQ1~P1-default.ssbn"))) { var writer = new BinaryNodeSerializer(); writer.WriteTree(new BinaryWriter(f), root); } }
public void Exhause() { var command = new SolverCommand { Puzzle = Puzzle.Builder.FromLines(new[] { "##########", "#O....XP.#", "#O.....X.#", "#O....X..#", "##########" }), Report = new XUnitOutput(outp), ExitConditions = new ExitConditions() { StopOnSolution = false, Duration = TimeSpan.FromHours(1) } }; var solver = new SingleThreadedForwardSolver(new SolverNodeFactoryTrivial()); var state = solver.Init(command) as SolverBaseState; var result = solver.Solve(state); // // // using (var f = File.CreateText(nameof(Exhause) + ".dot")) // { // // dot .\Exhause.dot -o file.svg -T svg // new GraphVisRender().Render(state.Root.Recurse(), f); // } // Assert.NotEmpty(state.Solutions); Assert.NotEmpty(state.Root.Children); Assert.True(state.Root.Recurse().All(x => ((SolverNode)x).IsClosed || x.Status == SolverNodeStatus.Solution || x.Status == SolverNodeStatus.SolutionPath)); Assert.Equal(ExitConditions.Conditions.ExhaustedTree, result); }
public IActionResult StartFromFile(string file) { var fileName = Path.GetFileName(file); var ident = PuzzleIdent.Parse(fileName.Substring(0, fileName.IndexOf("-"))); var p = compLib.GetPuzzleWithCaching(ident); var solver = new MultiThreadedForwardReverseSolver(new SolverNodeFactoryPoolingConcurrentBag("byteseq")); var solverCommand = new SolverCommand() { Puzzle = p.Puzzle, ExitConditions = new ExitConditions() { Duration = TimeSpan.FromMinutes(0), StopOnSolution = true } }; var model = new SolverModel() { Token = DateTime.Now.Ticks, Puzzle = p, Command = solverCommand, }; staticState[model.Token] = model; model.Task = Task.Run(() => { var ser = new BinaryNodeSerializer(); using (var f = System.IO.File.OpenRead(file)) { using (var br = new BinaryReader(f)) { model.RootForward = ser.AssembleTree(br); } } model.IsFinished = true; }); return(RedirectToAction("SolveMem", new { id = ident.ToString(), token = model.Token })); }
public void NoSolutions_InvalidPuzzle() { var command = new SolverCommand { Puzzle = Puzzle.Builder.FromLines(new[] { // More goals than crates - strictly not valid "##########", "#O...X..O#", "#O..XPX.O#", "#O..X.X.O#", "##########" }), Report = new XUnitOutput(outp), ExitConditions = ExitConditions.OneMinute() }; var solver = new SingleThreadedForwardSolver(new SolverNodeFactoryTrivial()); Assert.Throws <InvalidDataException>(() => { var state = solver.Init(command) as SolverBaseState; }); }
public IActionResult SolveStart(string id, bool stopOnSolution, double duration = 1) { var ident = PuzzleIdent.Parse(id); var p = compLib.GetPuzzleWithCaching(ident); var solver = new MultiThreadedForwardReverseSolver(new SolverNodeFactoryPoolingConcurrentBag("byteseq")); var solverCommand = new SolverCommand() { Puzzle = p.Puzzle, ExitConditions = new ExitConditions() { Duration = TimeSpan.FromMinutes(duration), StopOnSolution = true } }; var model = new SolverModel() { Token = DateTime.Now.Ticks, Puzzle = p, Command = solverCommand, State = solver.Init(solverCommand) }; staticState[model.Token] = model; model.Task = Task.Run(() => { model.RootForward = model.State.GetRootForward(); model.RootReverse = model.State.GetRootReverse(); solver.Solve(model.State); model.IsFinished = true; }); return(RedirectToAction("SolveMem", new { id, token = model.Token })); }
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 }