public void TagChanged() { var edge = new EquatableTaggedEdge <int, TestObject>(1, 2, null); int changeCount = 0; edge.TagChanged += (_, _) => ++ changeCount; edge.Tag = null; Assert.AreEqual(0, changeCount); var tag1 = new TestObject(1); edge.Tag = tag1; Assert.AreEqual(1, changeCount); edge.Tag = tag1; Assert.AreEqual(1, changeCount); var tag2 = new TestObject(2); edge.Tag = tag2; Assert.AreEqual(2, changeCount); edge.Tag = tag1; Assert.AreEqual(3, changeCount); }
public void Equals() { var tag1 = new TestObject(1); var tag2 = new TestObject(2); var edge1 = new EquatableTaggedEdge <int, TestObject>(1, 2, tag1); var edge2 = new EquatableTaggedEdge <int, TestObject>(1, 2, tag1); var edge3 = new EquatableTaggedEdge <int, TestObject>(1, 2, tag2); var edge4 = new EquatableTaggedEdge <int, TestObject>(1, 2, null); var edge5 = new EquatableTaggedEdge <int, TestObject>(1, 2, null); var edge6 = new EquatableTaggedEdge <int, TestObject>(2, 1, null); Assert.AreEqual(edge1, edge1); Assert.AreEqual(edge1, edge2); Assert.AreEqual(edge2, edge1); Assert.IsTrue(edge1.Equals((object)edge2)); Assert.IsTrue(edge1.Equals(edge3)); // Tag is not taken into account for equality Assert.IsTrue(edge1.Equals(edge4)); // Tag is not taken into account for equality Assert.AreEqual(edge4, edge5); Assert.AreEqual(edge5, edge4); Assert.IsTrue(edge4.Equals((object)edge5)); Assert.IsTrue(edge4.Equals(edge5)); // Tag is not taken into account for equality Assert.IsTrue(edge5.Equals(edge4)); // Tag is not taken into account for equality Assert.AreNotEqual(edge4, edge6); Assert.AreNotEqual(edge6, edge4); Assert.IsFalse(edge4.Equals((object)edge6)); Assert.IsFalse(edge4.Equals(edge6)); Assert.IsFalse(edge6.Equals(edge4)); Assert.AreNotEqual(null, edge1); Assert.IsFalse(edge1.Equals(null)); }
public void ObjectToString() { var edge1 = new EquatableTaggedEdge <int, TestObject>(1, 2, null); var edge2 = new EquatableTaggedEdge <int, TestObject>(1, 2, new TestObject(25)); var edge3 = new EquatableTaggedEdge <int, TestObject>(2, 1, null); Assert.AreEqual("1 -> 2 (no tag)", edge1.ToString()); Assert.AreEqual("1 -> 2 (25)", edge2.ToString()); Assert.AreEqual("2 -> 1 (no tag)", edge3.ToString()); }
public void Hashcode() { var tag = new TestObject(1); var edge1 = new EquatableTaggedEdge <int, TestObject>(1, 2, null); var edge2 = new EquatableTaggedEdge <int, TestObject>(1, 2, null); var edge3 = new EquatableTaggedEdge <int, TestObject>(2, 1, null); var edge4 = new EquatableTaggedEdge <int, TestObject>(1, 2, tag); Assert.AreEqual(edge1.GetHashCode(), edge2.GetHashCode()); Assert.AreNotEqual(edge1.GetHashCode(), edge3.GetHashCode()); Assert.AreEqual(edge1.GetHashCode(), edge4.GetHashCode()); // Tag is not taken into account for hashcode }
private void OnGraphEdgeRemoved(EquatableTaggedEdge <TVertex, double> edge) { _edgesToRestore.Add(edge); }
private bool SearchAndAddKthShortestPath( SortedPath previousPath, List <SortedPath> shortestPaths, IQueue <SortedPath> shortestPathCandidates) { // Iterate over all of the nodes in the (k-1)st shortest path except for the target node // For each node (up to) one new candidate path is generated by temporarily modifying // the graph and then running Dijkstra's algorithm to find the shortest path between // the node and the target in the modified graph for (int i = 0; i < previousPath.Count; ++i) { // Spur node is retrieved from the previous k-shortest path = currently visited vertex in the previous path TVertex spurVertex = previousPath.GetVertex(i); // The sequence of nodes from the source to the spur node of the previous k-shortest path EquatableTaggedEdge <TVertex, double>[] rootPath = previousPath.GetEdges(i); foreach (SortedPath path in shortestPaths) { if (rootPath.SequenceEqual(path.GetEdges(i))) { // Remove the links that are part of the previous shortest paths which share the same root path EquatableTaggedEdge <TVertex, double> edgeToRemove = path.GetEdge(i); _edgesToRestore.Add(edgeToRemove); _graph.RemoveEdge(edgeToRemove); } } var verticesToRestore = new List <TVertex>(); foreach (EquatableTaggedEdge <TVertex, double> rootPathEdge in rootPath) { TVertex source = rootPathEdge.Source; if (!EqualityComparer <TVertex> .Default.Equals(spurVertex, source)) { verticesToRestore.Add(source); _graph.EdgeRemoved += OnGraphEdgeRemoved; _graph.RemoveVertex(source); _graph.EdgeRemoved -= OnGraphEdgeRemoved; } } SortedPath?spurPath = GetShortestPathInGraph(_graph, spurVertex, _targetVertex); if (spurPath.HasValue) { // Entire path is made up of the root path and spur path var totalPath = new SortedPath(previousPath.GetEdges(i).Concat(spurPath.Value)); // Add the potential k-shortest path to the heap if (!shortestPathCandidates.Contains(totalPath)) { shortestPathCandidates.Enqueue(totalPath); } } // Add back the edges and nodes that were removed from the graph _graph.AddVertexRange(verticesToRestore); _graph.AddEdgeRange(_edgesToRestore); _edgesToRestore.Clear(); } // Identify the candidate path with the shortest cost SortedPath?newPath = ExtractShortestPathCandidate(shortestPaths, shortestPathCandidates); if (newPath is null) { // This handles the case of there being no spur paths, or no spur paths left. // This could happen if the spur paths have already been exhausted (added to A), // or there are no spur paths at all - such as when both the source and sink vertices // lie along a "dead end". return(false); } // Add the best, non-duplicate candidate identified as the k shortest path shortestPaths.Add(newPath.Value); return(true); }
private static double DefaultGetWeights(EquatableTaggedEdge <TVertex, double> edge) { return(edge.Tag); }
private E GetOriginalEdgeInstance(EquatableTaggedEdge <string, double> edgeAdaptee) { return(base.GetOriginalEdgeInstance(edgeAdaptee.Source, edgeAdaptee.Target)); }