public Tuple <List <object>, int> GetLongestPath(ISearchNode startState, ISearchNode goalState = null, bool verbose = false) { if (verbose) { Console.Clear(); } Stopwatch searchWatch = new Stopwatch(); searchWatch.Start(); openQueue = new SimplePriorityQueue <ISearchNode>(); closedSet = new HashSet <ISearchNode>(); openQueue.Enqueue(startState, 0); long step = 0; ISearchNode current; HashSet <ExpandAction> expandActions; ISearchNode newNode; ISearchNode match; var targetCandidates = new List <Tuple <List <object>, int> >(); while (openQueue.Count > 0) { step++; current = openQueue.Dequeue(); closedSet.Add(current); if (current.IsGoalState(goalState)) { //todo: this can probably be optimized to work more like standard A*, but negating Cost + Heuristic wasn't enough and this is probably the next best thing. Or at least it's the next thing I came up with. targetCandidates.Add(Tuple.Create(current.Actions, current.Cost)); continue; } expandActions = current.ExpandNode(); if (verbose) { OutputVerboseInfo(goalState, searchWatch, step, current); } foreach (ExpandAction expandAction in expandActions) { newNode = expandAction.Result; newNode.Cost = current.Cost + expandAction.Cost; newNode.Actions.Add(expandAction.Action); if (closedSet.Any(x => x.Equals(newNode))) { continue; } match = openQueue.SingleOrDefault(x => x.Equals(newNode)); if (match != default(ISearchNode)) { if (match.Cost < newNode.Cost) { openQueue.UpdatePriority(match, -1 * (newNode.Cost + newNode.GetHeuristic(goalState))); } } else { openQueue.Enqueue(newNode, -1 * (newNode.Cost + newNode.GetHeuristic(goalState))); } } } return(targetCandidates.OrderByDescending(c => c.Item2).First()); }
public Tuple <List <object>, int> GetOptimalPath(SearchNode startState, SearchNode goalState = null, bool verbose = false) { if (verbose) { Console.Clear(); } Stopwatch searchWatch = new Stopwatch(); searchWatch.Start(); openQueueNew = new SimplePriorityQueue <SearchNode>(); closedSetNew = new HashSet <SearchNode>(); openQueueNew.Enqueue(startState, 0); long step = 0; SearchNode current; HashSet <ExpandActionNew> expandActions; SearchNode newNode; SearchNode match; while (openQueueNew.Count > 0) { step++; current = openQueueNew.Dequeue(); if (current.IsGoalState(current)) { return(Tuple.Create(current.Actions, current.Cost)); } closedSetNew.Add(current); expandActions = current.ExpandNode(); if (verbose) { OutputVerboseInfo(goalState, searchWatch, step, current); } foreach (ExpandActionNew expandAction in expandActions) { newNode = expandAction.Result; newNode.Cost = current.Cost + expandAction.Cost; newNode.Actions.Add(expandAction.Action); if (closedSetNew.Contains(newNode)) { continue; } match = openQueueNew.SingleOrDefault(x => x.Equals(newNode)); if (match != null) { if (match.Cost > newNode.Cost) { openQueueNew.UpdatePriority(match, newNode.Cost + newNode.GetHeuristic(goalState)); } } else { openQueueNew.Enqueue(newNode, newNode.Cost + newNode.GetHeuristic(goalState)); } } } return(Tuple.Create(new List <object>(), -1)); }
// ReSharper disable once MemberCanBePrivate.Global public Tuple <List <object>, int> GetOptimalPath(ISearchNode startState, ISearchNode goalState = null, bool verbose = false, bool stepByStep = false) { if (verbose) { Console.Clear(); } Stopwatch searchWatch = new Stopwatch(); searchWatch.Start(); openQueue = new SimplePriorityQueue <ISearchNode>(); closedSet = new HashSet <ISearchNode>(); openQueue.Enqueue(startState, 0); long step = 0; ISearchNode current; HashSet <ExpandAction> expandActions; ISearchNode newNode; ISearchNode match; while (openQueue.Count > 0) { step++; current = openQueue.Dequeue(); if (current.IsGoalState(goalState)) { return(Tuple.Create(current.Actions, current.Cost)); } expandActions = current.ExpandNode(); closedSet.Add(current); if (verbose) { OutputVerboseInfo(goalState, searchWatch, step, current); if (stepByStep) { Console.ReadLine(); } } foreach (ExpandAction expandAction in expandActions) { newNode = expandAction.Result; newNode.Cost = current.Cost + expandAction.Cost; newNode.Actions.Add(expandAction.Action); if (closedSet.Any(x => x.Equals(newNode))) { continue; } match = openQueue.SingleOrDefault(x => x.Equals(newNode)); if (match != default(ISearchNode)) { if (match.Cost > newNode.Cost) { openQueue.UpdatePriority(match, newNode.Cost + newNode.GetHeuristic(goalState)); } } else { openQueue.Enqueue(newNode, newNode.Cost + newNode.GetHeuristic(goalState)); } } OnSearchNodeProcessed(new SearchEventArgs { ClosedSet = closedSet, OpenQueue = openQueue, CurrentNode = current }); } return(Tuple.Create(new List <object>(), -1)); }