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); }
/// <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); }
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); }
//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); }
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); }
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); }
//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); }
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); }