Skip to content

Commit 5198c47

Browse files
committed
feat(js): add modular solution and documentation for hard challenge 1 - Travelling Salesman Problem (Bitmasking)
1 parent 011299a commit 5198c47

File tree

4 files changed

+137
-2
lines changed

4 files changed

+137
-2
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Travelling Salesman Problem - Bitmasking Approach
2+
3+
## English
4+
5+
The Travelling Salesman Problem (TSP) is a classic algorithmic problem in the field of computer science and operations research. It focuses on optimization. In this problem, a salesman is given a list of cities and must determine the shortest possible route that visits each city exactly once and returns to the origin city.
6+
7+
This challenge requires implementing the TSP using bitmasking and dynamic programming to efficiently explore all possible routes without redundant calculations. The solution is implemented in JavaScript using Object-Oriented Programming (OOP) principles and follows DRY (Don't Repeat Yourself) best practices.
8+
9+
### Relevant Code Snippet
10+
11+
```javascript
12+
class TravellingSalesman {
13+
constructor(distanceMatrix) {
14+
this.distanceMatrix = distanceMatrix;
15+
this.n = distanceMatrix.length;
16+
this.memo = Array.from({ length: this.n }, () => []);
17+
}
18+
19+
tsp(mask = 1, pos = 0) {
20+
if (mask === (1 << this.n) - 1) {
21+
return this.distanceMatrix[pos][0];
22+
}
23+
if (this.memo[pos][mask] !== undefined) {
24+
return this.memo[pos][mask];
25+
}
26+
27+
let minCost = Infinity;
28+
for (let city = 0; city < this.n; city++) {
29+
if ((mask & (1 << city)) === 0) {
30+
const newCost = this.distanceMatrix[pos][city] + this.tsp(mask | (1 << city), city);
31+
if (newCost < minCost) {
32+
minCost = newCost;
33+
}
34+
}
35+
}
36+
this.memo[pos][mask] = minCost;
37+
return minCost;
38+
}
39+
}
40+
```
41+
42+
---
43+
44+
## Español
45+
46+
El Problema del Viajante de Comercio (TSP) es un problema clásico en el campo de la informática y la investigación operativa. Se centra en la optimización. En este problema, un viajante debe determinar la ruta más corta posible que visite cada ciudad exactamente una vez y regrese a la ciudad de origen.
47+
48+
Este reto requiere implementar el TSP usando bitmasking y programación dinámica para explorar eficientemente todas las rutas posibles sin cálculos redundantes. La solución está implementada en JavaScript usando principios de Programación Orientada a Objetos (POO) y siguiendo las mejores prácticas de DRY (No te repitas).
49+
50+
### Fragmento de Código Relevante
51+
52+
```javascript
53+
class TravellingSalesman {
54+
constructor(distanceMatrix) {
55+
this.distanceMatrix = distanceMatrix;
56+
this.n = distanceMatrix.length;
57+
this.memo = Array.from({ length: this.n }, () => []);
58+
}
59+
60+
tsp(mask = 1, pos = 0) {
61+
if (mask === (1 << this.n) - 1) {
62+
return this.distanceMatrix[pos][0];
63+
}
64+
if (this.memo[pos][mask] !== undefined) {
65+
return this.memo[pos][mask];
66+
}
67+
68+
let minCost = Infinity;
69+
for (let city = 0; city < this.n; city++) {
70+
if ((mask & (1 << city)) === 0) {
71+
const newCost = this.distanceMatrix[pos][city] + this.tsp(mask | (1 << city), city);
72+
if (newCost < minCost) {
73+
minCost = newCost;
74+
}
75+
}
76+
}
77+
this.memo[pos][mask] = minCost;
78+
return minCost;
79+
}
80+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// TravellingSalesman.js - TSP solver using Bitmasking and Dynamic Programming with OOP and DRY principles
2+
3+
class TravellingSalesman {
4+
constructor(distanceMatrix) {
5+
this.distanceMatrix = distanceMatrix;
6+
this.n = distanceMatrix.length;
7+
this.memo = Array.from({ length: this.n }, () => []);
8+
}
9+
10+
tsp(mask = 1, pos = 0) {
11+
if (mask === (1 << this.n) - 1) {
12+
return this.distanceMatrix[pos][0];
13+
}
14+
if (this.memo[pos][mask] !== undefined) {
15+
return this.memo[pos][mask];
16+
}
17+
18+
let minCost = Infinity;
19+
for (let city = 0; city < this.n; city++) {
20+
if ((mask & (1 << city)) === 0) {
21+
const newCost =
22+
this.distanceMatrix[pos][city] + this.tsp(mask | (1 << city), city);
23+
if (newCost < minCost) {
24+
minCost = newCost;
25+
}
26+
}
27+
}
28+
this.memo[pos][mask] = minCost;
29+
return minCost;
30+
}
31+
}
32+
33+
export default TravellingSalesman;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
Challenge:
3+
Given a set of cities and the distances between every pair of cities, find the shortest possible route that visits each city exactly once and returns to the origin city.
4+
This challenge requires implementing the Travelling Salesman Problem (TSP) using bitmasking and dynamic programming to optimize the solution.
5+
*/
6+
7+
import TravellingSalesman from "./TravellingSalesman.js";
8+
9+
function main() {
10+
const distanceMatrix = [
11+
[0, 10, 15, 20],
12+
[10, 0, 35, 25],
13+
[15, 35, 0, 30],
14+
[20, 25, 30, 0],
15+
];
16+
17+
const tspSolver = new TravellingSalesman(distanceMatrix);
18+
const minCost = tspSolver.tsp();
19+
console.log("Minimum cost to visit all cities:", minCost);
20+
}
21+
22+
main();

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ To maintain an organized and scalable project, we suggest the following folder s
4040

4141
The `proposed-solution` folder is exclusive for the solution by the owner @IbatoLionDev. To add your own solutions, please create a folder with your GitHub handle (e.g., `@YourUsername`) at the same level as the `proposed-solution` folder, not inside it. Place your code inside your folder.
4242

43-
If you, as an independent user, feel the need to explain your solution, please prepare an `article.md` file inside your folder.
43+
If you, as an independent user, feel the need to explain your solution, please prepare an `README.md` file inside your folder.
4444

4545
---
4646

@@ -84,4 +84,4 @@ Para mantener un proyecto organizado y escalable, sugerimos la siguiente estruct
8484

8585
La carpeta `propuesta-solucion` es exclusiva para la solución del propietario @IbatoLionDev. Para añadir tus propias soluciones, crea una carpeta con tu usuario de GitHub (por ejemplo, `@TuUsuario`) al mismo nivel que la carpeta `propuesta-solucion`, no dentro de ella. Coloca tu código dentro de tu carpeta.
8686

87-
Si tú, como usuario independiente, consideras necesario explicar tu solución, por favor prepara un archivo `articulo.md` dentro de tu carpeta.
87+
Si tú, como usuario independiente, consideras necesario explicar tu solución, por favor prepara un archivo `README.md` dentro de tu carpeta.

0 commit comments

Comments
 (0)