From 3b4653f8f551434af4a7e56b52977eb9d0a97629 Mon Sep 17 00:00:00 2001 From: Jivan <137729176+Jivanjamadar@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:36:37 +0530 Subject: [PATCH 1/2] Add files via upload --- Backtracking/HeldKarpAlgorithm.js | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Backtracking/HeldKarpAlgorithm.js diff --git a/Backtracking/HeldKarpAlgorithm.js b/Backtracking/HeldKarpAlgorithm.js new file mode 100644 index 0000000000..4d2257e079 --- /dev/null +++ b/Backtracking/HeldKarpAlgorithm.js @@ -0,0 +1,45 @@ +/* +Held-karp algorithm (https://en.wikipedia.org/wiki/Held-Karp_algorithm) + +- Held-karp algorithm solves the TSP problem using a dynamic programming paradigm. +- It computes the minimum cost to visit each city exactly once & return to the start point, + considering all subsets of cities & using memoization. +- Comparing it with the Hamiltonian algorithm vs Held-karp algorithm ( n! vs ~2^n), this is more efficient. +*/ + +function heldKarp(dist) { + const n = dist.length + const memo = Array.from({ length: n }, () => Array(1 << n).fill(null)) + + // Base case: distance from the starting point to itself is 0 + for (let i = 0; i < n; i++) { + memo[i][1 << i] = dist[i][0] + } + + // Iterate through all subsets of vertices + for (let mask = 0; mask < (1 << n); mask++) { + for (let u = 0; u < n; u++) { + if (!(mask & (1 << u))) continue // u must be in the subset + // Iterate through all vertices to find the minimum cost + for (let v = 0; v < n; v++) { + if (mask & (1 << v) || u === v) continue; // v must not be in the subset + const newMask = mask | (1 << v) + const newCost = memo[u][mask] + dist[u][v] + + if (memo[v][newMask] === null || newCost < memo[v][newMask]) { + memo[v][newMask] = newCost + } + } + } + } + + let minCost = Infinity + for (let u = 1; u < n; u++) { + const cost = memo[u][(1 << n) - 1] + dist[u][0] + minCost = Math.min(minCost, cost) + } + + return minCost +} + +export { heldKarp } From 8f45b5d4a6f5b8c349ad7b5c2d1c67f6000c076d Mon Sep 17 00:00:00 2001 From: Jivan <137729176+Jivanjamadar@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:36:55 +0530 Subject: [PATCH 2/2] Add files via upload --- Backtracking/tests/HeldKarpAlgorithm.test.js | 87 ++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Backtracking/tests/HeldKarpAlgorithm.test.js diff --git a/Backtracking/tests/HeldKarpAlgorithm.test.js b/Backtracking/tests/HeldKarpAlgorithm.test.js new file mode 100644 index 0000000000..b8d6ec3c94 --- /dev/null +++ b/Backtracking/tests/HeldKarpAlgorithm.test.js @@ -0,0 +1,87 @@ + +import { heldKarp } from '../HeldKarpAlgorithm' + +describe('Held-Karp Algorithm - TSP Solver', () => { + it('Test Case 1 - 4 cities (Simple)', () => { + const distanceMatrix = [ + [0, 10, 15, 20], + [10, 0, 35, 25], + [15, 35, 0, 30], + [20, 25, 30, 0] + ] + const result = heldKarp(distanceMatrix) + expect(result).toBe(80) + }) + + it('Test Case 2 - 3 cities', () => { + const distanceMatrix = [ + [0, 5, 10], + [5, 0, 15], + [10, 15, 0] + ] + const result = heldKarp(distanceMatrix) + expect(result).toBe(30) + }) + + it('Test Case 3 - 5 cities', () => { + const distanceMatrix = [ + [0, 10, 15, 20, 25], + [10, 0, 35, 25, 30], + [15, 35, 0, 30, 20], + [20, 25, 30, 0, 10], + [25, 30, 20, 10, 0] + ] + const result = heldKarp(distanceMatrix) + expect(result).toBe(95) + }) + + it('Test Case 4 - 1 city', () => { + const distanceMatrix = [ + [0] + ] + const result = heldKarp(distanceMatrix) + expect(result).toBe(0) + }) + + it('Test Case 5 - 2 cities', () => { + const distanceMatrix = [ + [0, 5], + [5, 0] + ] + const result = heldKarp(distanceMatrix) + expect(result).toBe(10) + }) + + it('Test Case 6 - Equal costs (4 cities)', () => { + const distanceMatrix = [ + [0, 1, 1, 1], + [1, 0, 1, 1], + [1, 1, 0, 1], + [1, 1, 1, 0] + ] + const result = heldKarp(distanceMatrix) + expect(result).toBe(4) + }) + + it('Test Case 7 - Custom distances', () => { + const distanceMatrix = [ + [0, 10, 20, 30], + [5, 0, 15, 25], + [10, 5, 0, 20], + [20, 15, 10, 0] + ] + const result = heldKarp(distanceMatrix) + expect(result).toBe(55) + }) + + it('Test Case 8 - Large distances', () => { + const distanceMatrix = [ + [0, 1000, 2000, 3000], + [1000, 0, 1500, 2500], + [2000, 1500, 0, 3500], + [3000, 2500, 3500, 0] + ] + const result = heldKarp(distanceMatrix) + expect(result).toBe(8000) + }) +})