private Tuple<double, List<Tuple<long, long>>, IVertexType, IVertexType> ShortPath(IVertexType start, IVertexType end) { #region initialization var currentVertex = start; List<UInt64> depthBuffer = new List<UInt64>(); List<long> edgeBuffer = new List<long>(); List<double> distanceBuffer = new List<double>(); List<IVertexType> VertexBuffer = new List<IVertexType>(); BufferForFindPathSchema buf = new BufferForFindPathSchema(); DataForFindPathSchema lists = new DataForFindPathSchema(); buf.Add(start, 0, 0); lists.Add(start, 0, 0, 0, start); bool endVertexFlag = false; #endregion #region Dijkstra algorithm double current_distance = 1; double currentVertexDistance = 0; ulong currentVertexDepth = 0; double endVertexDistance = 0; ulong endvertexDepth = 0; Stopwatch clock = new Stopwatch(); clock.Start(); while (buf.Count != 0) { var hyperEdgeOut = currentVertex.GetOutgoingEdgeDefinitions(true); var hyperEdgeInc = currentVertex.GetIncomingEdgeDefinitions(true); if (hyperEdgeOut != null || hyperEdgeInc != null) { for (int iCount = 0; iCount < hyperEdgeOut.Count(); iCount++) { var TargetVertexType = hyperEdgeOut.ElementAt(iCount).TargetVertexType; var current_Edge = hyperEdgeOut.ElementAt(iCount).ID; var TargetVertexID = lists.GetElement(TargetVertexType.ID); if (TargetVertexID == null) { if (!endVertexFlag) { buf.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } else { if (currentVertexDistance + current_distance < TargetVertexID.Item2) { if (!endVertexFlag) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } else if (currentVertexDistance + current_distance == TargetVertexID.Item2 && currentVertexDepth + 1 < TargetVertexID.Item3) { if (!endVertexFlag) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } } if (TargetVertexType == end) { endVertexFlag = true; var endNode = lists.GetElement(end.ID); endVertexDistance = endNode.Item2; endvertexDepth = endNode.Item3; } } for (int iCount = 0; iCount < hyperEdgeInc.Count(); iCount++) { var TargetVertexType = hyperEdgeInc.ElementAt(iCount).RelatedEdgeDefinition.SourceVertexType; var current_Edge = hyperEdgeInc.ElementAt(iCount).ID;//.RelatedEdgeDefinition.EdgeType; var TargetVertexID = lists.GetElement(TargetVertexType.ID); if (TargetVertexID == null) { if (!endVertexFlag) { buf.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } else { if (currentVertexDistance + current_distance < TargetVertexID.Item2) { if (!endVertexFlag) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } else if (currentVertexDistance + current_distance == TargetVertexID.Item2 && currentVertexDepth + 1 < TargetVertexID.Item3) { if (!endVertexFlag) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } } if (TargetVertexType == end) { endVertexFlag = true; var endNode = lists.GetElement(end.ID); endVertexDistance = endNode.Item2; endvertexDepth = endNode.Item3; } } } //delate from Buffer current Vertex or all if (currentVertex == end) { buf.Clear(); } else { buf.Remove(currentVertexDistance, currentVertex.ID); } //Minimum distance from Buffer if (buf.Count != 0) { var minVertex = buf.Min(); currentVertex = minVertex.Item1; currentVertexDistance = minVertex.Item2; currentVertexDepth = minVertex.Item3; } } #endregion #region create output List<Tuple<long, long>> parents = new List<Tuple<long, long>>(); currentVertex = end; while (currentVertex != start) { var current_tuple = lists.GetElement(currentVertex.ID); if (current_tuple == null) return null; VertexBuffer.Add(currentVertex); distanceBuffer.Add(current_tuple.Item2); depthBuffer.Add(current_tuple.Item3); edgeBuffer.Add(current_tuple.Item4); parents.Add(Tuple.Create(currentVertex.ID, current_tuple.Item4)); currentVertex = current_tuple.Item5; } parents.Add(Tuple.Create(start.ID, 0L)); return Tuple.Create(distanceBuffer.First(), parents, start, end); }
private Tuple <double, List <Tuple <long, long> >, IVertexType, IVertexType> ShortPath(IVertexType start, IVertexType end) { #region initialization var currentVertex = start; List <UInt64> depthBuffer = new List <UInt64>(); List <long> edgeBuffer = new List <long>(); List <double> distanceBuffer = new List <double>(); List <IVertexType> VertexBuffer = new List <IVertexType>(); BufferForFindPathSchema buf = new BufferForFindPathSchema(); DataForFindPathSchema lists = new DataForFindPathSchema(); buf.Add(start, 0, 0); lists.Add(start, 0, 0, 0, start); bool endVertexFlag = false; #endregion #region Dijkstra algorithm double current_distance = 1; double currentVertexDistance = 0; ulong currentVertexDepth = 0; double endVertexDistance = 0; ulong endvertexDepth = 0; Stopwatch clock = new Stopwatch(); clock.Start(); while (buf.Count != 0) { var hyperEdgeOut = currentVertex.GetOutgoingEdgeDefinitions(true); var hyperEdgeInc = currentVertex.GetIncomingEdgeDefinitions(true); if (hyperEdgeOut != null || hyperEdgeInc != null) { for (int iCount = 0; iCount < hyperEdgeOut.Count(); iCount++) { var TargetVertexType = hyperEdgeOut.ElementAt(iCount).TargetVertexType; var current_Edge = hyperEdgeOut.ElementAt(iCount).ID; var TargetVertexID = lists.GetElement(TargetVertexType.ID); if (TargetVertexID == null) { if (!endVertexFlag) { buf.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } else { if (currentVertexDistance + current_distance < TargetVertexID.Item2) { if (!endVertexFlag) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } else if (currentVertexDistance + current_distance == TargetVertexID.Item2 && currentVertexDepth + 1 < TargetVertexID.Item3) { if (!endVertexFlag) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } } if (TargetVertexType == end) { endVertexFlag = true; var endNode = lists.GetElement(end.ID); endVertexDistance = endNode.Item2; endvertexDepth = endNode.Item3; } } for (int iCount = 0; iCount < hyperEdgeInc.Count(); iCount++) { var TargetVertexType = hyperEdgeInc.ElementAt(iCount).RelatedEdgeDefinition.SourceVertexType; var current_Edge = hyperEdgeInc.ElementAt(iCount).ID; //.RelatedEdgeDefinition.EdgeType; var TargetVertexID = lists.GetElement(TargetVertexType.ID); if (TargetVertexID == null) { if (!endVertexFlag) { buf.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Add(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } else { if (currentVertexDistance + current_distance < TargetVertexID.Item2) { if (!endVertexFlag) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } else if (currentVertexDistance + current_distance == TargetVertexID.Item2 && currentVertexDepth + 1 < TargetVertexID.Item3) { if (!endVertexFlag) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } else if (endVertexDistance > currentVertexDistance + current_distance || (endVertexDistance == currentVertexDistance + current_distance && endvertexDepth > currentVertexDepth + 1)) { buf.Set(TargetVertexID.Item2, TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1); lists.Set(TargetVertexType, current_distance + currentVertexDistance, currentVertexDepth + 1, current_Edge, currentVertex); } } } if (TargetVertexType == end) { endVertexFlag = true; var endNode = lists.GetElement(end.ID); endVertexDistance = endNode.Item2; endvertexDepth = endNode.Item3; } } } //delate from Buffer current Vertex or all if (currentVertex == end) { buf.Clear(); } else { buf.Remove(currentVertexDistance, currentVertex.ID); } //Minimum distance from Buffer if (buf.Count != 0) { var minVertex = buf.Min(); currentVertex = minVertex.Item1; currentVertexDistance = minVertex.Item2; currentVertexDepth = minVertex.Item3; } } #endregion #region create output List <Tuple <long, long> > parents = new List <Tuple <long, long> >(); currentVertex = end; while (currentVertex != start) { var current_tuple = lists.GetElement(currentVertex.ID); if (current_tuple == null) { return(null); } VertexBuffer.Add(currentVertex); distanceBuffer.Add(current_tuple.Item2); depthBuffer.Add(current_tuple.Item3); edgeBuffer.Add(current_tuple.Item4); parents.Add(Tuple.Create(currentVertex.ID, current_tuple.Item4)); currentVertex = current_tuple.Item5; } parents.Add(Tuple.Create(start.ID, 0L)); return(Tuple.Create(distanceBuffer.First(), parents, start, end)); }