private BucketPuzzleSolveOutcome Solve(BucketPuzzle problem, int limit) { var frontier = new Stack <BucketPuzzle>(); frontier.Push(problem); var explored = new List <BucketPuzzle>(); do { var candidate = frontier.Pop(); if (candidate.IsASolution) { return(BucketPuzzleSolveOutcome.Solution(candidate)); } explored.Add(candidate); var childStates = candidate.Expand(limit); foreach (var childState in childStates) { if (!explored.Any(e => e.IsSame(childState)) && !frontier.Any(f => f.IsSame(childState))) { frontier.Push(childState); } } } while (frontier.Count > 0); return(BucketPuzzleSolveOutcome.CutOff(problem)); }
public bool IsSame(BucketPuzzle that) { var thisState = this.Buckets.Select(b => (b.Id, b.Volume, b.Capacity)).OrderBy(b => b.Id).ToList(); var thatState = that.Buckets.Select(b => (b.Id, b.Volume, b.Capacity)).OrderBy(b => b.Id).ToList(); var sequenceEqual = thisState.SequenceEqual(thatState); return(sequenceEqual); }
public BucketPuzzleSolveOutcome Solve(BucketPuzzle problem) { const int depthLimit = 256; // Give up after so many iterations. for (var depth = 0; depth < depthLimit; depth++) { var outcome = this.Solve(problem, depth); if (outcome.Classification != SolutionOutcomeClassification.CutOff) { return(outcome); } } return(BucketPuzzleSolveOutcome.CutOff(problem)); }
private BucketPuzzle(IEnumerable <Bucket> buckets, bool canEmpty, bool canRefill, int targetVolume, int depth, BucketPuzzle parent, string action) { this.Buckets = buckets; this.CanEmpty = canEmpty; this.CanRefill = canRefill; this.TargetVolume = targetVolume; this.Depth = depth; this.Parent = parent; this.Action = action; }