/// <summary> /// Initializes a new instance of the <see cref="FloydWarshallAllShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> public FloydWarshallAllShortestPathAlgorithm( IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> edgeWeights, IDistanceRelaxer distanceRelaxer) : this(null, visitedGraph, edgeWeights, distanceRelaxer) { }
/// <summary> /// Runs the relaxation algorithm on the given <paramref name="edge"/>. /// </summary> /// <param name="edge">Edge to relax.</param> /// <param name="source">Source vertex.</param> /// <param name="target">Target vertex.</param> /// <returns>True if relaxation decreased the target vertex distance, false otherwise.</returns> protected bool Relax(TEdge edge, TVertex source, TVertex target) { Debug.Assert(edge != null); Debug.Assert(source != null); Debug.Assert(target != null); Debug.Assert( (EqualityComparer <TVertex> .Default.Equals(edge.Source, source) && EqualityComparer <TVertex> .Default.Equals(edge.Target, target)) || (EqualityComparer <TVertex> .Default.Equals(edge.Source, target) && EqualityComparer <TVertex> .Default.Equals(edge.Target, source))); double du = Distances[source]; double dv = Distances[target]; double we = Weights(edge); IDistanceRelaxer relaxer = DistanceRelaxer; double duwe = relaxer.Combine(du, we); if (relaxer.Compare(duwe, dv) < 0) { Distances[target] = duwe; return(true); } return(false); }
private static void CompareSearches <TVertex, TEdge>( [NotNull] IBidirectionalGraph <TVertex, TEdge> graph, [NotNull] TVertex root, [NotNull] TVertex target) where TEdge : IEdge <TVertex> { double EdgeWeights(TEdge edge) => 1.0; IDistanceRelaxer distanceRelaxer = DistanceRelaxers.ShortestDistance; var search = new BestFirstFrontierSearchAlgorithm <TVertex, TEdge>( graph, EdgeWeights, distanceRelaxer); var recorder = new VertexDistanceRecorderObserver <TVertex, TEdge>(EdgeWeights); using (recorder.Attach(search)) search.Compute(root, target); var dijkstra = new DijkstraShortestPathAlgorithm <TVertex, TEdge>(graph, EdgeWeights, distanceRelaxer); var dijkstraRecorder = new VertexDistanceRecorderObserver <TVertex, TEdge>(EdgeWeights); using (dijkstraRecorder.Attach(dijkstra)) dijkstra.Compute(root); IDictionary <TVertex, double> bffsVerticesDistances = recorder.Distances; IDictionary <TVertex, double> dijkstraVerticesDistances = dijkstraRecorder.Distances; if (dijkstraVerticesDistances.TryGetValue(target, out double cost)) { Assert.IsTrue(bffsVerticesDistances.ContainsKey(target), $"Target {target} not found, should be {cost}."); Assert.AreEqual(dijkstraVerticesDistances[target], bffsVerticesDistances[target]); } }
/// <summary> /// Initializes a new instance of the <see cref="BestFirstFrontierSearchAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that for a given edge provide its weight.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> public BestFirstFrontierSearchAlgorithm( [NotNull] IBidirectionalIncidenceGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> edgeWeights, [NotNull] IDistanceRelaxer distanceRelaxer) : this(null, visitedGraph, edgeWeights, distanceRelaxer) { }
/// <summary> /// Initializes a new instance of the <see cref="BellmanFordShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> /// <exception cref="T:System.ArgumentNullException"><paramref name="visitedGraph"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="edgeWeights"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="distanceRelaxer"/> is <see langword="null"/>.</exception> public BellmanFordShortestPathAlgorithm( [NotNull] IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> edgeWeights, [NotNull] IDistanceRelaxer distanceRelaxer) : this(null, visitedGraph, edgeWeights, distanceRelaxer) { }
/// <summary> /// Initializes a new instance of the <see cref="HoffmanPavleyRankedShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that for a given edge provide its weight.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> /// <exception cref="T:System.ArgumentNullException"><paramref name="visitedGraph"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="edgeWeights"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="distanceRelaxer"/> is <see langword="null"/>.</exception> public HoffmanPavleyRankedShortestPathAlgorithm( [NotNull] IBidirectionalGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> edgeWeights, [NotNull] IDistanceRelaxer distanceRelaxer) : this(null, visitedGraph, edgeWeights, distanceRelaxer) { }
private static void RunSearch <TVertex, TEdge>( [NotNull] IBidirectionalGraph <TVertex, TEdge> graph) where TEdge : IEdge <TVertex> { if (graph.VertexCount == 0) { return; } IDistanceRelaxer distanceRelaxer = DistanceRelaxers.ShortestDistance; var search = new BestFirstFrontierSearchAlgorithm <TVertex, TEdge>( graph, e => 1, distanceRelaxer); TVertex root = graph.Vertices.First(); TVertex target = graph.Vertices.Last(); var recorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (recorder.Attach(search)) search.Compute(root, target); if (recorder.VertexPredecessors.ContainsKey(target)) { Assert.IsTrue(recorder.TryGetPath(target, out _)); } }
/// <summary> /// Initializes a new instance of the <see cref="UndirectedDijkstraShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> public UndirectedDijkstraShortestPathAlgorithm( IUndirectedGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> edgeWeights, IDistanceRelaxer distanceRelaxer) : this(null, visitedGraph, edgeWeights, distanceRelaxer) { }
/// <summary> /// Initializes a new instance of the <see cref="DagShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> public DagShortestPathAlgorithm( IVertexListGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> edgeWeights, IDistanceRelaxer distanceRelaxer) : this(null, visitedGraph, edgeWeights, distanceRelaxer) { }
public BellmanFordShortestPathAlgorithm( IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> weights, IDistanceRelaxer distanceRelaxer ) : this(null, visitedGraph, weights, distanceRelaxer) { }
public DagShortestPathAlgorithm( IVertexListGraph <TVertex, TEdge> g, IDictionary <TEdge, double> weights, IDistanceRelaxer distanceRelaxer ) : base(g, weights, distanceRelaxer) { }
public DijkstraShortestPathAlgorithm( IVertexListGraph <TVertex, TEdge> visitedGraph, IDictionary <TEdge, double> weights, IDistanceRelaxer distanceRelaxer ) : base(visitedGraph, weights, distanceRelaxer) { }
/// <summary> /// Initializes a new instance of the <see cref="UndirectedDijkstraShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="host">Host to use if set, otherwise use this reference.</param> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> public UndirectedDijkstraShortestPathAlgorithm( IAlgorithmComponent host, IUndirectedGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> edgeWeights, IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph, edgeWeights, distanceRelaxer) { }
public DagShortestPathAlgorithm( IVertexListGraph <TVertex, TEdge> g, Func <TEdge, double> weights, IDistanceRelaxer distanceRelaxer ) : this(null, g, weights, distanceRelaxer) { }
/// <summary> /// Initializes a new instance of the <see cref="AStarShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="costHeuristic">Function that computes a cost for a given vertex.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> /// <exception cref="T:System.ArgumentNullException"><paramref name="visitedGraph"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="edgeWeights"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="costHeuristic"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="distanceRelaxer"/> is <see langword="null"/>.</exception> public AStarShortestPathAlgorithm( [NotNull] IVertexListGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> edgeWeights, [NotNull] Func <TVertex, double> costHeuristic, [NotNull] IDistanceRelaxer distanceRelaxer) : this(null, visitedGraph, edgeWeights, costHeuristic, distanceRelaxer) { }
/// <summary> /// Initializes a new instance of the <see cref="DagShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="host">Host to use if set, otherwise use this reference.</param> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> public DagShortestPathAlgorithm( IAlgorithmComponent host, IVertexListGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> edgeWeights, IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph, edgeWeights, distanceRelaxer) { }
/// <summary> /// Initializes a new instance of the <see cref="BellmanFordShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="host">Host to use if set, otherwise use this reference.</param> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> /// <exception cref="T:System.ArgumentNullException"><paramref name="visitedGraph"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="edgeWeights"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="distanceRelaxer"/> is <see langword="null"/>.</exception> public BellmanFordShortestPathAlgorithm( [CanBeNull] IAlgorithmComponent host, [NotNull] IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> edgeWeights, [NotNull] IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph, edgeWeights, distanceRelaxer) { }
/// <summary> /// Initializes a new instance of the <see cref="RankedShortestPathAlgorithmBase{TVertex,TEdge,TGraph}"/> class. /// </summary> /// <param name="host">Host to use if set, otherwise use this reference.</param> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> protected RankedShortestPathAlgorithmBase( [CanBeNull] IAlgorithmComponent host, [NotNull] TGraph visitedGraph, [NotNull] IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph) { DistanceRelaxer = distanceRelaxer ?? throw new ArgumentNullException(nameof(distanceRelaxer)); }
public DagShortestPathAlgorithm( IAlgorithmComponent host, IVertexListGraph <TVertex, TEdge> g, Func <TEdge, double> weights, IDistanceRelaxer distanceRelaxer ) : base(host, g, weights, distanceRelaxer) { }
public AStarShortestPathAlgorithm( IVertexListGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> weights, Func <TVertex, double> costHeuristic, IDistanceRelaxer distanceRelaxer ) : this(null, visitedGraph, weights, costHeuristic, distanceRelaxer) { }
/// <summary> /// Initializes a new instance of the <see cref="HoffmanPavleyRankedShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="host">Host to use if set, otherwise use this reference.</param> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that for a given edge provide its weight.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> /// <exception cref="T:System.ArgumentNullException"><paramref name="visitedGraph"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="edgeWeights"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="distanceRelaxer"/> is <see langword="null"/>.</exception> public HoffmanPavleyRankedShortestPathAlgorithm( [CanBeNull] IAlgorithmComponent host, [NotNull] IBidirectionalGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> edgeWeights, [NotNull] IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph, distanceRelaxer) { _edgeWeights = edgeWeights ?? throw new ArgumentNullException(nameof(edgeWeights)); }
/// <summary> /// Initializes a new instance of the <see cref="VertexDistanceRecorderObserver{TVertex,TEdge}"/> class. /// </summary> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> /// <param name="distances">Distances per vertex.</param> public VertexDistanceRecorderObserver( [NotNull] Func <TEdge, double> edgeWeights, [NotNull] IDistanceRelaxer distanceRelaxer, [NotNull] IDictionary <TVertex, double> distances) { EdgeWeights = edgeWeights ?? throw new ArgumentNullException(nameof(edgeWeights)); DistanceRelaxer = distanceRelaxer ?? throw new ArgumentNullException(nameof(distanceRelaxer)); Distances = distances ?? throw new ArgumentNullException(nameof(distances)); }
/// <summary> /// Builds a new Bellman Ford searcher. /// </summary> /// <param name="g">The graph</param> /// <param name="weights">Edge weights</param> /// <exception cref="ArgumentNullException">Any argument is null</exception> /// <remarks>This algorithm uses the <seealso cref="BreadthFirstSearchAlgorithm"/>.</remarks> public BellmanFordShortestPathAlgorithm( IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph, IDictionary <TEdge, double> weights, IDistanceRelaxer distanceRelaxer ) : base(visitedGraph, weights, distanceRelaxer) { this.predecessors = new Dictionary <TVertex, TVertex>(); }
/// <summary> /// Initializes a new instance of the <see cref="ShortestPathAlgorithmBase{TVertex,TEdge,TGraph}"/> class. /// </summary> /// <param name="host">Host to use if set, otherwise use this reference.</param> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> protected ShortestPathAlgorithmBase( IAlgorithmComponent host, TGraph visitedGraph, Func <TEdge, double> edgeWeights, IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph) { Weights = edgeWeights ?? throw new ArgumentNullException(nameof(edgeWeights)); DistanceRelaxer = distanceRelaxer ?? throw new ArgumentNullException(nameof(distanceRelaxer)); }
/// <summary> /// Initializes a new instance of the <see cref="UndirectedShortestPathAlgorithmBase{TVertex,TEdge}"/> class. /// </summary> /// <param name="host">Host to use if set, otherwise use this reference.</param> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> /// <exception cref="T:System.ArgumentNullException"><paramref name="visitedGraph"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="edgeWeights"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="distanceRelaxer"/> is <see langword="null"/>.</exception> protected UndirectedShortestPathAlgorithmBase( [CanBeNull] IAlgorithmComponent host, [NotNull] IUndirectedGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> edgeWeights, [NotNull] IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph) { Weights = edgeWeights ?? throw new ArgumentNullException(nameof(edgeWeights)); DistanceRelaxer = distanceRelaxer ?? throw new ArgumentNullException(nameof(distanceRelaxer)); }
protected RankedShortestPathAlgorithmBase( IAlgorithmComponent host, TGraph visitedGraph, IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph) { Contract.Requires(distanceRelaxer != null); this.distanceRelaxer = distanceRelaxer; }
/// <summary> /// Initializes a new instance of the <see cref="BestFirstFrontierSearchAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="host">Host to use if set, otherwise use this reference.</param> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that for a given edge provide its weight.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> public BestFirstFrontierSearchAlgorithm( [CanBeNull] IAlgorithmComponent host, [NotNull] IBidirectionalIncidenceGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> edgeWeights, [NotNull] IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph) { _edgeWeights = edgeWeights ?? throw new ArgumentNullException(nameof(edgeWeights)); _distanceRelaxer = distanceRelaxer ?? throw new ArgumentNullException(nameof(distanceRelaxer)); }
/// <summary> /// Initializes a new instance of the <see cref="AStarShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="host">Host to use if set, otherwise use this reference.</param> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="costHeuristic">Function that computes a cost for a given vertex.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> /// <exception cref="T:System.ArgumentNullException"><paramref name="visitedGraph"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="edgeWeights"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="costHeuristic"/> is <see langword="null"/>.</exception> /// <exception cref="T:System.ArgumentNullException"><paramref name="distanceRelaxer"/> is <see langword="null"/>.</exception> public AStarShortestPathAlgorithm( [CanBeNull] IAlgorithmComponent host, [NotNull] IVertexListGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> edgeWeights, [NotNull] Func <TVertex, double> costHeuristic, [NotNull] IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph, edgeWeights, distanceRelaxer) { CostHeuristic = costHeuristic ?? throw new ArgumentNullException(nameof(costHeuristic)); }
public HoffmanPavleyRankedShortestPathAlgorithm( IAlgorithmComponent host, IBidirectionalGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> edgeWeights, IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph, distanceRelaxer) { Contract.Requires(edgeWeights != null); this.edgeWeights = edgeWeights; }
/// <summary> /// Initializes a new instance of the <see cref="FloydWarshallAllShortestPathAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="host">Host to use if set, otherwise use this reference.</param> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="edgeWeights">Function that computes the weight for a given edge.</param> /// <param name="distanceRelaxer">Distance relaxer.</param> public FloydWarshallAllShortestPathAlgorithm( [CanBeNull] IAlgorithmComponent host, [NotNull] IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> edgeWeights, [NotNull] IDistanceRelaxer distanceRelaxer) : base(host, visitedGraph) { _weights = edgeWeights ?? throw new ArgumentNullException(nameof(edgeWeights)); _distanceRelaxer = distanceRelaxer ?? throw new ArgumentNullException(nameof(distanceRelaxer)); _data = new Dictionary <SEquatableEdge <TVertex>, VertexData>(); }
private void Search( IVertexListGraph<string, Edge<string>> g, string root, IDistanceRelaxer relaxer) { DagShortestPathAlgorithm<string, Edge<string>> algo = new DagShortestPathAlgorithm<string, Edge<string>>( g, DagShortestPathAlgorithm<string, Edge<string>>.UnaryWeightsFromVertexList(g), relaxer ); VertexPredecessorRecorderObserver<string, Edge<string>> predecessors = new VertexPredecessorRecorderObserver<string, Edge<string>>(); predecessors.Attach(algo); algo.Compute(root); Verify(algo, predecessors); }