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 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 Header() { var mem = new MemoryStream(); var writer = new BinaryNodeSerializer(); var d = Puzzle.Builder.DefaultTestPuzzle(); using (var sw = new BinaryWriter(mem, Encoding.Unicode, true)) { writer.WriteHeader(sw, d.Size, 1234); } mem.Seek(0, SeekOrigin.Begin); using (var sr = new BinaryReader(mem)) { var x = writer.ReadHeader(sr); Assert.Equal(d.Size, x.Size); Assert.Equal(1234, x.Count); } }
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 SingleNode() { var d = Puzzle.Builder.DefaultTestPuzzle(); var n = new SolverNode(null, d.Player.Position, VectorInt2.Left, d.ToMap(d.Definition.AllCrates), d.ToMap(d.Definition.AllFloors)); var mem = new MemoryStream(); var writer = new BinaryNodeSerializer(); using (var sw = new BinaryWriter(mem, Encoding.Unicode, true)) { writer.Write(sw, n); } mem.Seek(0, SeekOrigin.Begin); using (var sr = new BinaryReader(mem)) { var temp = writer.Read(sr); Assert.Equal(n.SolverNodeId, temp.SolverNodeId); Assert.Equal(0, temp.ParentId); Assert.Equal(n.PlayerBefore.X, temp.PlayerBeforeX); Assert.Equal(n.PlayerBefore.Y, temp.PlayerBeforeY); Assert.Equal(n.Push.X, temp.PushX); Assert.Equal(n.Push.Y, temp.PushY); Assert.Equal(n.Status, (SolverNodeStatus)temp.Status); var c = n.CrateMap is BitmapByteSeq bs ? bs : new BitmapByteSeq(n.CrateMap); Assert.Equal(c.GetArray(), temp.Crate); var m = n.MoveMap is BitmapByteSeq ms ? ms : new BitmapByteSeq(n.MoveMap); Assert.Equal(m.GetArray(), temp.Move); } }
public List <SolverResultSummary> Run( SolverRun run, SolverCommand baseCommand, ISolver solver, bool showSummary, BatchSolveComponent.BatchArgs?batchArgs = null) { if (run == null) { throw new ArgumentNullException(nameof(run)); } if (baseCommand == null) { throw new ArgumentNullException(nameof(baseCommand)); } if (solver == null) { throw new ArgumentNullException(nameof(solver), "See: " + nameof(SingleThreadedForwardSolver)); } Report.WriteLine("Puzzle Exit Conditions: {0}", run.PuzzleExit); Report.WriteLine("Batch Exit Conditions : {0}", run.BatchExit); Report.WriteLine("Environment : {0}", DevHelper.RuntimeEnvReport()); Report.WriteLine("Solver Environment : v{0} -- {1}", SolverHelper.VersionUniversal, SolverHelper.VersionUniversalText); Report.WriteLine("Started : {0}", DateTime.Now.ToString("u")); Report.WriteLine(); var res = new List <SolverResultSummary>(); var start = new SolverStatistics { Started = DateTime.Now }; SolverState?state = null; var pp = 0; var consecutiveFails = 0; foreach (var puzzle in run) { if (baseCommand.CheckAbort(baseCommand)) { Progress.WriteLine("EXITING..."); break; } try { pp++; Progress.WriteLine($"(Puzzle {pp}/{run.Count}) Attempting: {puzzle.Ident} \"{puzzle.Name}\", R={StaticAnalysis.CalculateRating(puzzle.Puzzle)}. Stopping on [{baseCommand.ExitConditions}] ..."); Report.WriteLine(" Name: {0}", puzzle); Report.WriteLine(" Ident: {0}", puzzle.Ident); Report.WriteLine(" Rating: {0}", StaticAnalysis.CalculateRating(puzzle.Puzzle)); Report.WriteLine(puzzle.Puzzle.ToString()); // Adds 2x line feeds IReadOnlyCollection <SolutionDTO> existingSolutions = null; if (SkipPuzzlesWithSolutions && Repository != null) { existingSolutions = Repository.GetPuzzleSolutions(puzzle.Ident); if (existingSolutions != null && existingSolutions.Any( x => x.MachineName == Environment.MachineName && x.SolverType == solver.GetType().Name)) { Progress.WriteLine("Skipping... (SkipPuzzlesWithSolutions)"); continue; } } // #### Main Block Start -------------------------------------- var memStart = GC.GetTotalMemory(false); var attemptTimer = new Stopwatch(); attemptTimer.Start(); state = solver.Init(new SolverCommand(baseCommand) { Report = Report, Puzzle = puzzle.Puzzle }); var propsReport = GetPropReport(solver, state); Tracking?.Begin(state); try { solver.Solve(state); } catch (Exception e) { state.Exception = e; state.Exit = ExitConditions.Conditions.Error; state.EarlyExit = true; } var memEnd = GC.GetTotalMemory(false); state.Statistics.MemUsed = memEnd; var memDelta = memEnd - memStart; var bytesPerNode = memDelta / state.Statistics.TotalNodes; var maxNodes = (ulong)0; if (DevHelper.TryGetTotalMemory(out var totalMem)) { maxNodes = totalMem / (ulong)bytesPerNode; } Report.WriteLine($"Memory Used: {Humanise.SizeSuffix(memEnd)}, delta: {Humanise.SizeSuffix(memDelta)} ~ {bytesPerNode:#,##0} bytes/node => max nodes:{maxNodes:#,##0}"); attemptTimer.Stop(); // #### Main Block End ------------------------------------------ state.Summary = new SolverResultSummary( puzzle, state.Solutions, state.Exit, SolverHelper.GenerateSummary(state), attemptTimer.Elapsed, state.Statistics ); res.Add(state.Summary); start.TotalNodes += state.Statistics.TotalNodes; start.TotalDead += state.Statistics.TotalDead; Report.WriteLine("[DONE] {0}", state.Summary.Text); Progress.WriteLine($" -> {state.Summary.Text}"); if (batchArgs != null && batchArgs.Save != null) { Console.WriteLine(" -> Saving..."); var binSer = new BinaryNodeSerializer(); var rootForward = state.GetRootForward(); if (rootForward != null) { var outState = System.IO.Path.Combine(batchArgs.Save, $"{puzzle.Ident}-forward.ssbn"); using (var f = File.Create(outState)) { using (var bw = new BinaryWriter(f)) { binSer.WriteTree(bw, rootForward); } } Report.WriteLine($"\tSaving State: {outState}"); Progress.WriteLine($"\tSaving State: {outState}"); } var rootReverse = state.GetRootReverse(); if (rootReverse != null) { var outState = System.IO.Path.Combine(batchArgs.Save, $"{puzzle.Ident}-reverse.ssbn"); using (var f = File.Create(outState)) { using (var bw = new BinaryWriter(f)) { binSer.WriteTree(bw, rootReverse); } } Report.WriteLine($"\tSaving State: {outState}"); Progress.WriteLine($"\tSaving State: {outState}"); } } // Add Depth Reporting Console.WriteLine(" -> Generating Reports..."); GenerateReports(state, solver); if (Repository != null) { var id = StoreAttempt(solver, puzzle, state, propsReport.ToString()); if (id >= 0) { var solTxt = $"Checking against known solutions. SolutionId={id}"; Report.WriteLine(solTxt); Console.WriteLine(solTxt); } } else { Report.WriteLine($"Solution Repository not available: Skipping."); } if (state?.Summary?.Solutions != null && state.Summary.Solutions.Any()) // May have been removed above { consecutiveFails = 0; } else { consecutiveFails++; if (StopOnConsecutiveFails != 0 && consecutiveFails > StopOnConsecutiveFails) { Progress.WriteLine("ABORTING... StopOnConsecutiveFails"); break; } } Tracking?.End(state); if (state.Exception != null) { Report.WriteLine("[EXCEPTION]"); WriteException(Report, state.Exception); } if (state.Exit == ExitConditions.Conditions.Aborted) { Progress.WriteLine("ABORTING..."); if (showSummary) { WriteSummary(res, start); } return(res); } if (start.DurationInSec > run.BatchExit.Duration.TotalSeconds) { Progress.WriteLine("BATCH TIMEOUT..."); if (showSummary) { WriteSummary(res, start); } return(res); } Progress.WriteLine(); } catch (Exception ex) { if (state != null) { state.Exception = ex; } Progress.WriteLine("ERROR: " + ex.Message); WriteException(Report, ex); } finally { state = null; if (puzzle != run.Last()) { GC.Collect(); } } } if (showSummary) { WriteSummary(res, start); } Report.WriteLine("Completed : {0}", DateTime.Now.ToString("u")); return(res); }
public static void Run(string file, string report) { System.Console.WriteLine($"<file> {file} --report {report}"); var ser = new BinaryNodeSerializer(); if (report == "depth") { using (var f = System.IO.File.OpenRead(file)) { using (var br = new BinaryReader(f)) { System.Console.WriteLine($"Reading File..."); var root = ser.AssembleTree(br); var repDepth = MapToReporting.Create <SolverHelper.DepthLineItem>() .AddColumn("Depth", x => x.Depth) .AddColumn("Total", x => x.Total) .AddColumn("Growth Rate", x => x.GrowthRate) .AddColumn("UnEval", x => x.UnEval) .AddColumn("Complete", x => (x.Total - x.UnEval) * 100 / x.Total, c => c.ColumnInfo.AsPercentage()); repDepth.RenderTo(SolverHelper.ReportDepth(root), new MapToReportingRendererText(), System.Console.Out); } } } else if (report == "clash") { using (var f = File.OpenRead(file)) { var writer = new BinaryNodeSerializer(); var nodes = writer.ReadAll(new BinaryReader(f)); Dictionary <int, ClashLineItem> hash = new Dictionary <int, ClashLineItem>(); foreach (var n in nodes) { if (hash.TryGetValue(n.HashCode, out var c)) { c.Count++; if (c.First.CrateMap.Equals(n.CrateMap) && c.First.MoveMap.Equals(n.MoveMap)) { c.Dups++; } } else { hash[n.HashCode] = new ClashLineItem() { Hash = n.HashCode, Count = 1, First = n }; } } var items = hash.Where(x => x.Value.Count > 1).OrderByDescending(x => x.Value.Dups).ThenByDescending(x => x.Value.Count).Take(50).Select(x => x.Value); MapToReporting.Create <ClashLineItem>() .AddColumn("Hash", x => x.Hash) .AddColumn("Count", x => x.Count) .AddColumn("Dups", x => x.Dups) .RenderTo(items, new MapToReportingRendererText(), System.Console.Out); System.Console.WriteLine($"Total Dups: {hash.Values.Sum(x=>x.Dups)}"); } } else if (report == "dump") { using (var f = File.OpenRead(file)) { var writer = new BinaryNodeSerializer(); using (var br = new BinaryReader(f)) { foreach (var node in writer.ReadAll(br).OrderBy(x => x.SolverNodeId).Take(20)) { System.Console.WriteLine(node); } } } } else { throw new Exception($"Unknown Report: {report}"); } }