public void TestEqualityDifferentWeights()
        {
            var edge1 = new UndirectedEdge <int>(between: new IntNode(21), and: new IntNode(42));
            var edge2 = new UndirectedEdge <int>(between: new IntNode(21), and: new IntNode(42), weight: 13.0d);

            Assert.AreEqual(edge1, edge2);
        }
예제 #2
0
        public RandomErdosGraph(int numberOfNodes, double probability)
        {
            _numberOfNodes = numberOfNodes;

            _probability = probability;

            Graph = new UndirectedGraph <int, UndirectedEdge <int> >();

            List <int> vertexs = new List <int>();

            Random random = new Random();

            for (int i = 0; i < _numberOfNodes; i++)
            {
                var vertex = i;
                vertexs.Add(vertex);
                Graph.AddVertex(vertex);
            }

            for (int i = 0; i < _numberOfNodes; i++)
            {
                for (int j = i; j < _numberOfNodes; j++)
                {
                    if (i != j)
                    {
                        var p = random.NextDouble();
                        if (_probability == 1.0f || p >= _probability)
                        {
                            var e1 = new UndirectedEdge <int>(vertexs.ElementAt(i), vertexs.ElementAt(j));
                            Graph.AddEdge(e1);
                        }
                    }
                }
            }
        }
예제 #3
0
        public void UndirectedEdge_EqualsWithSameVertexOrderTest()
        {
            // Arrange.
            UndirectedEdge <Vertex> edge1;
            UndirectedEdge <Vertex> edge2;
            Vertex vertex1;
            Vertex vertex2;
            Vertex vertex3;
            Vertex vertex4;
            string expectedEdge1Vertex1Label = "My label a";
            string expectedEdge1Vertex2Label = "My label b";
            string expectedEdge2Vertex1Label = "My label a";
            string expectedEdge2Vertex2Label = "My label b";

            // Act.
            vertex1 = new Vertex(expectedEdge1Vertex1Label);
            vertex2 = new Vertex(expectedEdge1Vertex2Label);
            vertex3 = new Vertex(expectedEdge2Vertex1Label);
            vertex4 = new Vertex(expectedEdge2Vertex2Label);
            edge1   = new UndirectedEdge <Vertex>(vertex1, vertex2);
            edge2   = new UndirectedEdge <Vertex>(vertex3, vertex4);

            // Assert.
            Assert.AreNotSame(edge1, edge2);
            Assert.AreEqual(edge1, edge2);
            Assert.IsTrue(edge1 == edge2);
            Assert.IsFalse(edge1 != edge2);
        }
예제 #4
0
        public void EdgesComparerTests()
        {
            var v11        = new Vertex("A");
            var v21        = new Vertex("B");
            var v12        = new Vertex("A");
            var v22        = new Vertex("B");
            var dirEdge1   = new DirectedEdge(v11, v21);
            var dirEdge2   = new DirectedEdge(v12, v22);
            var dirEdge3   = new DirectedEdge(v11, v22);
            var dirEdge4   = new DirectedEdge(v21, v11);
            var dirEdge5   = new DirectedEdge(v11, v11);
            var undirEdge1 = new UndirectedEdge(v11, v21);
            var undirEdge2 = new UndirectedEdge(v12, v22);
            var undirEdge3 = new UndirectedEdge(v11, v22);
            var undirEdge4 = new UndirectedEdge(v21, v11);
            var undirEdge5 = new UndirectedEdge(v11, v11);

            Assert.IsTrue(dirEdge1.Equals(dirEdge2));
            Assert.IsTrue(dirEdge1.Equals(dirEdge3));
            Assert.IsTrue(undirEdge1.Equals(undirEdge2));
            Assert.IsTrue(undirEdge1.Equals(undirEdge3));
            Assert.IsFalse(dirEdge1.Equals(undirEdge1));
            Assert.IsFalse(dirEdge1.Equals(dirEdge4));
            Assert.IsTrue(undirEdge1.Equals(undirEdge4));
            Assert.IsFalse(dirEdge1.Equals(dirEdge5));
            Assert.IsFalse(undirEdge1.Equals(undirEdge5));
        }
