private static IEnumerable <State> FindPath(Node[,] nodes, X_Y emptyNodePos) { var targetNodePos = new X_Y { X = nodes.GetLength(0) - 1, Y = 0 }; var maxAvail = nodes[emptyNodePos.X, emptyNodePos.Y].Available; var initState = new GraphNode { TargetNodePos = targetNodePos, EmptyNodePos = emptyNodePos, H = 0, F = 0, }; var endTargetNodePos = new X_Y { X = 0, Y = 0 }; var open = new HashSetOrderedBy <GraphNode, int>((state) => state.G); var close = new HashSet <GraphNode>(); open.Add(initState); var count = 0; GraphNode path = null; while (open.Any() && path == null) { count++; var currentNode = open.ValueWithMinSelector(); var children = GenerateChildren(currentNode, nodes, maxAvail, endTargetNodePos); foreach (var child in children) { if (open.TryGetValue(child, out GraphNode existingNode) || close.TryGetValue(child, out existingNode)) { if (existingNode.H <= child.H) { continue; } open.Remove(existingNode); } open.Add(child); if (child.TargetNodePos.Equals(endTargetNodePos)) { path = child; break; } } open.Remove(currentNode); close.Add(currentNode); yield return(new State { Closed = close, Open = open, LastClosed = currentNode, Path = path, }); } }
private GraphNode SolveTSP(Dictionary <char, Dictionary <char, GraphNode> > graph, Dictionary <char, X_Y> locations, char zeroPoint, Func <GraphNode, GraphNode, bool> targetCondition) { GraphNode path = null; var locationsToVisit = new string(locations.Keys.OrderBy(c => c).ToArray()); locationsToVisit = this.VisitLocation(locationsToVisit, zeroPoint); var initState = new GraphNode { CurrentPos = locations[zeroPoint], LocationsToVisit = locationsToVisit, LastLocation = '0', H = 0, F = 0, }; var returnState = new GraphNode { CurrentPos = locations[zeroPoint], LocationsToVisit = string.Empty, }; var open = new HashSetOrderedBy <GraphNode, int>((state) => state.G); var close = new HashSet <GraphNode>(); open.Add(initState); var count = 0; while (open.Any()) { count++; var currentNode = open.ValueWithMinSelector(); var lastOpen = new LinkedList <GraphNode>(); var children = this.GenerateChildrenTSP(currentNode, graph, locations, path); foreach (var child in children) { if (open.TryGetValue(child, out GraphNode existingNode) || close.TryGetValue(child, out existingNode)) { if (existingNode.H <= child.H) { continue; } open.Remove(existingNode); } lastOpen.AddLast(child); open.Add(child); if (targetCondition(child, returnState) && (path == null || path.H > child.H)) { path = child; var nodesToDelete = open.Where(n => n.H >= path.H).ToList(); foreach (var nd in nodesToDelete) { open.Remove(nd); } } } open.Remove(currentNode); close.Add(currentNode); } return(path); }
private IEnumerable <GraphNode> SolveGraph(Dictionary <string, Dictionary <string, int> > graph) { GraphNode path = null; var open = new HashSetOrderedBy <GraphNode, int>((state) => state.Cost); var close = new HashSet <GraphNode>(); var keyToHash = new Dictionary <string, int>(); var hash = 1; foreach (var key in graph.Keys) { keyToHash.Add(key, hash); hash <<= 1; } var locationsToVisit = hash - 1; foreach (var location in graph.Keys) { var initState = new GraphNode { CurrentPos = location, LocationsToVisit = locationsToVisit - keyToHash[location], Cost = 0, }; open.Add(initState); } while (open.Any()) { var currentNode = open.ValueWithMinSelector(); var children = this.GenerateChildren(currentNode, graph, path, keyToHash); foreach (var child in children) { if (open.TryGetValue(child, out GraphNode existingNode) || close.TryGetValue(child, out existingNode)) { if (existingNode.Cost <= child.Cost) { continue; } open.Remove(existingNode); } open.Add(child); if (child.LocationsToVisit == 0) { path = child; var nodesToDelete = open.Where(n => n.Cost >= path.Cost).ToList(); foreach (var nd in nodesToDelete) { open.Remove(nd); } } } open.Remove(currentNode); close.Add(currentNode); yield return(currentNode); } yield return(path); }