Пример #1
0
        /// <summary>
        /// Create a path by simply doing the current path then reversing it.
        /// </summary>
        /// <returns></returns>
        private WeightedAdjacencyNode <T>[] CreateOutAndBack(WeightedAdjacencyNode <T> turnaround)
        {
            var outPath = _currentStack.ToList();

            outPath.Add(turnaround);
            outPath.AddRange(_currentStack.Reverse());
            return(outPath.ToArray());
        }
Пример #2
0
 private void PushNode(WeightedAdjacencyNode <T> currentNode)
 {
     _currentStack.Push(currentNode);
     if (!_nodeCount.ContainsKey(currentNode))
     {
         _nodeCount.Add(currentNode, 0);
     }
     _nodeCount[currentNode]++;
     if (!_vertextCounts.ContainsKey(currentNode.Vertex))
     {
         _vertextCounts.Add(currentNode.Vertex, 0);
     }
     _vertextCounts[currentNode.Vertex]++;
 }
Пример #3
0
        // return is a reject depth
        private int Recurse(T startingPlace, WeightedAdjacencyNode <T> currentNode, double maxDistance, double currentDistance)
        {
            // Console.WriteLine($"{new string(' ', _currentStack.Count)}{currentNode.Vertex}");
            var previousVertex = _currentStack.Peek().Vertex;
            var rejectDepth    = 0;

            if (currentDistance > maxDistance)
            {
                return(rejectDepth); // base case: too far away so log a path and don't recurse.
            }
            if (_simpleDistanceCostCompute(startingPlace, currentNode.Vertex) + currentDistance > maxDistance)
            {
                // return a path that represents an out and back.
                AddPath(CreateOutAndBack(currentNode));
                return(1);
            }
            if (maxDistance * MaxTurnsPerKilometer < _currentStack.Count())
            {
                return(rejectDepth);
            }
            if (_nodeCount.Where(kvp => kvp.Value > 2).Select(kvp => kvp.Key.Distance * kvp.Value).Sum() > maxDistance * MaxDuplicatedDistance)
            {
                return(rejectDepth);
            }

            PushNode(currentNode);
            foreach (var node in _graph.Neighbors[currentNode.Vertex])
            {
                if (node.Vertex.Equals(startingPlace))
                {
                    rejectDepth = AddPath(CreateLoop(currentNode)); // base case: hit start so log a path and don't recurse.
                }
                else
                {
                    if (!TightLoop(node) && !node.Vertex.Equals(previousVertex))
                    {
                        rejectDepth = Recurse(startingPlace, node, maxDistance, currentDistance + node.Distance);
                    }
                }
                if (rejectDepth > 0)
                {
                    break;
                }
            }
            PopNode(currentNode);
            return(--rejectDepth);
        }
Пример #4
0
        private WeightedAdjacencyNode <T>[] CreateLoop(WeightedAdjacencyNode <T> lastLink)
        {
            var outPath = _currentStack.ToArray();

            return(outPath);
        }
Пример #5
0
 private void PopNode(WeightedAdjacencyNode <T> currentNode)
 {
     _currentStack.Pop();
     _nodeCount[currentNode]--;
     _vertextCounts[currentNode.Vertex]--;
 }
Пример #6
0
 private bool TightLoop(WeightedAdjacencyNode <T> node)
 {
     return((_nodeCount.ContainsKey(node) && _nodeCount[node] + 1 > MaxTripsForSegment) ||
            (_vertextCounts.ContainsKey(node.Vertex) && _vertextCounts[node.Vertex] + 1 > MaxTripsForVertex));
 }