Advertisement
Guest User

UndirectedAStarShortestPathAlgorithm

a guest
Mar 27th, 2014
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.28 KB | None | 0 0
  1. public sealed class UndirectedAStarShortestPathAlgorithm<TVertex, TEdge>
  2.     : UndirectedShortestPathAlgorithmBase<TVertex, TEdge>
  3.     , IVertexColorizerAlgorithm<TVertex, TEdge>
  4.     , IVertexPredecessorRecorderAlgorithm<TVertex, TEdge>
  5.     , IDistanceRecorderAlgorithm<TVertex, TEdge>
  6.     where TEdge : IEdge<TVertex>
  7. {
  8.     private FibonacciQueue<TVertex, double> vertexQueue;
  9.     private Dictionary<TVertex, double> costs;
  10.     private readonly Func<TVertex, double> costHeuristic;
  11.  
  12.     public UndirectedAStarShortestPathAlgorithm(
  13.         IUndirectedGraph<TVertex, TEdge> visitedGraph,
  14.         Func<TEdge, double> weights,
  15.         Func<TVertex, double> costHeuristic
  16.         )
  17.         : this(visitedGraph, weights, costHeuristic, DistanceRelaxers.ShortestDistance)
  18.     { }
  19.  
  20.     public UndirectedAStarShortestPathAlgorithm(
  21.         IUndirectedGraph<TVertex, TEdge> visitedGraph,
  22.         Func<TEdge, double> weights,
  23.         Func<TVertex, double> costHeuristic,
  24.         IDistanceRelaxer distanceRelaxer
  25.         )
  26.         : this(null, visitedGraph, weights, costHeuristic, distanceRelaxer)
  27.     { }
  28.  
  29.     public UndirectedAStarShortestPathAlgorithm(
  30.         IAlgorithmComponent host,
  31.         IUndirectedGraph<TVertex, TEdge> visitedGraph,
  32.         Func<TEdge, double> weights,
  33.         Func<TVertex, double> costHeuristic,
  34.         IDistanceRelaxer distanceRelaxer
  35.         )
  36.         : base(host, visitedGraph, weights, distanceRelaxer)
  37.     {
  38.         Contract.Requires(costHeuristic != null);
  39.  
  40.         this.costHeuristic = costHeuristic;
  41.     }
  42.  
  43.     public Func<TVertex, double> CostHeuristic
  44.     {
  45.         get { return this.costHeuristic; }
  46.     }
  47.  
  48.     public event VertexAction<TVertex> InitializeVertex;
  49.     public event VertexAction<TVertex> DiscoverVertex;
  50.     public event VertexAction<TVertex> StartVertex;
  51.     public event VertexAction<TVertex> ExamineVertex;
  52.     public event EdgeAction<TVertex, TEdge> ExamineEdge;
  53.     public event VertexAction<TVertex> FinishVertex;
  54.  
  55.     public event EdgeAction<TVertex, TEdge> EdgeNotRelaxed;
  56.     private void OnEdgeNotRelaxed(TEdge e)
  57.     {
  58.         var eh = this.EdgeNotRelaxed;
  59.         if (eh != null)
  60.             eh(e);
  61.     }
  62.  
  63.     private void InternalExamineEdge(TEdge args)
  64.     {
  65.         if (this.Weights(args) < 0)
  66.             throw new NegativeWeightException();
  67.     }
  68.  
  69.     private bool Relax(UndirectedEdgeEventArgs<TVertex, TEdge> e)
  70.     {
  71.         if (e.Reversed)
  72.         {
  73.             return Relax(e.Edge, e.Target, e.Source);
  74.         }
  75.         return Relax(e.Edge, e.Source, e.Target);
  76.     }
  77.  
  78.     private void InternalTreeEdge(object sender, UndirectedEdgeEventArgs<TVertex, TEdge> e)
  79.     {
  80.         bool decreased = Relax(e);
  81.         if (decreased)
  82.         {
  83.             this.OnTreeEdge(e.Edge, e.Reversed);
  84.         }
  85.         else
  86.             this.OnEdgeNotRelaxed(e.Edge);
  87.     }
  88.  
  89.     private void InternalGrayTarget(object sender, UndirectedEdgeEventArgs<TVertex, TEdge> e)
  90.     {
  91.         var target = e.Target;
  92.  
  93.         bool decreased = Relax(e);
  94.         double distance = this.Distances[target];
  95.         if (decreased)
  96.         {
  97.             this.costs[target] = this.DistanceRelaxer.Combine(distance, this.costHeuristic(target));
  98.             this.vertexQueue.Update(target);
  99.             this.OnTreeEdge(e.Edge, e.Reversed);
  100.         }
  101.         else
  102.         {
  103.             this.OnEdgeNotRelaxed(e.Edge);
  104.         }
  105.     }
  106.  
  107.     private void InternalBlackTarget(object sender, UndirectedEdgeEventArgs<TVertex, TEdge> e)
  108.     {
  109.         var target = e.Target;
  110.  
  111.         bool decreased = Relax(e);
  112.         double distance = this.Distances[target];
  113.         if (decreased)
  114.         {
  115.             this.OnTreeEdge(e.Edge, e.Reversed);
  116.             this.costs[target] = this.DistanceRelaxer.Combine(distance, this.costHeuristic(target));
  117.             this.vertexQueue.Enqueue(target);
  118.             this.VertexColors[target] = GraphColor.Gray;
  119.         }
  120.         else
  121.         {
  122.             this.OnEdgeNotRelaxed(e.Edge);
  123.         }
  124.     }
  125.  
  126.     protected override void Initialize()
  127.     {
  128.         base.Initialize();
  129.  
  130.         this.VertexColors.Clear();
  131.         this.costs = new Dictionary<TVertex, double>(this.VisitedGraph.VertexCount);
  132.         // init color, distance
  133.         var initialDistance = this.DistanceRelaxer.InitialDistance;
  134.         foreach (var u in VisitedGraph.Vertices)
  135.         {
  136.             this.VertexColors.Add(u, GraphColor.White);
  137.             this.Distances.Add(u, initialDistance);
  138.             this.costs.Add(u, initialDistance);
  139.         }
  140.         this.vertexQueue = new FibonacciQueue<TVertex, double>(this.costs, this.DistanceRelaxer.Compare);
  141.     }
  142.  
  143.     protected override void InternalCompute()
  144.     {
  145.         TVertex rootVertex;
  146.         if (this.TryGetRootVertex(out rootVertex))
  147.             this.ComputeFromRoot(rootVertex);
  148.         else
  149.         {
  150.             foreach (var v in this.VisitedGraph.Vertices)
  151.                 if (this.VertexColors[v] == GraphColor.White)
  152.                     this.ComputeFromRoot(v);
  153.         }
  154.     }
  155.  
  156.     private void ComputeFromRoot(TVertex rootVertex)
  157.     {
  158.         Contract.Requires(rootVertex != null);
  159.         Contract.Requires(this.VisitedGraph.ContainsVertex(rootVertex));
  160.         Contract.Requires(this.VertexColors[rootVertex] == GraphColor.White);
  161.  
  162.         this.VertexColors[rootVertex] = GraphColor.Gray;
  163.         this.Distances[rootVertex] = 0;
  164.         this.ComputeNoInit(rootVertex);
  165.     }
  166.  
  167.     public void ComputeNoInit(TVertex s)
  168.     {
  169.         UndirectedBreadthFirstSearchAlgorithm<TVertex, TEdge> bfs = null;
  170.  
  171.         try
  172.         {
  173.             bfs = new UndirectedBreadthFirstSearchAlgorithm<TVertex, TEdge>(
  174.                 this,
  175.                 this.VisitedGraph,
  176.                 this.vertexQueue,
  177.                 VertexColors
  178.                 );
  179.  
  180.             bfs.InitializeVertex += this.InitializeVertex;
  181.             bfs.DiscoverVertex += this.DiscoverVertex;
  182.             bfs.StartVertex += this.StartVertex;
  183.             bfs.ExamineEdge += this.ExamineEdge;
  184.             bfs.ExamineVertex += this.ExamineVertex;
  185.             bfs.FinishVertex += this.FinishVertex;
  186.  
  187.             bfs.ExamineEdge += new EdgeAction<TVertex, TEdge>(this.InternalExamineEdge);
  188.             bfs.TreeEdge += new UndirectedEdgeAction<TVertex, TEdge>(this.InternalTreeEdge);
  189.             bfs.GrayTarget += new UndirectedEdgeAction<TVertex, TEdge>(this.InternalGrayTarget);
  190.             bfs.BlackTarget += new UndirectedEdgeAction<TVertex, TEdge>(this.InternalBlackTarget);
  191.  
  192.             bfs.Visit(s);
  193.         }
  194.         finally
  195.         {
  196.             if (bfs != null)
  197.             {
  198.                 bfs.InitializeVertex -= this.InitializeVertex;
  199.                 bfs.DiscoverVertex -= this.DiscoverVertex;
  200.                 bfs.StartVertex -= this.StartVertex;
  201.                 bfs.ExamineEdge -= this.ExamineEdge;
  202.                 bfs.ExamineVertex -= this.ExamineVertex;
  203.                 bfs.FinishVertex -= this.FinishVertex;
  204.  
  205.                 bfs.ExamineEdge -= new EdgeAction<TVertex, TEdge>(this.InternalExamineEdge);
  206.                 bfs.TreeEdge -= new UndirectedEdgeAction<TVertex, TEdge>(this.InternalTreeEdge);
  207.                 bfs.GrayTarget -= new UndirectedEdgeAction<TVertex, TEdge>(this.InternalGrayTarget);
  208.                 bfs.BlackTarget -= new UndirectedEdgeAction<TVertex, TEdge>(this.InternalBlackTarget);
  209.             }
  210.         }
  211.     }
  212.  
  213.     public event EdgeAction<TVertex, TEdge> TreeEdge;
  214. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement