-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Incoming features from graph algorithms
- Loading branch information
1 parent
fbccf56
commit dfa5632
Showing
32 changed files
with
2,338 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Bellman–Ford Algorithm | ||
|
||
The Bellman–Ford algorithm is an algorithm that computes shortest | ||
paths from a single source vertex to all of the other vertices | ||
in a weighted digraph. It is slower than Dijkstra's algorithm | ||
for the same problem, but more versatile, as it is capable of | ||
handling graphs in which some of the edge weights are negative | ||
numbers. | ||
|
||
![Bellman-Ford](https://upload.wikimedia.org/wikipedia/commons/2/2e/Shortest_path_Dijkstra_vs_BellmanFord.gif) | ||
|
||
## Complexity | ||
|
||
Worst-case performance `O(|V||E|)` | ||
Best-case performance `O(|E|)` | ||
Worst-case space complexity `O(|V|)` | ||
|
||
## References | ||
|
||
- [Wikipedia](https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm) | ||
- [On YouTube by Michael Sambol](https://www.youtube.com/watch?v=obWXjtg0L64&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import GraphVertex from '../../../../data-structures/graph/GraphVertex'; | ||
import GraphEdge from '../../../../data-structures/graph/GraphEdge'; | ||
import Graph from '../../../../data-structures/graph/Graph'; | ||
import bellmanFord from '../bellmanFord'; | ||
|
||
describe('bellmanFord', () => { | ||
it('should find minimum paths to all vertices for undirected graph', () => { | ||
const vertexA = new GraphVertex('A'); | ||
const vertexB = new GraphVertex('B'); | ||
const vertexC = new GraphVertex('C'); | ||
const vertexD = new GraphVertex('D'); | ||
const vertexE = new GraphVertex('E'); | ||
const vertexF = new GraphVertex('F'); | ||
const vertexG = new GraphVertex('G'); | ||
const vertexH = new GraphVertex('H'); | ||
|
||
const edgeAB = new GraphEdge(vertexA, vertexB, 4); | ||
const edgeAE = new GraphEdge(vertexA, vertexE, 7); | ||
const edgeAC = new GraphEdge(vertexA, vertexC, 3); | ||
const edgeBC = new GraphEdge(vertexB, vertexC, 6); | ||
const edgeBD = new GraphEdge(vertexB, vertexD, 5); | ||
const edgeEC = new GraphEdge(vertexE, vertexC, 8); | ||
const edgeED = new GraphEdge(vertexE, vertexD, 2); | ||
const edgeDC = new GraphEdge(vertexD, vertexC, 11); | ||
const edgeDG = new GraphEdge(vertexD, vertexG, 10); | ||
const edgeDF = new GraphEdge(vertexD, vertexF, 2); | ||
const edgeFG = new GraphEdge(vertexF, vertexG, 3); | ||
const edgeEG = new GraphEdge(vertexE, vertexG, 5); | ||
|
||
const graph = new Graph(); | ||
graph | ||
.addVertex(vertexH) | ||
.addEdge(edgeAB) | ||
.addEdge(edgeAE) | ||
.addEdge(edgeAC) | ||
.addEdge(edgeBC) | ||
.addEdge(edgeBD) | ||
.addEdge(edgeEC) | ||
.addEdge(edgeED) | ||
.addEdge(edgeDC) | ||
.addEdge(edgeDG) | ||
.addEdge(edgeDF) | ||
.addEdge(edgeFG) | ||
.addEdge(edgeEG); | ||
|
||
const { distances, previousVertices } = bellmanFord(graph, vertexA); | ||
|
||
expect(distances).toEqual({ | ||
H: Infinity, | ||
A: 0, | ||
B: 4, | ||
E: 7, | ||
C: 3, | ||
D: 9, | ||
G: 12, | ||
F: 11, | ||
}); | ||
|
||
expect(previousVertices.F.getKey()).toBe('D'); | ||
expect(previousVertices.D.getKey()).toBe('B'); | ||
expect(previousVertices.B.getKey()).toBe('A'); | ||
expect(previousVertices.G.getKey()).toBe('E'); | ||
expect(previousVertices.C.getKey()).toBe('A'); | ||
expect(previousVertices.A).toBeNull(); | ||
expect(previousVertices.H).toBeNull(); | ||
}); | ||
|
||
it('should find minimum paths to all vertices for directed graph with negative edge weights', () => { | ||
const vertexS = new GraphVertex('S'); | ||
const vertexE = new GraphVertex('E'); | ||
const vertexA = new GraphVertex('A'); | ||
const vertexD = new GraphVertex('D'); | ||
const vertexB = new GraphVertex('B'); | ||
const vertexC = new GraphVertex('C'); | ||
const vertexH = new GraphVertex('H'); | ||
|
||
const edgeSE = new GraphEdge(vertexS, vertexE, 8); | ||
const edgeSA = new GraphEdge(vertexS, vertexA, 10); | ||
const edgeED = new GraphEdge(vertexE, vertexD, 1); | ||
const edgeDA = new GraphEdge(vertexD, vertexA, -4); | ||
const edgeDC = new GraphEdge(vertexD, vertexC, -1); | ||
const edgeAC = new GraphEdge(vertexA, vertexC, 2); | ||
const edgeCB = new GraphEdge(vertexC, vertexB, -2); | ||
const edgeBA = new GraphEdge(vertexB, vertexA, 1); | ||
|
||
const graph = new Graph(true); | ||
graph | ||
.addVertex(vertexH) | ||
.addEdge(edgeSE) | ||
.addEdge(edgeSA) | ||
.addEdge(edgeED) | ||
.addEdge(edgeDA) | ||
.addEdge(edgeDC) | ||
.addEdge(edgeAC) | ||
.addEdge(edgeCB) | ||
.addEdge(edgeBA); | ||
|
||
const { distances, previousVertices } = bellmanFord(graph, vertexS); | ||
|
||
expect(distances).toEqual({ | ||
H: Infinity, | ||
S: 0, | ||
A: 5, | ||
B: 5, | ||
C: 7, | ||
D: 9, | ||
E: 8, | ||
}); | ||
|
||
expect(previousVertices.H).toBeNull(); | ||
expect(previousVertices.S).toBeNull(); | ||
expect(previousVertices.B.getKey()).toBe('C'); | ||
expect(previousVertices.C.getKey()).toBe('A'); | ||
expect(previousVertices.A.getKey()).toBe('D'); | ||
expect(previousVertices.D.getKey()).toBe('E'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* @param {Graph} graph | ||
* @param {GraphVertex} startVertex | ||
* @return {{distances, previousVertices}} | ||
*/ | ||
export default function bellmanFord(graph, startVertex) { | ||
const distances = {}; | ||
const previousVertices = {}; | ||
|
||
// Init all distances with infinity assuming that currently we can't reach | ||
// any of the vertices except start one. | ||
distances[startVertex.getKey()] = 0; | ||
graph.getAllVertices().forEach((vertex) => { | ||
previousVertices[vertex.getKey()] = null; | ||
if (vertex.getKey() !== startVertex.getKey()) { | ||
distances[vertex.getKey()] = Infinity; | ||
} | ||
}); | ||
|
||
// We need (|V| - 1) iterations. | ||
for (let iteration = 0; iteration < (graph.getAllVertices().length - 1); iteration += 1) { | ||
// During each iteration go through all vertices. | ||
Object.keys(distances).forEach((vertexKey) => { | ||
const vertex = graph.getVertexByKey(vertexKey); | ||
|
||
// Go through all vertex edges. | ||
graph.getNeighbors(vertex).forEach((neighbor) => { | ||
const edge = graph.findEdge(vertex, neighbor); | ||
// Find out if the distance to the neighbor is shorter in this iteration | ||
// then in previous one. | ||
const distanceToVertex = distances[vertex.getKey()]; | ||
const distanceToNeighbor = distanceToVertex + edge.weight; | ||
if (distanceToNeighbor < distances[neighbor.getKey()]) { | ||
distances[neighbor.getKey()] = distanceToNeighbor; | ||
previousVertices[neighbor.getKey()] = vertex; | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
return { | ||
distances, | ||
previousVertices, | ||
}; | ||
} |
This file was deleted.
Oops, something went wrong.
36 changes: 0 additions & 36 deletions
36
algorithms/detect-cycle/__test__/detectUndirectedCycleUsingDisjointSet.test.js
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Dijkstra's Algorithm | ||
|
||
Dijkstra's algorithm is an algorithm for finding the shortest | ||
paths between nodes in a graph, which may represent, for example, | ||
road networks. | ||
|
||
The algorithm exists in many variants; Dijkstra's original variant | ||
found the shortest path between two nodes, but a more common | ||
variant fixes a single node as the "source" node and finds | ||
shortest paths from the source to all other nodes in the graph, | ||
producing a shortest-path tree. | ||
|
||
![Dijkstra](https://upload.wikimedia.org/wikipedia/commons/5/57/Dijkstra_Animation.gif) | ||
|
||
Dijkstra's algorithm to find the shortest path between `a` and `b`. | ||
It picks the unvisited vertex with the lowest distance, | ||
calculates the distance through it to each unvisited neighbor, | ||
and updates the neighbor's distance if smaller. Mark visited | ||
(set to red) when done with neighbors. | ||
|
||
## References | ||
|
||
- [Wikipedia](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) | ||
- [On YouTube by Nathaniel Fan](https://www.youtube.com/watch?v=gdmfOwyQlcI&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) | ||
- [On YouTube by Tushar Roy](https://www.youtube.com/watch?v=lAXZGERcDf4&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) |
Oops, something went wrong.