示例#1
0
		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);


		}
示例#2
0
        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));
        }