diff --git a/README.md b/README.md index 72e3883..680ef46 100644 --- a/README.md +++ b/README.md @@ -358,6 +358,8 @@ import {UndirectedGraph} from 'data-structure-typed'; ![](https://github.com/zrwusa/assets/blob/master/images/data-structure-typed/examples/dfs-pre-order.webp) +![](https://github.com/zrwusa/assets/blob/master/images/data-structure-typed/examples/map-graph.webp) + ![](https://github.com/zrwusa/assets/blob/master/images/data-structure-typed/examples/test-graphs.webp) ![](https://github.com/zrwusa/assets/blob/master/images/data-structure-typed/examples/cut-off-trees-for-golf.webp) diff --git a/src/data-structures/graph/map-graph.ts b/src/data-structures/graph/map-graph.ts index eae7e7e..5f350aa 100644 --- a/src/data-structures/graph/map-graph.ts +++ b/src/data-structures/graph/map-graph.ts @@ -1,18 +1,57 @@ -import {MapGraphCoordinate, VertexId } from '../types'; +import {MapGraphCoordinate, VertexId} from '../types'; import {DirectedEdge, DirectedGraph, DirectedVertex} from './directed-graph'; export class MapVertex extends DirectedVertex { - + /** + * The constructor function initializes an object with an id, latitude, longitude, and an optional value. + * @param {VertexId} id - The `id` parameter is of type `VertexId` and represents the identifier of the vertex. + * @param {number} lat - The "lat" parameter represents the latitude of a vertex. Latitude is a geographic coordinate + * that specifies the north-south position of a point on the Earth's surface. It is measured in degrees, with positive + * values representing points north of the equator and negative values representing points south of the equator. + * @param {number} long - The "long" parameter represents the longitude of a location. Longitude is a geographic + * coordinate that specifies the east-west position of a point on the Earth's surface. It is measured in degrees, with + * values ranging from -180 to 180. + * @param {T} [val] - The "val" parameter is an optional value of type T. It is not required to be provided when + * creating an instance of the class. + */ constructor(id: VertexId, lat: number, long: number, val?: T) { super(id, val); - this.lat = lat; - this.long = long; + this._lat = lat; + this._long = long; + } + + private _lat: number; + + get lat(): number { + return this._lat; + } + + set lat(value: number) { + this._lat = value; + } + + private _long: number; + + get long(): number { + return this._long; + } + + set long(value: number) { + this._long = value; } - lat: number; - long: number; } export class MapEdge extends DirectedEdge { + /** + * The constructor function initializes a new instance of a class with the given source, destination, weight, and + * value. + * @param {VertexId} src - The `src` parameter is the source vertex ID. It represents the starting point of an edge in + * a graph. + * @param {VertexId} dest - The `dest` parameter is the identifier of the destination vertex for an edge. + * @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge. + * @param {T} [val] - The "val" parameter is an optional parameter of type T. It is used to store additional + * information or data associated with the edge. + */ constructor(src: VertexId, dest: VertexId, weight?: number, val?: T) { super(src, dest, weight, val); } @@ -20,19 +59,69 @@ export class MapEdge extends DirectedEdge { export class MapGraph = MapVertex, E extends MapEdge = MapEdge> extends DirectedGraph { - constructor(topLeft: MapGraphCoordinate, bottomRight: MapGraphCoordinate) { + + /** + * The constructor function initializes the origin and bottomRight properties of a MapGraphCoordinate object. + * @param {MapGraphCoordinate} origin - The `origin` parameter is a `MapGraphCoordinate` object that represents the + * starting point or reference point of the map graph. It defines the coordinates of the top-left corner of the map + * graph. + * @param {MapGraphCoordinate} [bottomRight] - The `bottomRight` parameter is an optional parameter of type + * `MapGraphCoordinate`. It represents the bottom right coordinate of a map graph. If this parameter is not provided, + * it will default to `undefined`. + */ + constructor(origin: MapGraphCoordinate, bottomRight?: MapGraphCoordinate) { super(); - this.topLeft = topLeft; - this.bottomRight = bottomRight; + this._origin = origin; + this._bottomRight = bottomRight; } - topLeft: MapGraphCoordinate; - bottomRight: MapGraphCoordinate; + private _origin: MapGraphCoordinate = [0, 0]; - override createVertex(id: VertexId, val?: V['val'], lat: number = this.topLeft[0], long: number = this.topLeft[1]): V { + get origin(): MapGraphCoordinate { + return this._origin; + } + + set origin(value: MapGraphCoordinate) { + this._origin = value; + } + + private _bottomRight: MapGraphCoordinate | undefined; + + get bottomRight(): MapGraphCoordinate | undefined { + return this._bottomRight; + } + + set bottomRight(value: MapGraphCoordinate | undefined) { + this._bottomRight = value; + } + + /** + * The function creates a new vertex with the given id, value, latitude, and longitude. + * @param {VertexId} id - The id parameter is the unique identifier for the vertex. It is of type VertexId, which could + * be a string or a number depending on how you define it in your code. + * @param [val] - The `val` parameter is an optional value that can be assigned to the `val` property of the vertex. It + * is of type `V['val']`, which means it should be of the same type as the `val` property of the vertex class `V`. + * @param {number} lat - The `lat` parameter represents the latitude of the vertex. It is a number that specifies the + * position of the vertex on the Earth's surface in the north-south direction. + * @param {number} long - The `long` parameter represents the longitude coordinate of the vertex. + * @returns The method is returning a new instance of the `MapVertex` class, casted as type `V`. + */ + override createVertex(id: VertexId, val?: V['val'], lat: number = this.origin[0], long: number = this.origin[1]): V { return new MapVertex(id, lat, long, val) as V; } + /** + * The function creates a new instance of a MapEdge with the given source, destination, weight, and value. + * @param {VertexId} src - The source vertex ID of the edge. It represents the starting point of the edge. + * @param {VertexId} dest - The `dest` parameter is the identifier of the destination vertex for the edge being + * created. + * @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the edge. It + * is used to assign a numerical value to the edge, which can be used in algorithms such as shortest path algorithms. + * If the weight is not provided, it can be set to a default value or left undefined. + * @param [val] - The `val` parameter is an optional value that can be assigned to the edge. It can be of any type, + * depending on the specific implementation of the `MapEdge` class. + * @returns a new instance of the `MapEdge` class, casted as type `E`. + */ override createEdge(src: VertexId, dest: VertexId, weight?: number, val?: E['val']): E { return new MapEdge(src, dest, weight, val) as E; } diff --git a/tests/unit/data-structures/binary-tree/overall.test.ts b/tests/unit/data-structures/binary-tree/overall.test.ts index a27fd06..3e5f1f9 100644 --- a/tests/unit/data-structures/binary-tree/overall.test.ts +++ b/tests/unit/data-structures/binary-tree/overall.test.ts @@ -33,11 +33,14 @@ describe('Overall BinaryTree Test', () => { objBST.add(11, {id: 11, keyA: 11}); objBST.add(3, {id: 3, keyA: 3}); - objBST.addMany([{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8}, - {id: 13, keyA: 13}, {id: 16, keyA: 16}, {id: 2, keyA: 2}, - {id: 6, keyA: 6}, {id: 9, keyA: 9}, {id: 12, keyA: 12}, - {id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7}, - {id: 10, keyA: 10}, {id: 5, keyA: 5}]); + objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], + [ + {id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8}, + {id: 13, keyA: 13}, {id: 16, keyA: 16}, {id: 2, keyA: 2}, + {id: 6, keyA: 6}, {id: 9, keyA: 9}, {id: 12, keyA: 12}, + {id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7}, + {id: 10, keyA: 10}, {id: 5, keyA: 5} + ]); objBST.remove(11); diff --git a/tests/unit/data-structures/graph/map-graph.test.ts b/tests/unit/data-structures/graph/map-graph.test.ts new file mode 100644 index 0000000..30a7285 --- /dev/null +++ b/tests/unit/data-structures/graph/map-graph.test.ts @@ -0,0 +1,46 @@ +import {MapGraph, MapVertex} from '../../../../src'; + +describe('MapGraph Operation Test', () => { + it('dijkstra shortest path', () => { + const mapGraph = new MapGraph([5.500338, 100.173665]); + + mapGraph.addVertex(new MapVertex('Surin', 5.466724, 100.274805)); + mapGraph.addVertex(new MapVertex('Batu Feringgi Beach', 5.475141, 100.276670)); + mapGraph.addVertex(new MapVertex('Lotus', 5.459044, 100.308767)); + mapGraph.addVertex(new MapVertex('The Breeza', 5.454197, 100.307859)); + mapGraph.addVertex(new MapVertex('Hard Rock Hotel', 5.467850, 100.241876)); + mapGraph.addVertex(new MapVertex('Mira', 5.456749, 100.286650)); + mapGraph.addVertex(new MapVertex('Penang Bible Church', 5.428683, 100.314825)); + mapGraph.addVertex(new MapVertex('Queensbay', 5.332760, 100.306651)); + mapGraph.addVertex(new MapVertex('Saanen Goat Farm', 5.405738, 100.207699)); + mapGraph.addVertex(new MapVertex('Trinity Auto', 5.401126, 100.303739)); + mapGraph.addVertex(new MapVertex('Penang Airport', 5.293185, 100.265772)); + mapGraph.addEdge('Surin', 'Lotus', 4.7); + mapGraph.addEdge('Lotus', 'The Breeza', 1); + mapGraph.addEdge('Batu Feringgi Beach', 'Hard Rock Hotel', 5.2); + mapGraph.addEdge('Surin', 'Mira', 2.8); + mapGraph.addEdge('Mira', 'Penang Bible Church', 7.0); + mapGraph.addEdge('Lotus', 'Penang Bible Church', 5.7); + mapGraph.addEdge('Penang Bible Church', 'Queensbay', 13.9); + mapGraph.addEdge('Hard Rock Hotel', 'Saanen Goat Farm', 18.5); + mapGraph.addEdge('The Breeza', 'Trinity Auto', 9.1); + mapGraph.addEdge('Trinity Auto', 'Saanen Goat Farm', 26.3); + mapGraph.addEdge('The Breeza', 'Penang Airport', 24.8); + mapGraph.addEdge('Penang Airport', 'Saanen Goat Farm', 21.2); + const expected1 = ['Surin', 'Lotus', 'The Breeza', 'Trinity Auto', 'Saanen Goat Farm']; + + const minPathBetween = mapGraph.getMinPathBetween('Surin', 'Saanen Goat Farm'); + expect(minPathBetween?.map(v => v.id)).toEqual(expected1); + const surinToSaanenGoatFarmDij = mapGraph.dijkstra('Surin', 'Saanen Goat Farm', true, true); + expect(surinToSaanenGoatFarmDij?.minPath.map(v => v.id)).toEqual(expected1); + expect(surinToSaanenGoatFarmDij?.minDist).toBe(41.1); + mapGraph.addEdge('Surin', 'Batu Feringgi Beach', 1.5); + const expected2 = ['Surin', 'Batu Feringgi Beach', 'Hard Rock Hotel', 'Saanen Goat Farm']; + const minPathBetweenViaBFB = mapGraph.getMinPathBetween('Surin', 'Saanen Goat Farm', true); + expect(minPathBetweenViaBFB?.map(v => v.id)).toEqual(expected2); + const surinToSaanenGoatFarmViaDij = mapGraph.dijkstra('Surin', 'Saanen Goat Farm', true, true); + expect(surinToSaanenGoatFarmViaDij?.minPath.map(v => v.id)).toEqual(expected2); + expect(surinToSaanenGoatFarmViaDij?.minDist).toBe(25.2); + }); + +});