Skip to content

Commit

Permalink
add more readme for shortest path algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
hmdsefi committed Feb 17, 2024
1 parent 0e0dbe6 commit 416a11f
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
25 changes: 25 additions & 0 deletions path/bellman-ford.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,29 @@ The Bellman-Ford algorithm is a graph algorithm used to find the shortest path f
vertices in a weighted graph, even in the presence of negative weight edges (as long as there are no negative weight
cycles). It was developed by Richard Bellman and Lester Ford Jr.

Here's a step-by-step explanation of how the Bellman-Ford algorithm works:

1. **Initialization:** Start by setting the distance of the source vertex to itself as 0,
and the distance of all other vertices to infinity.

2. **Relaxation:** Iterate through all edges in the graph |V| - 1 times, where |V| is
the number of vertices. In each iteration, attempt to improve the shortest path estimates
for all vertices. This is done by relaxing each edge: if the distance to the destination
vertex through the current edge is shorter than the current estimate, update the estimate with the shorter distance.

3. **Detection of Negative Cycles:** After the |V| - 1 iterations, perform an additional iteration.
If during this iteration, any of the distances are further reduced, it indicates the presence of a
negative weight cycle in the graph. This is because if a vertex's distance can still be improved
after |V| - 1 iterations, it means there's a negative weight cycle that can be traversed indefinitely
to reduce the distance further.

4. **Output:** If there is no negative weight cycle, the algorithm outputs the shortest path
distances from the source vertex to all other vertices. If there is a negative weight cycle,
the algorithm typically returns an indication of this fact.

The time complexity of the Bellman-Ford algorithm is O(V*E), where V is the number of vertices and E
is the number of edges. This makes it less efficient than algorithms like Dijkstra's algorithm for
graphs with non-negative edge weights, but its ability to handle negative weight edges (as long as
there are no negative weight cycles) makes it useful in certain scenarios.


56 changes: 56 additions & 0 deletions path/dijkstra.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# gograph
## Shortest Path
### Bellman-Ford
Dijkstra's algorithm is a graph algorithm used to find the shortest path from a single source vertex to all
other vertices in a weighted graph with non-negative edge weights. It was developed by Dutch computer scientist
Edsger W. Dijkstra in 1956.

Here's a step-by-step explanation of how Dijkstra's algorithm works:

1. **Initialization:** Start by selecting a source vertex. Set the distance of the source vertex to itself as 0, and the
distances of all other vertices to infinity. Maintain a priority queue (or a min-heap) to keep track of vertices
based on their tentative distances from the source vertex.

2. **Selection of Vertex:** At each step, select the vertex with the smallest tentative distance from the priority queue.
Initially, this will be the source vertex.

3. **Relaxation:** For the selected vertex, iterate through all its neighboring vertices. For each neighboring vertex,
update its tentative distance if going through the current vertex results in a shorter path than the current
known distance. If the tentative distance is updated, update the priority queue accordingly.

4. **Repeating Steps:** Repeat steps 2 and 3 until all vertices have been visited or until the priority queue is empty.

5. **Output:** After the algorithm terminates, the distances from the source vertex to all other vertices will be finalized.

Dijkstra's algorithm guarantees the shortest path from the source vertex to all other vertices in the graph,
as long as the graph does not contain negative weight edges. It works efficiently for sparse graphs with
non-negative edge weights.

The time complexity of Dijkstra's algorithm is O((V + E) log V), where V is the number of vertices and E is
the number of edges in the graph. This complexity arises from the use of a priority queue to maintain the tentative
distances efficiently. If a simple array-based implementation is used to select the minimum distance vertex in each
step, the time complexity becomes O(V^2), which is more suitable for dense graphs.

#### Implementation with Slices
Steps:
1. Initialize distances with maximum float/integer values except for the source vertex distance, which is set to 0.
2. Iterate numVertices - 1 times (where numVertices is the number of vertices in the graph).
3. Select the vertex with the minimum distance among the unvisited vertices.
4. Relax the distances of its neighboring vertices if a shorter path is found.
5. Mark the selected vertex as visited.

**Time Complexity:** O(V^2), where V is the number of vertices in the graph. This is because finding the
minimum distance vertex in each iteration takes O(V) time, and we perform this process V times.
**Space Complexity:** O(V^2) for storing the graph and distances.

#### Implementation with Heap
Steps:
* Similar to the slice implementation but instead of linearly searching for the vertex with the minimum distance,
we use a heap to maintain the priority queue.
* The priority queue ensures that the vertex with the smallest tentative distance is efficiently selected
in each iteration.

**Time Complexity:** O((V + E) log V), where V is the number of vertices and E is the number of edges in
the graph. This is because each vertex is pushed and popped from the priority queue once, and each
edge is relaxed once.
**Space Complexity:** O(V) for storing the priority queue and distances.
29 changes: 29 additions & 0 deletions path/floyd-warshall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# gograph
## Shortest Path
### Floyd-Warshall
The Floyd-Warshall algorithm is a dynamic programming algorithm used to find the shortest paths between
all pairs of vertices in a weighted graph, even in the presence of negative weight edges (as long as there
are no negative weight cycles). It was proposed by Robert Floyd and Stephen Warshall.

Here's a step-by-step explanation of how the Floyd-Warshall algorithm works:

1. **Initialization:** Create a distance matrix `D[][]` where `D[i][j]` represents the shortest distance between
vertex i and vertex j. Initialize this matrix with the weights of the edges between vertices if there
is an edge, otherwise set the value to infinity. Also, set the diagonal elements `D[i][i]` to 0.

2. **Shortest Path Calculation:** Iterate through all vertices as intermediate vertices. For each pair of
vertices (i, j), check if going through the current intermediate vertex k leads to a shorter path than
the current known distance from i to j. If so, update the distance matrix `D[i][j]` to the new shorter
distance `D[i][k] + D[k][j]`.

3. **Detection of Negative Cycles:** After the iterations, if any diagonal element `D[i][i]` of the distance
matrix is negative, it indicates the presence of a negative weight cycle in the graph.

4. **Output:** The resulting distance matrix `D[][]` will contain the shortest path distances between all
pairs of vertices. If there is a negative weight cycle, it might not produce the correct shortest paths,
but it can still detect the presence of such cycles.

The time complexity of the Floyd-Warshall algorithm is O(V^3), where V is the number of vertices in the graph.
Despite its cubic time complexity, it is often preferred over other algorithms like Bellman-Ford for dense
graphs or when the graph has negative weight edges and no negative weight cycles, as it calculates shortest
paths between all pairs of vertices in one go.

0 comments on commit 416a11f

Please sign in to comment.