예제 #5
0
        public RandomGraph(int N, double P)
        {
            int v1 = 0, v2 = 0;

            count    = 0;
            MaxEdges = (int)Math.Round(P * N * (N - 1) / 2);
            for (int i = 1; i <= N; i++)
            {
                g.AddVertex(i);
            }
            for (int i = 0; i < MaxEdges; i++)
            {
                v1 = 0;
                v2 = 0;
                v1 = random.Next() % N + 1;
                v2 = random.Next() % N + 1;
                if (v1 == v2)
                {
                    continue;
                }
                if (!g.ContainsEdge(v2, v1))
                {
                    var  e1 = new UndirectedEdge <int>(v1, v2);
                    bool v  = g.AddEdge(e1);
                    if (v)
                    {
                        count++;
                    }
                }
            }
            Console.WriteLine("Max Edges: " + MaxEdges);
            Console.WriteLine("Egdes created: " + count);
        }
예제 #6
0
        public bool EdgeRemove(UndirectedEdge <int> edge)
        {
            if (MGraph.ContainsEdge(edge))
            {
                _mNumEdges--;
                var findf = _edgeDictionary.Values.ToList()
                            .Find((e) =>
                {
                    return(e.Target == edge.Target && e.Source == edge.Source);
                }
                                  );
                if (_edgeDictionary.Values.ToList().Find((e) => e.Target == edge.Target && e.Source == edge.Source) != null)
                {
                    var edgeUn = _edgeDictionary.First(e => e.Value.Target == edge.Target && e.Value.Source == edge.Source);
                    if (edgeUn.Equals(default(KeyValuePair <int, UndirectedEdge <int> >)))
                    {
                        return(false);
                    }
                    _edgeDictionary.Remove(edgeUn.Key);
                }
                return(MGraph.RemoveEdge(edge));
            }

            return(false);
        }
예제 #7
0
        public void CloneTest()
        {
            var graph      = new UndirectedGraph();
            var newVertex1 = new Vertex("test-1");
            var newVertex2 = new Vertex("test-2");
            var newVertex3 = new Vertex("test-3");

            graph.AddVertex(newVertex1);
            graph.AddVertex(newVertex2);
            graph.AddVertex(newVertex3);
            var newEdge1 = new UndirectedEdge(newVertex1, newVertex2);
            var newEdge2 = new UndirectedEdge(newVertex1, newVertex3);

            graph.AddEdge(newEdge1);
            graph.AddEdge(newEdge2);

            var clonedGraph = graph.Clone() as IGraph;

            Assert.IsTrue(clonedGraph is UndirectedGraph);
            Assert.AreEqual(graph.VerticesCount, clonedGraph.VerticesCount);
            foreach (var vertex in graph.Vertices)
            {
                var clonedVertex = clonedGraph.Vertices.Single(v => v.Equals(vertex));
                Assert.AreNotSame(clonedVertex, vertex);
            }
            Assert.AreEqual(graph.EdgesCount, clonedGraph.EdgesCount);
            foreach (var clonedEdge in clonedGraph.Edges)
            {
                Assert.IsTrue(clonedEdge is UndirectedEdge);
                var edge = graph.Edges.Single(e => e.Equals(clonedEdge));
                Assert.AreNotSame(edge, clonedEdge);
            }
        }
        public void TestInverseOrderEquality()
        {
            var edge1 = new UndirectedEdge <int>(between: new IntNode(21), and: new IntNode(42));
            var edge2 = new UndirectedEdge <int>(between: new IntNode(42), and: new IntNode(21));

            Assert.AreEqual(edge1, edge2);
        }
예제 #9
0
        public void toStringTest()
        {
            UndirectedEdge <int> ue = new UndirectedEdge <int>(0, 1);
            string result           = ue.ToString();

            Assert.AreEqual("0<->1", result);
        }
예제 #10
0
 public bool Equals(UndirectedEdge edge) //"Overwrite" Equals() function
 {
     if (VOne.Equals(edge.VOne) && VTwo.Equals(edge.VTwo))
     {
         return(true);
     }
     return(false);
 }
        public int Compare(UndirectedEdge <T> other)
        {
            if (this.Id == other.Id)
            {
                return(0);
            }

            return(this.Id < other.Id ? -1 : 1);
        }
