Exemple #1
0
        protected override int ExecuteTest()
        {
            if (NodeStates.FixedTargetNodeCount <= 1 || NodeStates.VariableTargetNodeCount > 0)
            {
                return(0);
            }

            var removedNodes = 0;

            var mst = new MinimalSpanningTree(NodeStates.FixedTargetNodeIndices.ToList(), DistanceLookup);

            mst.Span(StartNodeIndex);
            var maxEdgeDistance = mst.SpanningEdges.Max(e => e.Priority);

            for (var i = 0; i < SearchSpaceSize; i++)
            {
                if (NodeStates.IsTarget(i) || NodeStates.IsRemoved(i))
                {
                    continue;
                }

                // Theoretically, this can be sped up by using Voronoi partitions. The Voronoi base of i is the
                // terminal with the smallest distance to i by definition, so only the distance to that terminal
                // has to be checked.
                if (NodeStates.FixedTargetNodeIndices.All(t => DistanceLookup[i, t] >= maxEdgeDistance))
                {
                    EdgeSet.EdgesOf(i).ForEach(EdgeSet.Remove);
                    NodeStates.MarkNodeAsRemoved(i);
                    removedNodes++;
                }
            }

            return(removedNodes);
        }
        /// <summary>
        /// Removes all nodes that were marked as removed from the search space and updates the distance lookup and the edge set.
        /// </summary>
        private void ContractSearchSpace()
        {
            var distanceLookup = _data.DistanceLookup;
            // Save all edges by the GraphNodes they are connecting. (the indices are worthless after the search space is contracted)
            var edges =
                _data.EdgeSet.Select(
                    e => Tuple.Create(distanceLookup.IndexToNode(e.N1), distanceLookup.IndexToNode(e.N2), e.Weight))
                .ToList();

            // Contract the search space and update _distanceLookup.
            _nodeStates.SearchSpace = distanceLookup.RemoveNodes(_nodeStates.SearchSpace.Where(n => _nodeStates.IsRemoved(n.DistancesIndex)));
            // Add all edges back.
            _data.EdgeSet = new GraphEdgeSet(distanceLookup.CacheSize);
            foreach (var tuple in edges)
            {
                _data.EdgeSet.Add(tuple.Item1.DistancesIndex, tuple.Item2.DistancesIndex, tuple.Item3);
            }
        }