diff --git a/path/bellman-ford.md b/path/bellman-ford.md index 85f0e8b..625ec72 100644 --- a/path/bellman-ford.md +++ b/path/bellman-ford.md @@ -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. + diff --git a/path/dijkstra.md b/path/dijkstra.md new file mode 100644 index 0000000..fe2a0f1 --- /dev/null +++ b/path/dijkstra.md @@ -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. diff --git a/path/floyd-warshall.md b/path/floyd-warshall.md new file mode 100644 index 0000000..52b6afc --- /dev/null +++ b/path/floyd-warshall.md @@ -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. \ No newline at end of file