diff --git a/src/algorithms/graph/bellman-ford/__test__/bellmanFord.test.js b/src/algorithms/graph/bellman-ford/__test__/bellmanFord.test.js index ffa30eba21..f115a87aa6 100644 --- a/src/algorithms/graph/bellman-ford/__test__/bellmanFord.test.js +++ b/src/algorithms/graph/bellman-ford/__test__/bellmanFord.test.js @@ -4,6 +4,16 @@ import Graph from '../../../../data-structures/graph/Graph'; import bellmanFord from '../bellmanFord'; describe('bellmanFord', () => { + it('should not use another edge weight when relaxing a self-loop', () => { + const graph = new Graph(true); + const vertexA = new GraphVertex('A'); + const vertexB = new GraphVertex('B'); + graph.addEdge(new GraphEdge(vertexA, vertexB, -3)); + graph.addEdge(new GraphEdge(vertexA, vertexA, 9)); + + expect(bellmanFord(graph, vertexA).distances).toEqual({ A: 0, B: -3 }); + }); + it('should find minimum paths to all vertices for undirected graph', () => { const vertexA = new GraphVertex('A'); const vertexB = new GraphVertex('B'); diff --git a/src/data-structures/graph/GraphVertex.js b/src/data-structures/graph/GraphVertex.js index f3514d44e1..fc699ef0cd 100644 --- a/src/data-structures/graph/GraphVertex.js +++ b/src/data-structures/graph/GraphVertex.js @@ -91,11 +91,7 @@ export default class GraphVertex { * @returns {boolean} */ hasNeighbor(vertex) { - const vertexNode = this.edges.find({ - callback: (edge) => edge.startVertex === vertex || edge.endVertex === vertex, - }); - - return !!vertexNode; + return !!this.findEdge(vertex); } /** @@ -104,7 +100,9 @@ export default class GraphVertex { */ findEdge(vertex) { const edgeFinder = (edge) => { - return edge.startVertex === vertex || edge.endVertex === vertex; + // Match both endpoints: querying this vertex itself requires a self-loop. + return (edge.startVertex === this && edge.endVertex === vertex) + || (edge.endVertex === this && edge.startVertex === vertex); }; const edge = this.edges.find({ callback: edgeFinder }); diff --git a/src/data-structures/graph/__test__/Graph.test.js b/src/data-structures/graph/__test__/Graph.test.js index 11c7a6c31d..381eebbfc6 100644 --- a/src/data-structures/graph/__test__/Graph.test.js +++ b/src/data-structures/graph/__test__/Graph.test.js @@ -3,6 +3,18 @@ import GraphVertex from '../GraphVertex'; import GraphEdge from '../GraphEdge'; describe('Graph', () => { + it('should use the self-loop weight in the adjacency matrix', () => { + const graph = new Graph(); + const vertexA = new GraphVertex('A'); + const vertexB = new GraphVertex('B'); + const loop = new GraphEdge(vertexA, vertexA, 5); + graph.addEdge(new GraphEdge(vertexA, vertexB, 2)); + expect(graph.findEdge(vertexA, vertexA)).toBeNull(); + graph.addEdge(loop); + expect(graph.findEdge(vertexA, vertexA)).toBe(loop); + expect(graph.getAdjacencyMatrix()).toEqual([[5, 2], [2, Infinity]]); + }); + it('should add vertices to graph', () => { const graph = new Graph(); diff --git a/src/data-structures/graph/__test__/GraphVertex.test.js b/src/data-structures/graph/__test__/GraphVertex.test.js index 3fc2110d57..486b5967eb 100644 --- a/src/data-structures/graph/__test__/GraphVertex.test.js +++ b/src/data-structures/graph/__test__/GraphVertex.test.js @@ -2,6 +2,26 @@ import GraphVertex from '../GraphVertex'; import GraphEdge from '../GraphEdge'; describe('GraphVertex', () => { + it('should distinguish self-loops from edges to other vertices', () => { + const vertexA = new GraphVertex('A'); + const vertexB = new GraphVertex('B'); + const edgeAB = new GraphEdge(vertexA, vertexB); + const edgeBA = new GraphEdge(vertexB, vertexA); + const loop = new GraphEdge(vertexA, vertexA); + + vertexA.addEdge(edgeAB).addEdge(edgeBA); + expect(vertexA.findEdge(vertexA)).toBeNull(); + expect(vertexA.hasNeighbor(vertexA)).toBe(false); + + vertexA.addEdge(loop); + expect(vertexA.findEdge(vertexA)).toBe(loop); + expect(vertexA.hasNeighbor(vertexA)).toBe(true); + expect(vertexA.findEdge(vertexB)).toBe(edgeAB); + vertexA.deleteEdge(edgeAB); + expect(vertexA.findEdge(vertexB)).toBe(edgeBA); + expect(vertexA.hasNeighbor(vertexB)).toBe(true); + }); + it('should throw an error when trying to create vertex without value', () => { let vertex = null;