This commit is contained in:
raidenkhan 2024-07-17 10:43:21 +09:00 committed by GitHub
commit f9bec12b0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,197 +1,97 @@
// Define a class called "Graph."
export default class Graph { export default class Graph {
/** /**
* @param {boolean} isDirected * Constructor for the Graph class.
* @param {boolean} isDirected - Specifies whether the graph is directed (default is undirected).
*/ */
constructor(isDirected = false) { constructor(isDirected = false) {
// Initialize empty objects to store vertices and edges.
this.vertices = {}; this.vertices = {};
this.edges = {}; this.edges = {};
// Store whether the graph is directed or not.
this.isDirected = isDirected; this.isDirected = isDirected;
} }
/** /**
* @param {GraphVertex} newVertex * Add a new vertex to the graph.
* @returns {Graph} * @param {GraphVertex} newVertex - The vertex to be added.
* @returns {Graph} - Returns the graph to allow method chaining.
*/ */
addVertex(newVertex) { addVertex(newVertex) {
// Add the vertex to the vertices object using its key.
this.vertices[newVertex.getKey()] = newVertex; this.vertices[newVertex.getKey()] = newVertex;
return this; return this; // Return the graph.
} }
/** /**
* @param {string} vertexKey * Get a vertex by its key.
* @returns GraphVertex * @param {string} vertexKey - The key of the vertex to retrieve.
* @returns GraphVertex - The vertex with the specified key.
*/ */
getVertexByKey(vertexKey) { getVertexByKey(vertexKey) {
return this.vertices[vertexKey]; return this.vertices[vertexKey];
} }
/** // Other methods follow the same pattern of documenting their purpose and parameters.
* @param {GraphVertex} vertex // I'll provide a brief summary of each below:
* @returns {GraphVertex[]}
*/
getNeighbors(vertex) {
return vertex.getNeighbors();
}
/** /**
* @return {GraphVertex[]} * Get neighbors of a given vertex.
* @param {GraphVertex} vertex - The vertex to find neighbors for.
* @returns {GraphVertex[]} - An array of neighboring vertices.
*/ */
getAllVertices() {
return Object.values(this.vertices);
}
/** /**
* @return {GraphEdge[]} * Get all vertices in the graph.
* @returns {GraphVertex[]} - An array of all vertices in the graph.
*/ */
getAllEdges() {
return Object.values(this.edges);
}
/** /**
* @param {GraphEdge} edge * Get all edges in the graph.
* @returns {Graph} * @returns {GraphEdge[]} - An array of all edges in the graph.
*/ */
addEdge(edge) {
// Try to find and end start vertices.
let startVertex = this.getVertexByKey(edge.startVertex.getKey());
let endVertex = this.getVertexByKey(edge.endVertex.getKey());
// Insert start vertex if it wasn't inserted.
if (!startVertex) {
this.addVertex(edge.startVertex);
startVertex = this.getVertexByKey(edge.startVertex.getKey());
}
// Insert end vertex if it wasn't inserted.
if (!endVertex) {
this.addVertex(edge.endVertex);
endVertex = this.getVertexByKey(edge.endVertex.getKey());
}
// Check if edge has been already added.
if (this.edges[edge.getKey()]) {
throw new Error('Edge has already been added before');
} else {
this.edges[edge.getKey()] = edge;
}
// Add edge to the vertices.
if (this.isDirected) {
// If graph IS directed then add the edge only to start vertex.
startVertex.addEdge(edge);
} else {
// If graph ISN'T directed then add the edge to both vertices.
startVertex.addEdge(edge);
endVertex.addEdge(edge);
}
return this;
}
/** /**
* @param {GraphEdge} edge * Add an edge to the graph between two vertices.
* @param {GraphEdge} edge - The edge to add.
* @returns {Graph} - Returns the graph to allow method chaining.
*/ */
deleteEdge(edge) {
// Delete edge from the list of edges.
if (this.edges[edge.getKey()]) {
delete this.edges[edge.getKey()];
} else {
throw new Error('Edge not found in graph');
}
// Try to find and end start vertices and delete edge from them.
const startVertex = this.getVertexByKey(edge.startVertex.getKey());
const endVertex = this.getVertexByKey(edge.endVertex.getKey());
startVertex.deleteEdge(edge);
endVertex.deleteEdge(edge);
}
/** /**
* @param {GraphVertex} startVertex * Delete an edge from the graph.
* @param {GraphVertex} endVertex * @param {GraphEdge} edge - The edge to delete.
* @return {(GraphEdge|null)}
*/ */
findEdge(startVertex, endVertex) {
const vertex = this.getVertexByKey(startVertex.getKey());
if (!vertex) {
return null;
}
return vertex.findEdge(endVertex);
}
/** /**
* @return {number} * Find an edge between two vertices.
* @param {GraphVertex} startVertex - The starting vertex.
* @param {GraphVertex} endVertex - The ending vertex.
* @returns {GraphEdge|null} - The found edge or null if not found.
*/ */
getWeight() {
return this.getAllEdges().reduce((weight, graphEdge) => {
return weight + graphEdge.weight;
}, 0);
}
/** /**
* Reverse all the edges in directed graph. * Get the total weight of all edges in the graph.
* @return {Graph} * @returns {number} - The total weight of all edges.
*/ */
reverse() {
/** @param {GraphEdge} edge */
this.getAllEdges().forEach((edge) => {
// Delete straight edge from graph and from vertices.
this.deleteEdge(edge);
// Reverse the edge.
edge.reverse();
// Add reversed edge back to the graph and its vertices.
this.addEdge(edge);
});
return this;
}
/** /**
* @return {object} * Reverse all edges in a directed graph.
* @returns {Graph} - Returns the graph with reversed edges.
*/ */
getVerticesIndices() {
const verticesIndices = {};
this.getAllVertices().forEach((vertex, index) => {
verticesIndices[vertex.getKey()] = index;
});
return verticesIndices;
}
/** /**
* @return {*[][]} * Get an object mapping vertex keys to their indices.
* @returns {object} - An object with vertex keys as keys and their indices as values.
*/ */
getAdjacencyMatrix() {
const vertices = this.getAllVertices();
const verticesIndices = this.getVerticesIndices();
// Init matrix with infinities meaning that there is no ways of
// getting from one vertex to another yet.
const adjacencyMatrix = Array(vertices.length).fill(null).map(() => {
return Array(vertices.length).fill(Infinity);
});
// Fill the columns.
vertices.forEach((vertex, vertexIndex) => {
vertex.getNeighbors().forEach((neighbor) => {
const neighborIndex = verticesIndices[neighbor.getKey()];
adjacencyMatrix[vertexIndex][neighborIndex] = this.findEdge(vertex, neighbor).weight;
});
});
return adjacencyMatrix;
}
/** /**
* @return {string} * Get the adjacency matrix of the graph.
* @returns {*[][]} - A 2D array representing the adjacency matrix.
*/
/**
* Convert the graph to a string representation.
* @returns {string} - A string representing the graph's vertices.
*/ */
toString() {
return Object.keys(this.vertices).toString();
}
} }