예제 #12
0
        public UndirectedEdge <MapNode> GetEdge(MapNode source, MapNode target)
        {
            UndirectedEdge <MapNode> edge = AdjacentOutEdges(source).Where(mn => mn.Target == target).SingleOrDefault();

            if (edge == null)
            {
                throw new ArgumentException($"No such edge {source} <-> {target}");
            }
            return(edge);
        }
예제 #13
0
        public void Equals()
        {
            var edge1 = new UndirectedEdge <int>(1, 2);
            var edge2 = new UndirectedEdge <int>(1, 2);

            Assert.AreEqual(edge1, edge1);
            Assert.AreNotEqual(edge1, edge2);

            Assert.AreNotEqual(edge1, null);
        }
예제 #14
0
        /// <summary>
        /// Adds a connection between specified vertices.
        /// </summary>
        /// <param name="i">First vertex number.</param>
        /// <param name="j">Second vertex number.</param>
        public void AddConnection(int i, int j)
        {
            if (i == j || AreConnected(i, j))
            {
                return;
            }
            UndirectedEdge <int> e = (i < j) ? new UndirectedEdge <int>(i, j) : new UndirectedEdge <int>(j, i);

            graph.AddEdge(e);
        }
        /**
         * Return true if the given loops form a valid polygon. Assumes that that all
         * of the given loops have already been validated.
         */

        public static bool IsValidPolygon(System.Collections.Generic.IReadOnlyList <S2Loop> loops)
        {
            // If a loop contains an edge AB, then no other loop may contain AB or BA.
            // We only need this test if there are at least two loops, assuming that
            // each loop has already been validated.
            if (loops.Count > 1)
            {
                System.Collections.Generic.IDictionary <UndirectedEdge, LoopVertexIndexPair> edges = new Dictionary <UndirectedEdge, LoopVertexIndexPair>();
                for (var i = 0; i < loops.Count; ++i)
                {
                    var lp = loops[i];
                    for (var j = 0; j < lp.NumVertices; ++j)
                    {
                        var key   = new UndirectedEdge(lp.Vertex(j), lp.Vertex(j + 1));
                        var value = new LoopVertexIndexPair(i, j);
                        if (edges.ContainsKey(key))
                        {
                            var other = edges[key];
                            Debug.WriteLine(
                                "Duplicate edge: loop " + i + ", edge " + j + " and loop " + other.LoopIndex
                                + ", edge " + other.VertexIndex);
                            return(false);
                        }
                        else
                        {
                            edges[key] = value;
                        }
                    }
                }
            }

            // Verify that no loop covers more than half of the sphere, and that no
            // two loops cross.
            for (var i = 0; i < loops.Count; ++i)
            {
                if (!loops[i].IsNormalized)
                {
                    Debug.WriteLine("Loop " + i + " encloses more than half the sphere");
                    return(false);
                }
                for (var j = i + 1; j < loops.Count; ++j)
                {
                    // This test not only checks for edge crossings, it also detects
                    // cases where the two boundaries cross at a shared vertex.
                    if (loops[i].ContainsOrCrosses(loops[j]) < 0)
                    {
                        Debug.WriteLine("Loop " + i + " crosses loop " + j);
                        return(false);
                    }
                }
            }
            return(true);
        }
예제 #16
0
 public UnitMove(Unit unit, MapNode mapNode, bool disband = false)
 {
     Unit = unit;
     if (!disband)
     {
         Edge = new UndirectedEdge <MapNode>(mapNode, mapNode);
     }
     else
     {
         Edge = new UndirectedEdge <MapNode>(mapNode, null);
     }
 }
