コード例 #1
0
        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,
                });
            }
        }
コード例 #2
0
ファイル: Day24.cs プロジェクト: AlexChernov/adventofcode
        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);
        }
コード例 #3
0
        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);
        }