public void Update(ISolver caller, SolverCommandResult state, SolverStatistics global) { if (global != null) { var d = global.DurationInSec; Console.WriteLine("\t{0:#,###,##0} nodes at {1:0.0} nodes/sec after {2:#} sec. Depth: {3}/{4}/{5} (Completed/Curr/Max)", global.TotalNodes, global.TotalNodes / d, d, global.DepthCompleted, global.DepthCurrent, global.DepthMax); } }
public Conditions ShouldExit(SolverCommandResult res) { if (StopOnSolution && res.HasSolution) return Conditions.Solution; if (res.Statistics != null) { if (res.Statistics.TotalNodes >= TotalNodes) return Conditions.TotalNodes; if (DateTime.Now - res.Statistics.Started >= Duration) return Conditions.Time; // TODO: This is unnessesarily slow } return Conditions.Continue; }
private bool CheckValidSolutions(SolverCommandResult state, SolverNode posibleSolution) { var b = state.StaticMaps.WallMap.BitwiseOR(state.StaticMaps.CrateStart); var f = state.Command.Puzzle.Player.Position; var path = posibleSolution.PathToRoot(); path.Reverse(); var start = path[0]; var t = start.PlayerAfter; var first = PathFinder.Find(b, f, t); return first != null; }
public bool Evaluate(SolverCommandResult state, ISolverQueue queue, ISolverNodeLookup myPool, ISolverNodeLookup solutionPool, SolverNode node) { if (node.HasChildren) throw new InvalidOperationException(); node.Status = SolverNodeStatus.Evaluting; var solution = false; var toEnqueue = new List<SolverNode>(); foreach (var move in node.MoveMap.TruePositions()) { foreach (var dir in VectorInt2.Directions) { var p = move; var pc = p + dir; var pp = p - dir; if (node.CrateMap[pc]) // crate to push { if (state.StaticMaps.FloorMap[pp] && !node.CrateMap[p]) { if (!CheckDeadReverse(state, pp)) { var newKid = new SolverNode { PlayerBefore = p, PlayerAfter = pp, CrateBefore = pc, CrateAfter = p, CrateMap = new Bitmap(node.CrateMap), Evaluator = this, }; newKid.CrateMap[pc] = false; newKid.CrateMap[p] = true; var boundry = state.StaticMaps.WallMap.BitwiseOR(newKid.CrateMap); newKid.MoveMap = FloodFill.Fill(boundry, pp); newKid.Goals = newKid.CrateMap.BitwiseAND(state.StaticMaps.GoalMap).Count(); // Optimisation: PreCalc hash newKid.EnsureHash(); // Cycle Check: Does this node exist already? var dup = myPool.FindMatch(newKid); if (dup != null) { // NOTE: newKid is NOT added as a ChildNode (which means less memory usage) // Duplicate newKid.Status = SolverNodeStatus.Duplicate; state.Statistics.Duplicates++; if (IsDebugMode) { node.AddDuplicate(dup); } } else { SolverNode match = null; if (solutionPool != null) match = solutionPool.FindMatch(newKid); if (match != null) { // Add to tree / itterator node.Add(newKid); // Solution if (state.SolutionsWithReverse == null) state.SolutionsWithReverse = new List<SolutionChain>(); var pair = new SolutionChain() { ForwardNode = match, ReverseNode = newKid, FoundUsing = this }; state.SolutionsWithReverse.Add(pair); solution = true; state.Command.Debug.Raise(this, SolverDebug.Solution, pair); foreach (var n in newKid.PathToRoot().Union(match.PathToRoot())) { n.Status = SolverNodeStatus.SolutionPath; } newKid.Status = SolverNodeStatus.Solution; match.Status = SolverNodeStatus.Solution; if (state.Command.ExitConditions.StopOnSolution) { return true; } } else { // Add to tree / itterator node.Add(newKid); if (DeadMapAnalysis.DynamicCheck(state.StaticMaps, node)) { newKid.Status = SolverNodeStatus.Dead; } else { toEnqueue.Add(newKid); if (newKid.CrateMap.BitwiseAND(state.StaticMaps.CrateStart).Equals(newKid.CrateMap)) { // Possible Solution: Did we start in a valid position if (CheckValidSolutions(state, newKid)) { state.Solutions.Add(newKid); state.Command.Debug.Raise(this, SolverDebug.Solution, newKid); solution = true; foreach (var n in newKid.PathToRoot()) { n.Status = SolverNodeStatus.SolutionPath; } newKid.Status = SolverNodeStatus.Solution; } else { newKid.Status = SolverNodeStatus.InvalidSolution; } } } } } } } } } } node.Status = node.HasChildren ? SolverNodeStatus.Evaluted : SolverNodeStatus.Dead; if (node.Status == SolverNodeStatus.Dead && node.Parent != null) { var p = (SolverNode)node.Parent; p.CheckDead(); } queue.Enqueue(toEnqueue); myPool.Add(toEnqueue); return solution; }
private bool CheckDeadReverse(SolverCommandResult state, VectorInt2 ppp) { return false; return state.StaticMaps.DeadMap[ppp]; }
public void Solve(SolverCommandResult state) { Solver((CommandResult) state); }
protected virtual bool Tick(SolverCommand command, CommandResult state, ISolverQueue queue, out SolverCommandResult solve) { state.Statistics.DepthCompleted = queue.Statistics.DepthCompleted; state.Statistics.DepthMax = queue.Statistics.DepthMax; if (command.Progress != null) { command.Progress.Update(this, state, state.Statistics); } if (command.CheckAbort != null) { if (command.CheckAbort(command)) { state.Exit = ExitConditions.Conditions.Aborted; state.EarlyExit = true; state.Statistics.Completed = DateTime.Now; solve = state; return true; } } var check = command.ExitConditions.ShouldExit(state); if (check != ExitConditions.Conditions.Continue) { state.EarlyExit = true; state.Statistics.Completed = DateTime.Now; state.Exit = check; solve = state; return true; } solve = null; return false; }
public void Solve(SolverCommandResult state) { Solve(state as CommandResult); }
public void Solve(SolverCommandResult state) { var full = (CommandResult)state; full.IsRunning = true; full.ProgressTask.Start(); foreach (var worker in full.Workers) { worker.Task.Start(); } var allTasks = full.Workers.Select(x => x.Task).ToArray(); Task.WaitAll(allTasks); full.IsRunning = false; foreach (var worker in full.Workers) { if (worker.WorkerCommandResult.HasSolution) { if (worker.WorkerCommandResult.Solutions != null) { if (full.Solutions == null) full.Solutions = new List<SolverNode>(); full.Solutions.AddRange(worker.WorkerCommandResult.Solutions); } if (worker.WorkerCommandResult.SolutionsWithReverse != null) { if (full.SolutionsWithReverse == null) full.SolutionsWithReverse = new List<SolutionChain>(); full.SolutionsWithReverse.AddRange(worker.WorkerCommandResult.SolutionsWithReverse); } } } state.Statistics.Completed = DateTime.Now; }