예제 #17
0
        public bool AddEdge(string vOneLabel, string vTwoLabel, int weight)
        {
            Vertex vOne = Vertices.Find(p => p.Label == vOneLabel);

            if (vOne == null)
            {
                throw new ArgumentException("vOneLabel is not a valid vertex label.");
            }

            Vertex vTwo = Vertices.Find(p => p.Label == vTwoLabel);

            if (vTwo == null)
            {
                throw new ArgumentException("vTwoLabel is not a valid vertex label.");
            }

            UndirectedEdge undirectedEdge = new UndirectedEdge()
            {
                VOne   = vOne,
                VTwo   = vTwo,
                Weight = weight
            };

            if (Edges == null)
            {
                Edges = new List <UndirectedEdge>();
            }
            else
            {
                foreach (UndirectedEdge uEdge in Edges)
                {
                    if (uEdge.Equals(undirectedEdge))
                    {
                        return(false);
                    }
                }
            }


            Edges.Add(undirectedEdge);

            vOne.IncidentEdges.Add(undirectedEdge);

            //invert and re add just in case it both ways werent noted in graph creation- it is undirected anyway ;)
            undirectedEdge = new UndirectedEdge()
            {
                VOne   = vTwo,
                VTwo   = vOne,
                Weight = weight
            };
            vTwo.IncidentEdges.Add(undirectedEdge);
            return(true);
        }
 private UndirectedGraph<int, UndirectedEdge<int>> BuildGraph(int[] verticies, int[] edges)
 {
     var graph = new UndirectedGraph<int, UndirectedEdge<int>>();
     graph.AddVertexRange(verticies);
     var convEdges = new UndirectedEdge<int>[edges.Length / 2];
     for (int i = 0; i < edges.Length; i += 2)
     {
         convEdges[i / 2] = new UndirectedEdge<int>(edges[i], edges[i + 1]);
     }
     graph.AddEdgeRange(convEdges);
     return graph;
 }
예제 #19
0
        public int EdgeCreate(int sourceNode, int targetNode, bool directed)
        {
            var edgeNumber = _edgeIdCount;

            _mNumEdges++;
            _edgeIdCount++;
            var edge = new UndirectedEdge <int>(sourceNode, targetNode);

            _edgeDictionary.Add(edgeNumber, edge);
            MGraph.AddEdge(edge);
            return(edgeNumber);
        }
예제 #20
0
        private static double GetEdgeCost(Dictionary<int, Node> nodesMap, UndirectedEdge<int> e)
        {
            Node startNode = nodesMap[e.Source];
            Node endNode = nodesMap[e.Target];

            decimal diffX = endNode.X - startNode.X;
            decimal diffY = endNode.Y - startNode.Y;
            // Unterschiede im Stockwerk beachten
            // Da Höhe unbekannt einfach irgendwelche Kosten festlegen
            decimal diffZ = endNode.FloorId != startNode.FloorId ? 0.2m : 0m;

            return Math.Sqrt((double)(diffX * diffX + diffY * diffY + diffZ * diffZ));
        }
예제 #21
0
        private UndirectedGraph <int, UndirectedEdge <int> > BuildGraph(int[] verticies, int[] edges)
        {
            var graph = new UndirectedGraph <int, UndirectedEdge <int> >();

            graph.AddVertexRange(verticies);
            var convEdges = new UndirectedEdge <int> [edges.Length / 2];

            for (int i = 0; i < edges.Length; i += 2)
            {
                convEdges[i / 2] = new UndirectedEdge <int>(edges[i], edges[i + 1]);
            }
            graph.AddEdgeRange(convEdges);
            return(graph);
        }
        private UndirectedGraph <object, UndirectedEdge <object> > BuildGraph(int[] verticies, int[] edges)
        {
            var graph = new UndirectedGraph <object, UndirectedEdge <object> >();

            graph.AddVertexRange(verticies.Cast <object>());
            var newEdges  = edges.Cast <object>().ToArray();
            var convEdges = new UndirectedEdge <object> [edges.Length / 2];

            for (int i = 0; i < newEdges.Length; i += 2)
            {
                convEdges[i / 2] = new UndirectedEdge <object>(newEdges[i], newEdges[i + 1]);
            }
            graph.AddEdgeRange(convEdges);
            return(graph);
        }
예제 #23
0
        public void Equals()
        {
            var edge1 = new UndirectedEdge <int>(1, 2);
            var edge2 = new UndirectedEdge <int>(1, 2);

            Assert.AreEqual(edge1, edge1);

            Assert.AreNotEqual(edge1, edge2);
            Assert.AreNotEqual(edge2, edge1);
            Assert.IsFalse(edge1.Equals(edge2));
            Assert.IsFalse(edge2.Equals(edge1));

            Assert.AreNotEqual(null, edge1);
            Assert.IsFalse(edge1.Equals(null));
        }
