Skip to content

Commit

Permalink
nearest insertion
Browse files Browse the repository at this point in the history
  • Loading branch information
jhackshaw committed Oct 18, 2019
1 parent 5317f1a commit 2f07e8a
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 7 deletions.
12 changes: 6 additions & 6 deletions src/components/MenuSolverControls.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,26 +73,26 @@ const MenuSolverControls = ({ onStart, onFullSpeed, onStop }) => {
fullWidth
margin="dense"
>
<ListSubheader>Exhaustive</ListSubheader>
{ algorithms.filter(alg => alg.type === "exhaustive")
<ListSubheader>Heuristic Construction</ListSubheader>
{ algorithms.filter(alg => alg.type === "heuristic-construction")
.map(alg => (
<SelectItem value={alg.solverKey}
key={alg.solverKey}
>
{ alg.friendlyName }
</SelectItem>
))}
<ListSubheader>Heuristic Construction</ListSubheader>
{ algorithms.filter(alg => alg.type === "heuristic-construction")
<ListSubheader>Heuristic Improvement</ListSubheader>
{ algorithms.filter(alg => alg.type === "heuristic-improvement")
.map(alg => (
<SelectItem value={alg.solverKey}
key={alg.solverKey}
>
{ alg.friendlyName }
</SelectItem>
))}
<ListSubheader>Heuristic Improvement</ListSubheader>
{ algorithms.filter(alg => alg.type === "heuristic-improvement")
<ListSubheader>Exhaustive</ListSubheader>
{ algorithms.filter(alg => alg.type === "exhaustive")
.map(alg => (
<SelectItem value={alg.solverKey}
key={alg.solverKey}
Expand Down
2 changes: 1 addition & 1 deletion src/content/heurisitc-construction/furthestInsertion.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
type: heuristic-construction
order: 3
order: 4
solverKey: furthestInsertion
friendlyName: Furthest Insertion
defaults:
Expand Down
83 changes: 83 additions & 0 deletions src/content/heurisitc-construction/nearestInsertion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
type: heuristic-construction
order: 3
solverKey: nearestInsertion
friendlyName: Nearest Insertion
defaults:
evaluatingDetailLevel: 1
maxEvaluatingDetailLevel: 1
---


# Furthest Insertion

This is a heuristic construction algorithm. It chooses the furthest point from the path to add to it, and then figures out where the best place to put it will be.

1. From the starting point
2. First, go to the closest point
3. Choose the point that is **nearest** to the current path
4. Find the cheapest place to add it in the path
4. Chosen point is no longer an "available point"
5. Continue from #3 until there are no available points, and then return to the start.


## The code

```javascript

const furthestInsertion = async points => {
// from the starting point
const path = [points.shift()];

//
// INITIALIZATION - go to the nearest point first
//
points.sort((a, b) => (
distance(path[0], b) -
distance(path[0], a)
));
path.push(points.pop());


while (points.length > 0) {
//
// SELECTION - nearest point to the path
//
let [selectedDistance, selectedIdx] = [Infinity, null];
for (const [freePointIdx, freePoint] of points.entries()) {

// find the minimum distance to the path for freePoint
let [bestCostToPath, costToPathIdx] = [Infinity, null];
for (const pathPoint of path) {
const dist = distance(freePoint, pathPoint);
if (dist < bestCostToPath) {
[bestCostToPath, costToPathIdx] = [dist, freePointIdx]
}
}

// if this point is closer to the path than the currently selected
if (bestCostToPath < selectedDistance) {
[selectedDistance, selectedIdx] = [bestCostToPath, costToPathIdx];
}
}
const [ nextPoint ] = points.splice(selectedIdx, 1);

//
// INSERTION - find the insertion spot that minimizes distance
//
let [bestCost, bestIdx] = [Infinity, null];
for (let i=1; i<path.length; i++) {
const insertionCost = pathCost([
path[i-1], nextPoint, path[i]
])
if (insertionCost < bestCost) {
[bestCost, bestIdx] = [insertionCost, i];
}
}
path.splice(bestIdx, 0, nextPoint);
}

// return to start after visiting all other points
path.push(path[0]);
}
```
2 changes: 2 additions & 0 deletions src/solvers/heuristic/furthestInsertion.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const furthestInsertion = async points => {
cost: pathCost(path)
}))

await self.sleep();


while (points.length > 0) {
//
Expand Down
89 changes: 89 additions & 0 deletions src/solvers/heuristic/nearestInsertion.worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* eslint-disable no-restricted-globals */
import makeSolver from '../makeSolver';
import { pathCost, distance } from '../cost';


const furthestInsertion = async points => {
// from the starting point
const path = [points.shift()];

//
// INITIALIZATION - go to the nearest point first
//
points.sort((a, b) => (
distance(path[0], b) -
distance(path[0], a)
));
path.push(points.pop());

self.setEvaluatingPaths(() => ({
paths: [{ path }],
cost: pathCost(path)
}))

await self.sleep();


while (points.length > 0) {
//
// SELECTION - nearest point to the path
//
let [selectedDistance, selectedIdx] = [0, null];
for (const [freePointIdx, freePoint] of points.entries()) {

// find the minimum distance to the path for freePoint
let [bestCostToPath, costToPathIdx] = [Infinity, null];
for (const pathPoint of path) {
const dist = distance(freePoint, pathPoint);
if (dist < bestCostToPath) {
[bestCostToPath, costToPathIdx] = [dist, freePointIdx]
}
}

// if this point is closer to the path than the currently selected
if (bestCostToPath < selectedDistance) {
[selectedDistance, selectedIdx] = [bestCostToPath, costToPathIdx];
}
}

// get the next point to add
const [ nextPoint ] = points.splice(selectedIdx, 1);

//
// INSERTION - find the insertion spot that minimizes distance
//
let [bestCost, bestIdx] = [Infinity, null];
for (let i=1; i<path.length; i++) {
const insertionCost = pathCost([
path[i-1], nextPoint, path[i]
])
if (insertionCost < bestCost) {
[bestCost, bestIdx] = [insertionCost, i];
}
}
path.splice(bestIdx, 0, nextPoint);


self.setEvaluatingPaths(() => ({
paths: [{ path }],
cost: pathCost(path)
}))

await self.sleep();
}

// return to start after visiting all other points
path.push(path[0]);
const cost = pathCost(path);

self.setEvaluatingPaths(() => ({
paths: [{ path }],
cost
}))
await self.sleep();

self.setBestPath(path, cost)

}

makeSolver(furthestInsertion);
2 changes: 2 additions & 0 deletions src/solvers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import branchAndBoundOnCost from './exhaustive/branchAndBoundOnCost.worker';

import shortestPath from './heuristic/shortestPath.worker';
import arbitraryInsertion from './heuristic/arbitraryInsertion.worker';
import nearestInsertion from './heuristic/nearestInsertion.worker';
import furthestInsertion from './heuristic/furthestInsertion.worker';

import twoOptInversion from './heuristic/twoOptInversion.worker';
Expand All @@ -18,6 +19,7 @@ export default {
shortestPath,
arbitraryInsertion,
furthestInsertion,
nearestInsertion,

twoOptInversion,
twoOptReciprocalExchange
Expand Down

0 comments on commit 2f07e8a

Please sign in to comment.