Exemple #1
0
        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);
        }
Exemple #2
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);
        }