예제 #24
0
        public void UndirectedEdge_IsSelfLoopTest()
        {
            // Arrange.
            UndirectedEdge <Vertex> edge;
            Vertex vertex1;
            Vertex vertex2;
            string expectedVertex1Label = "My label 1";

            // Act.
            vertex1 = new Vertex(expectedVertex1Label);
            vertex2 = vertex1;
            edge    = new UndirectedEdge <Vertex>(vertex1, vertex2);

            // Assert.
            Assert.IsTrue(edge.IsSelfLoop);
        }
예제 #25
0
        private void DivideEdge(int pInd0, int pInd1, out Vector3 pNewVertex, out int pNewIndex)
        {
            var edge = new UndirectedEdge(pInd0, pInd1);

            if (_subdividedEdges.TryGetValue(edge, out pNewIndex))
            {
                pNewVertex = _vertexPositions[pNewIndex];
            }
            else
            {
                pNewVertex = (_vertexPositions[pInd0] + _vertexPositions[pInd1]) * 0.5f;
                pNewIndex  = _vertexPositions.Count;
                _vertexPositions.Add(pNewVertex);
                _subdividedEdges[edge] = pNewIndex;
            }
        }
예제 #26
0
        public void RemoveVertexFromNonEmptyGraphTest()
        {
            var graph      = new UndirectedGraph();
            var newVertex1 = new Vertex("test-1");
            var newVertex2 = new Vertex("test-2");

            graph.AddVertex(newVertex1);
            graph.AddVertex(newVertex2);
            var edge = new UndirectedEdge(newVertex1, newVertex2);

            graph.AddEdge(edge);

            Assert.DoesNotThrow(() => graph.RemoveVertex(newVertex1));
            Assert.AreEqual(graph.VerticesCount, 1);
            Assert.AreEqual(graph.EdgesCount, 0);
            Assert.IsTrue(graph.Vertices.Contains(newVertex2));
        }
예제 #27
0
        public void RemoveEdgeTest()
        {
            var graph   = new UndirectedGraph();
            var vertex1 = new Vertex("test-1");
            var vertex2 = new Vertex("test-2");

            graph.AddVertex(vertex1);
            graph.AddVertex(vertex2);
            var edge = new UndirectedEdge(vertex1, vertex2);

            graph.AddEdge(edge);
            Assert.DoesNotThrow(() => graph.RemoveEdge(edge));
            Assert.AreEqual(graph.EdgesCount, 0);
            Assert.IsNull(graph[vertex1, vertex2]);
            Assert.IsNull(graph[vertex2, vertex1]);
            Assert.Throws <InvalidOperationException>(() => graph.RemoveEdge(edge));
            Assert.Throws <ArgumentNullException>(() => graph.RemoveEdge(null));
        }
예제 #28
0
        public void UndirectedEdge_InitializationWithValuesTest()
        {
            // Arrange.
            UndirectedEdge <Vertex> edge;
            Vertex vertex1;
            Vertex vertex2;
            string expectedVertex1Label = "My label 1";
            string expectedVertex2Label = "My label 2";

            // Act.
            vertex1 = new Vertex(expectedVertex1Label);
            vertex2 = new Vertex(expectedVertex2Label);
            edge    = new UndirectedEdge <Vertex>(vertex1, vertex2);

            // Assert.
            Assert.IsNotNull(edge.Vertex1);
            Assert.AreSame(vertex1, edge.Vertex1);
            Assert.IsNotNull(edge.Vertex2);
            Assert.AreSame(vertex2, edge.Vertex2);
        }
        public void HasLoopTest()
        {
            var ae = new UndirectedEdge <string>("A", "E");
            var ab = new UndirectedEdge <string>("A", "B");
            var bc = new UndirectedEdge <string>("B", "C");
            var cd = new UndirectedEdge <string>("C", "D");
            var de = new UndirectedEdge <string>("D", "E");
            var bd = new UndirectedEdge <string>("B", "D");
            var be = new UndirectedEdge <string>("B", "E");

            var edges = new HashSet <UndirectedEdge <string> > {
                ab, bc, cd, de, ae
            };
            var graph = new UndirectedGraph <string>(edges);

            Assert.IsTrue(graph.HasLoop());

            edges = new HashSet <UndirectedEdge <string> > {
                ae, ab, bc, cd, bd
            };
            graph = new UndirectedGraph <string>(edges);
            graph.Add("O");
            Assert.IsTrue(graph.HasLoop());

            edges = new HashSet <UndirectedEdge <string> >()
            {
                ab, bc, cd, de
            };
            graph = new UndirectedGraph <string>(edges);
            Assert.IsFalse(graph.HasLoop());

            edges = new HashSet <UndirectedEdge <string> >()
            {
                ae, be, bc, cd, de
            };
            graph = new UndirectedGraph <string>(edges);
            Assert.IsTrue(graph.HasLoop());
        }
