Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/algorithms/graph/bellman-ford/__test__/bellmanFord.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
10 changes: 4 additions & 6 deletions src/data-structures/graph/GraphVertex.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand All @@ -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 });
Expand Down
12 changes: 12 additions & 0 deletions src/data-structures/graph/__test__/Graph.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
20 changes: 20 additions & 0 deletions src/data-structures/graph/__test__/GraphVertex.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down