2 using System.Collections.Generic;
5 using System.Threading.Tasks;
59 public Func<Arc, double>
Cost {
get;
private set; }
68 private readonly Dictionary<Node, double> distance;
69 private readonly Dictionary<Node, Arc> parentArc;
70 private readonly PriorityQueue<Node, double> priorityQueue;
82 distance =
new Dictionary<Node, double>();
83 parentArc =
new Dictionary<Node, Arc>();
84 priorityQueue =
new PriorityQueue<Node, double>();
87 private void ValidateCost(
double c)
90 throw new InvalidOperationException(
"Invalid cost: " + c);
108 if (
Reached(node))
throw new InvalidOperationException(
"Cannot add a reached node as a source.");
109 ValidateCost(nodeCost);
112 priorityQueue[node] = nodeCost;
124 Node min = priorityQueue.Peek(out minDist);
127 if (
double.IsPositiveInfinity(minDist))
return Node.
Invalid;
128 distance[min] = minDist;
134 if (
Fixed(other))
continue;
136 double arcCost =
Cost(arc);
137 ValidateCost(arcCost);
138 double newDist = (
Mode ==
DijkstraMode.Sum ? minDist + arcCost : Math.Max(minDist, arcCost));
141 if (!priorityQueue.TryGetPriority(other, out oldDist)) oldDist =
double.PositiveInfinity;
143 if (newDist < oldDist)
145 priorityQueue[other] = newDist;
146 parentArc[other] = arc;
164 if (
Fixed(target))
return target;
168 if (fixedNode ==
Node.
Invalid || fixedNode == target)
return fixedNode;
181 if (fixedNode ==
Node.
Invalid || isTarget(fixedNode))
return fixedNode;
189 return parentArc.ContainsKey(node);
194 public IEnumerable<Node>
ReachedNodes {
get {
return parentArc.Keys; } }
206 return distance.ContainsKey(node);
211 public IEnumerable<Node>
FixedNodes {
get {
return distance.Keys; } }
219 return distance.TryGetValue(node, out result) ? result :
double.PositiveInfinity;
227 return parentArc.TryGetValue(node, out result) ? result :
Arc.
Invalid;
234 if (!
Reached(node))
return null;
242 result.AddFirst(arc);
243 node =
Graph.Other(arc, node);