Please click on the white screen or use input range to place points randomly
The obvious and the least accurate solution. Complexity O(n).
The most accurate, complex and the least efective solution. Complexity O(n!).
The nearest neighbour (NN) algorithm (a greedy algorithm) lets the salesman choose the nearest unvisited city as his next move. This algorithm quickly yields an effectively short route. For N cities randomly distributed on a plane, the algorithm on average yields a path 25% longer than the shortest possible path. However, there exist many specially arranged city distributions which make the NN algorithm give the worst route. Read more
MST-DFS algorithm is an approximation algorithm that falls approximatly between 1 to 2 of the optimal solution length.
Christofides–Serdyukov algorithm is an approximation algorithm that guarantees that its solutions will be within a factor of 3/2 of the optimal solution length.
No code snippet for this one. Nope.
Red lines represent potential options Black lines represent the result No potential options for > 7 points function generateIndexPerm(array) { switch (array.length) { case 1: return array; case 2: const [a, b] = array; return [[a, b], [b, a]]; default: const result = []; array.forEach((x, i) => { const head = array.slice(0, i); const tail = array.slice(i + 1); generateIndexPerm(head.concat(tail)).map(p => [x].concat(p)).forEach(p => result.push(p)); }); return result; } }
const nearestNeighborpath = (points) => { let progressPoints = points.slice(); let newpoints = [points[0]]; for(let i = 0; i < points.length-2; i++) { let minDistCoord = progressPoints[i+1]; let minDist = distanceHelper([progressPoints[i], progressPoints[i+1]]); let newIndex = i+1; for(let j = i+1; j < points.length-1; j++) { let curDist = distanceHelper([progressPoints[i], progressPoints[j]]); if (minDist > curDist) { minDist = curDist; minDistCoord = progressPoints[j]; newIndex = j; } } progressPoints = swapLines(progressPoints, i+1, newIndex) newpoints.push(minDistCoord); } }
Red lines represent an approximation matrix
Purple lines represent a mst
Black lines represent the result
function generateMST(points) { const visIdx = [0]; let unvisIdx = seq(1, points.length); const path = []; while(unvisIdx.length > 0) { let from = null; let to = null; let shortestDistance = Number.MAX_VALUE; for (let i = 0; i < visIdx.length; i++) { for (let j = 0; j < unvisIdx.length; j++) { const dist = distance(points[visIdx[i]], points[unvisIdx[j]]) if (dist < shortestDistance) { shortestDistance = dist; from = i; to = j; } } } path.push([visIdx[from], unvisIdx[to]]); visIdx.push(unvisIdx[to]); unvisIdx = unvisIdx.slice(0, to).concat(unvisIdx.slice(to + 1)); } const root = { idx: 0, children: [] } const nodes = {0: root}; path.forEach(([from, to]) => { const toNode = { idx: to, children: [] } const fromNode = nodes[from]; fromNode.children.push(toNode); nodes[to] = toNode; }); return { path, root }; }
inspited by link
Red lines represent an approximation matrix
Purple lines represent a mst
Red circles represent odd vertexes
Blue lines represent perfect matches
Black lines represent the result
function findOddDegreeIndexes(root, isRoot = true) { let indices = []; if (root.children.length % 2 === (isRoot ? 1 : 0)) { indices.push(root.idx); } root.children.map(child => { indices = indices.concat(findOddDegreeIndexes(child, false)); }); return indices; } function findPerfectPairingIndexes(points, indexes, mstPath) { let pairings = []; while(indexes.length > 0) { let from = indexes[0]; let to = null; let shortestDistance = Number.MAX_VALUE; for (let i = 1; i < indexes.length; i++) { const dist = distance(points[from], points[indexes[i]]); if (dist < shortestDistance && !mstPath.find(([f1, t1]) => f1 === from && t1 === indexes[i])) { shortestDistance = dist; to = i; } } pairings.push([from, indexes[to]]); indexes = indexes.slice(1, to).concat(indexes.slice(to + 1)); } return pairings.filter((pair) => (pair[1])); }
inspited by link