예제 #1
0
        public override bool AddEdge(T v1, T v2, K weight)
        {
            if (v1 is null)
            {
                throw new ArgumentNullException(nameof(v1));
            }

            if (v2 is null)
            {
                throw new ArgumentNullException(nameof(v2));
            }

            if (weight is null)
            {
                throw new ArgumentNullException(nameof(weight));
            }

            if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2))
            {
                return(false);
            }

            IPairValue <T> pair = new PairValueI <T>(v1, v2);

            if (EdgeSet.Contains(pair))
            {
                return(false);
            }

            EdgeSet.Add(pair);
            Weights[pair] = weight;
            return(true);
        }
예제 #2
0
        /// <summary>
        /// Merges the node x into the fixed target node into.
        ///
        /// Edges between these nodes, edges to x and related distance information is updated.
        ///
        /// x is marked as to be removed from the search space. If x was the start node, into
        /// will now be the start node.
        /// </summary>
        /// <returns>All neighbors of x before merging. These are the nodes that had their adjacency
        /// information changed.</returns>
        protected IEnumerable <int> MergeInto(int x, int into)
        {
            if (!NodeStates.IsFixedTarget(into))
            {
                throw new ArgumentException("Nodes can only be merged into fixed target nodes", "into");
            }

            _data.DistanceLookup.IndexToNode(into).MergeWith(_data.DistanceLookup.IndexToNode(x), _data.DistanceLookup.GetShortestPath(x, into));
            _data.DistanceLookup.MergeInto(x, into);

            EdgeSet.Remove(x, into);
            var intoNeighbors = EdgeSet.NeighborsOf(into);
            var xNeighbors    = EdgeSet.NeighborsOf(x);
            var neighbors     = intoNeighbors.Union(xNeighbors);

            foreach (var neighbor in xNeighbors)
            {
                EdgeSet.Remove(x, neighbor);
            }
            foreach (var neighbor in neighbors)
            {
                EdgeSet.Add(into, neighbor, _data.DistanceLookup[into, neighbor]);
            }

            if (StartNodeIndex == x)
            {
                _data.StartNodeIndex = into;
            }

            NodeStates.MarkNodeAsRemoved(x);

            return(xNeighbors);
        }
예제 #3
0
    public EdgeSet CreateEdgeSet()
    {
        EdgeSet edgeSet = new EdgeSet();

        foreach (Polygon poly in this)
        {
            foreach (Polygon neighbor in poly.m_Neighbors)
            {
                if (this.Contains(neighbor))
                {
                    continue;
                }
                Edge edge = new Edge(poly, neighbor);
                edgeSet.Add(edge);
            }
        }
        return(edgeSet);
    }
예제 #4
0
    //Given a set of Polys, calculate the set of Edges that surround them.
    public EdgeSet GenerateEdgeSet()
    {
        EdgeSet edgeSet = new EdgeSet();

        foreach (Polygon poly in this)
        {
            foreach (Polygon neighbor in poly.m_Neighbors)
            {
                if (this.Contains(neighbor))
                {
                    continue;
                }
                // If our neighbor is not in polyset then the edge is between this poly and neighbor
                Edge edge = new Edge(poly, neighbor);
                edgeSet.Add(edge);
            }
        }
        return(edgeSet);
    }
예제 #5
0
        public override bool AddEdge(TV v1, TV v2, TK weigth)
        {
            if (v1 == null || v2 == null || weigth == null)
            {
                throw new ArgumentNullException();
            }
            if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2))
            {
                return(false);
            }
            IPairValue <TV> pair = new PairValue <TV>(v1, v2);

            if (EdgeSet.Contains(pair))
            {
                return(false);
            }
            EdgeSet.Add(pair);
            Weigths[pair] = weigth;
            return(true);
        }
    //Given a set of Polys, calculate the set of Edges
    //that surround them.

    public EdgeSet CreateEdgeSet()
    {
        EdgeSet edgeSet = new EdgeSet();

        foreach (Polygon poly in this)
        {
            foreach (Polygon neighbor in poly.m_Neighbors)
            {
                if (this.Contains(neighbor))
                {
                    continue;
                }
                // If our neighbor isn't in our PolySet, then
                // the edge between us and our neighbor is one
                // of the edges of this PolySet.
                Edge edge = new Edge(poly, neighbor);
                edgeSet.Add(edge);
            }
        }
        return(edgeSet);
    }
예제 #7
0
        public override bool AddEdge(KeyValuePair <T, K> v1, KeyValuePair <T, K> v2, K weight)
        {
            if (v1.Key == null || v2.Key == null || weight == null)
            {
                throw new ArgumentNullException();
            }
            if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2))
            {
                return(false);
            }
            IPairValue <T> pair = new PairValue <T>(v1.Key, v2.Key);

            if (EdgeSet.Contains(pair))
            {
                return(false);
            }

            EdgeSet.Add(pair);
            Weights[pair] = weight;
            return(true);
        }
