Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
        private IEnumerable <GraphNode> GenerateChildren(GraphNode currentNode, Dictionary <string, Dictionary <string, int> > graph, GraphNode path, Dictionary <string, int> keyToHash)
        {
            foreach (var kvp in graph[currentNode.CurrentPos])
            {
                if ((currentNode.LocationsToVisit & keyToHash[kvp.Key]) == 0)
                {
                    continue;
                }

                var h = currentNode.Cost + kvp.Value;

                if (path != null && path.Cost < h)
                {
                    continue;
                }

                yield return(new GraphNode
                {
                    CurrentPos = kvp.Key,
                    Cost = h,
                    LocationsToVisit = currentNode.LocationsToVisit - keyToHash[kvp.Key],
                    Parent = currentNode,
                });
            }
        }
Exemplo n.º 3
0
        private IEnumerable <GraphNode> TSP(Dictionary <string, Dictionary <string, int> > graph, HashSet <string> visited, GraphNode currPos, int n, int count, GraphNode ans)
        {
            if (count == n)
            {
                if (ans.Cost < currPos.Cost)
                {
                    ans.Parent     = currPos.Parent;
                    ans.Cost       = currPos.Cost;
                    ans.CurrentPos = currPos.CurrentPos;
                }

                yield break;
            }

            if (currPos == null)
            {
                foreach (var nextLocation in graph.Keys)
                {
                    visited.Add(nextLocation);
                    var next = new GraphNode
                    {
                        Parent     = currPos,
                        Cost       = 0,
                        CurrentPos = nextLocation,
                    };
                    foreach (var innerNodes in this.TSP(graph, visited, next, n, count + 1, ans))
                    {
                        yield return(innerNodes);
                    }

                    visited.Remove(nextLocation);
                }
            }
            else
            {
                foreach (var nextLocation in graph[currPos.CurrentPos].Keys)
                {
                    if (!visited.Contains(nextLocation))
                    {
                        visited.Add(nextLocation);
                        var next = new GraphNode
                        {
                            Parent     = currPos,
                            Cost       = currPos.Cost + graph[currPos.CurrentPos][nextLocation],
                            CurrentPos = nextLocation,
                        };

                        yield return(next);

                        foreach (var innerNodes in this.TSP(graph, visited, next, n, count + 1, ans))
                        {
                            yield return(innerNodes);
                        }

                        visited.Remove(nextLocation);
                    }
                }
            }
        }