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);
 }
示例#8
0
 private E GetOriginalEdgeInstance(EquatableTaggedEdge <string, double> edgeAdaptee)
 {
     return(base.GetOriginalEdgeInstance(edgeAdaptee.Source, edgeAdaptee.Target));
 }