예제 #8
0
    //Given a set of Polys, calculate the set of Edges
    //that surround them.

    public static EdgeSet CreateEdgeSet(HashSet <Polygon> polygons)
    {
        var edgeSet = new EdgeSet();

        foreach (Polygon poly in polygons)
        {
            foreach (Polygon neighbor in poly.Neighbors)
            {
                if (polygons.Contains(neighbor))
                {
                    continue;
                }

                // If our neighbor isn't in our PolySet, then
                // the edge between us and our neighbor is one
                // of the edges of this PolySet.
                var edge = new Edge(poly, neighbor);
                edgeSet.Add(edge);
            }
        }

        return(edgeSet);
    }
예제 #9
0
        private void RemoveNode(int index)
        {
            if (NodeStates.IsTarget(index))
            {
                throw new ArgumentException("Target nodes can't be removed", "index");
            }

            var neighbors = EdgeSet.NeighborsOf(index);

            switch (neighbors.Count)
            {
            case 0:
                break;

            case 1:
                EdgeSet.Remove(index, neighbors[0]);
                break;

            case 2:
                // Merge the two incident edges.
                var left      = neighbors[0];
                var right     = neighbors[1];
                var newWeight = EdgeSet[index, left].Weight + EdgeSet[index, right].Weight;
                EdgeSet.Remove(index, left);
                EdgeSet.Remove(index, right);
                if (newWeight <= DistanceLookup[left, right])
                {
                    EdgeSet.Add(left, right, newWeight);
                }
                break;

            default:
                throw new ArgumentException("Removing nodes with more than 2 neighbors is not supported", "index");
            }

            NodeStates.MarkNodeAsRemoved(index);
        }
        protected override int ExecuteTest()
        {
            var edges        = new GraphEdge[SearchSpaceSize];
            var removedNodes = 0;

            for (var i = 0; i < SearchSpaceSize; i++)
            {
                // This test only checks non-terminals.
                if (NodeStates.IsTarget(i))
                {
                    continue;
                }

                // Nodes with less than 3 neighbors are covered by DegreeTest
                // Nodes are limited to 7 neighbors because this test is exponential in the neighbor count.
                var neighbors = EdgeSet.NeighborsOf(i);
                if (neighbors.Count < 3 || neighbors.Count > 7)
                {
                    continue;
                }

                // Cache the edges. They might be removed from EdgeSet when we need them.
                foreach (var neighbor in neighbors)
                {
                    edges[neighbor] = EdgeSet[i, neighbor];
                }

                // Check whether each subset satisfies the condition.
                var canBeRemoved = true;
                foreach (var subset in GetAllSubsets(neighbors))
                {
                    // Only subsets of at least size 3 are relevant.
                    if (subset.Count < 3)
                    {
                        continue;
                    }

                    // Sum up the weights of all edges between the nodes of the subsets and i.
                    var edgeSum = subset.Sum(j => edges[j].Weight);
                    // Build the MST of the fully connected graph of the nodes in the subset with the bottleneck
                    // Steiner distances as edge weights.
                    var mst = new MinimalSpanningTree(subset, SMatrix);
                    mst.Span(subset[0]);
                    // Sum up the edge weights of the MST.
                    var mstSum = mst.SpanningEdges.Sum(e => e.Priority);
                    // The condition is only satisfied if edgeSum >= mstSum.
                    if (edgeSum < mstSum)
                    {
                        canBeRemoved = false;
                        break;
                    }
                }

                if (!canBeRemoved)
                {
                    continue;
                }

                // Remove i and replace its edges.
                foreach (var neighbor in neighbors)
                {
                    // Remove the old edges between i and its neighbors.
                    var edge = edges[neighbor];
                    EdgeSet.Remove(edge);
                    // For each pair of neighbors create a new edge.
                    foreach (var neighbor2 in neighbors)
                    {
                        if (neighbor >= neighbor2)
                        {
                            continue;
                        }
                        // The weight of the new edge between the two neighbors is the sum of their edge weights to i.
                        var edge2         = edges[neighbor2];
                        var newEdgeWeight = edge.Weight + edge2.Weight;
                        // Only add this edge if it wouldn't be removed by the Paths with many terminals test.
                        if (newEdgeWeight <= SMatrix[neighbor, neighbor2])
                        {
                            EdgeSet.Add(neighbor, neighbor2, newEdgeWeight);
                        }
                    }
                }

                NodeStates.MarkNodeAsRemoved(i);
                removedNodes++;
            }
            return(removedNodes);
        }