예제 #30
0
        private void DivideEdge(int i0, int i1, out Vector3 outVertex, out int outIndex)
        {
            // Function that, when given the index of two vertices, creates a new vertex at the midpoint of those vertices.

            UndirectedEdge edge = new UndirectedEdge(i0, i1);

            // Check to see if we've already generated this vertex
            if (subdividedEdges.TryGetValue(edge, out outIndex))
            {
                // We've already generated this vertex before
                outVertex = vertexPositions[outIndex];                 // and the vertex itself
            }
            else
            {
                // Haven't generated this vertex before: so add it now

                outVertex = (vertexPositions[i0] + vertexPositions[i1]) * 0.5f;
                outIndex  = vertexPositions.Count;

                vertexPositions.Add(outVertex);
                subdividedEdges[edge] = outIndex;                 // Now add it to the map.
            }
        }
예제 #31
0
                // Function that, when given the index of two vertices, creates a new vertex at the midpoint of those vertices.
                private void DivideEdge(int i0, int i1, out Vector3 outVertex, out int outIndex)
                {
                    var edge = new UndirectedEdge(i0, i1);

                    // Check to see if we've already generated this vertex
                    if (subdividedEdges.TryGetValue(edge, out outIndex))
                    {
                        // We've already generated this vertex before
                        outVertex = vertexPositions[outIndex]; // and the vertex itself
                    }
                    else
                    {
                        // Haven't generated this vertex before: so add it now

                        // outVertex = (vertices[i0] + vertices[i1]) / 2
                        outVertex = (vertexPositions[i0] + vertexPositions[i1]) * 0.5f;
                        outIndex  = vertexPositions.Count;
                        vertexPositions.Add(outVertex);

                        // Now add it to the map.
                        subdividedEdges[edge] = outIndex;
                    }
                }
예제 #32
0
        protected virtual IQueryableGraph<int> MakeSophisticatedAssociations(IEnumerable<int> nodeIds, IMindSettings settings)
        {
            var nodeList = nodeIds.ToList();
            var nodeCount = nodeList.Count;
            if (nodeCount < 2) throw new ArgumentException("The count of nodes should be at least two.");

            Func<IEnumerable<IEnumerable<int>>, List<int>> getSucceededNodeIds =
                (currentSucceededPaths) =>
                {
                    var succeededNodeIds = new List<int>(currentSucceededPaths.Count()); // An incorrect estimate, but (micro)enhaces performance

                    foreach (var row in currentSucceededPaths)
                    {
                        succeededNodeIds = succeededNodeIds.Union(row).ToList();
                    }

                    return succeededNodeIds;
                };

            return _queryableFactory.Create<int>(
                (parameters) =>
                {
                    var idsJoined = string.Join(", ", nodeIds.Select(node => node.ToString()));

                    var graph = _cacheService.GetMonitored(_graphDescriptor, MakeCacheKey("SophisticatedAssociations.BaseGraph." + idsJoined, settings), () =>
                        {
                            var g = _graphEditor.GraphFactory<int>();
                            IList<IEnumerable<int>> succeededPaths;

                            Func<IUndirectedGraph<int, IUndirectedEdge<int>>> emptyResult = () =>  _graphEditor.GraphFactory<int>();

                            var pathFinderSettings = new PathFinderSettings { MaxDistance = settings.MaxDistance };
                            var allPairSucceededPaths = _graphDescriptor.Services.PathFinder.FindPaths(nodeList[0], nodeList[1], pathFinderSettings).SucceededPaths;

                            if (allPairSucceededPaths.Count() == 0) return emptyResult();

                            if (nodeList.Count == 2)
                            {
                                succeededPaths = allPairSucceededPaths.ToList();
                            }
                            // Calculate the routes between every nodes pair, then calculate the intersection of the routes
                            else
                            {
                                // We have to preserve the searched node ids in the succeeded paths despite the intersections
                                var searchedNodeIds = new List<int>(nodeList.Count);
                                nodeIds.ToList().ForEach(
                                        node => searchedNodeIds.Add(node)
                                    );

                                var commonSucceededNodeIds = getSucceededNodeIds(allPairSucceededPaths).Union(searchedNodeIds).ToList();

                                for (int i = 0; i < nodeList.Count - 1; i++)
                                {
                                    int n = i + 1;
                                    if (i == 0) n = 2; // Because of the calculation of intersections the first iteration is already done above

                                    while (n < nodeList.Count)
                                    {
                                        // Here could be multithreading
                                        var pairSucceededPaths = _graphDescriptor.Services.PathFinder.FindPaths(nodeList[i], nodeList[n], pathFinderSettings).SucceededPaths;
                                        commonSucceededNodeIds = commonSucceededNodeIds.Intersect(getSucceededNodeIds(pairSucceededPaths).Union(searchedNodeIds)).ToList();
                                        allPairSucceededPaths = allPairSucceededPaths.Union(pairSucceededPaths).ToList();

                                        n++;
                                    }
                                }

                                if (allPairSucceededPaths.Count() == 0 || commonSucceededNodeIds.Count == 0) return emptyResult();

                                succeededPaths = new List<IEnumerable<int>>(allPairSucceededPaths.Count()); // We are oversizing, but it's worth the performance gain

                                foreach (var path in allPairSucceededPaths)
                                {
                                    var succeededPath = path.Intersect(commonSucceededNodeIds);
                                    if (succeededPath.Count() > 2) succeededPaths.Add(succeededPath); // Only paths where intersecting nodes are present
                                }

                                if (succeededPaths.Count() == 0) return emptyResult();
                            }

                            g.AddVertexRange(getSucceededNodeIds(succeededPaths));

                            foreach (var path in succeededPaths)
                            {
                                var pathList = path.ToList();
                                for (int i = 1; i < pathList.Count; i++)
                                {
                                    var node1Id = pathList[i - 1];
                                    var node2Id = pathList[i];

                                    // Despite the graph being undirected and not allowing parallel edges, the same edges, registered with a
                                    // different order of source and dest are recognized as different edges.
                                    // See issue: http://quickgraph.codeplex.com/workitem/21805
                                    var newEdge = new UndirectedEdge<int>(node1Id, node2Id);
                                    IUndirectedEdge<int> reversedNewEdge;

                                    // It's sufficient to only check the reversed edge; if newEdge is present it will be overwritten without problems
                                    if (!g.TryGetEdge(node2Id, node1Id, out reversedNewEdge))
                                    {
                                        g.AddEdge(newEdge);
                                    }
                                }
                            }

                            return g;
                        });

                    return QueryableGraphHelper.LastStepsWithPaging(new LastStepParams
                    {
                        CacheService = _cacheService,
                        GraphEditor = _graphEditor,
                        GraphDescriptor = _graphDescriptor,
                        ExecutionParameters = parameters,
                        Graph = graph,
                        BaseCacheKey = MakeCacheKey("SophisticatedAssociations." + idsJoined, settings)
                    });
                });
        }
        public void Execute(int _SourceNodeId, int _TargetNodeId)
        {
            Console.WriteLine("Start Dijkstra");
            try
            {
                foreach (var hEdge in FUsedGraph.GetEdgeIndices())
                {
                    if (hEdge.GetWeightValue() < 0.0)
                    {
                        throw new DijkastraException("Negative Kantengewichte gefunden. Der Dijkstra-Algorithmus kann nicht mit mit negativen Werten umgehen.");
                    }
                }

                var  hNodeDictionary = FUsedGraph.GetNodeDictionary();
                var  hStartNode      = hNodeDictionary[_SourceNodeId];
                var  hTargetNode     = hNodeDictionary[_TargetNodeId];
                bool hTargetFound    = false;

                var hCostDictionary    = new Dictionary <INode, double>();
                var hParentNodeEdge    = new Dictionary <INode, Edge>(); // Speichert mit welcher Kante ein Knoten erreicht wurde
                var hNodePriorityQueue = new SimplePriorityQueue <INode, double>();
                var hVisitedNodes      = new HashSet <INode>();

                // Initialisierung
                foreach (var hNode in hNodeDictionary.Values)
                {
                    hParentNodeEdge.Add(hNode, null);
                    hCostDictionary.Add(hNode, Double.PositiveInfinity);
                }

                hNodePriorityQueue.Enqueue(hStartNode, 0.0);
                hCostDictionary[hStartNode] = 0.0;


                while (!hTargetFound)
                {
                    var hCurrentNode = hNodePriorityQueue.Dequeue();
                    hVisitedNodes.Add(hCurrentNode);

                    if (hCurrentNode == hTargetNode)
                    {
                        hTargetFound = true;
                        // break
                    }

                    foreach (var hNeighborEdge in hCurrentNode.NeighbourEdges)
                    {
                        if (!hVisitedNodes.Contains(hNeighborEdge.Node))
                        {
                            // Nachbar ist noch nicht besucht worden
                            var hTourCostToNeighbor = hCostDictionary[hCurrentNode] + hNeighborEdge.Edge.GetWeightValue();

                            // Ist der Nachbar schon in der Priority Queue drin und hab einen besseren Weg gefunden?
                            if (hNodePriorityQueue.Contains(hNeighborEdge.Node) && (hTourCostToNeighbor < hNodePriorityQueue.GetPriority(hNeighborEdge.Node)))
                            {
                                hNodePriorityQueue.UpdatePriority(hNeighborEdge.Node, hTourCostToNeighbor);
                                hParentNodeEdge[hNeighborEdge.Node] = hNeighborEdge.Edge;
                                hCostDictionary[hNeighborEdge.Node] = hTourCostToNeighbor;
                            }
                            else if (!hNodePriorityQueue.Contains(hNeighborEdge.Node))
                            {
                                // Nachbarknoten wurde noch garnicht bemerkt. Also mit den gerade gefunden Kosten in die Priority Queue
                                hNodePriorityQueue.Enqueue(hNeighborEdge.Node, hTourCostToNeighbor);
                                hParentNodeEdge[hNeighborEdge.Node] = hNeighborEdge.Edge;
                                hCostDictionary[hNeighborEdge.Node] = hTourCostToNeighbor;
                            }
                        }
                    }
                }

                // Jetzt vom Zielknonten zurück zum Startknoten ;)
                var hTmpNode           = hTargetNode;
                var hShortestPathStack = new Stack <int>();
                var hCosts             = 0.0;
                while (hTmpNode != hStartNode)
                {
                    hCosts += hParentNodeEdge[hTmpNode].GetWeightValue();
                    hShortestPathStack.Push(hTmpNode.Id);

                    // "Knoten davor"
                    if (hParentNodeEdge[hTmpNode] is DirectedEdge)
                    {
                        DirectedEdge hEdge = (DirectedEdge)hParentNodeEdge[hTmpNode];
                        hTmpNode = hEdge.GetEdgeSource();
                    }
                    else if (hParentNodeEdge[hTmpNode] is UndirectedEdge)
                    {
                        UndirectedEdge hEdge = (UndirectedEdge)hParentNodeEdge[hTmpNode];
                        hTmpNode = hParentNodeEdge[hTmpNode].GetOtherEndpoint(hTmpNode);
                    }
                }

                hShortestPathStack.Push(hStartNode.Id);

                // Ausgabe
                Console.WriteLine("Kürzeste Route:\t" + string.Join(",", hShortestPathStack));
                Console.WriteLine("Kosten:\t" + hCosts);
            }
            catch (DijkastraException ex)
            {
                Console.WriteLine(ex.Message);
            }
        }  // Execute