Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 37 additions & 37 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,49 @@

## salesman
**See**: [demo](https://lovasoa.github.io/salesman.js/)
**Author:** Ophir LOJKINE
**Author**: Ophir LOJKINE

salesman npm module

Good heuristic for the traveling salesman problem using simulated annealing.

* [salesman](#module_salesman)
* [~Point](#module_salesman..Point)
* [new Point(x, y)](#new_module_salesman..Point_new)
* [~solve(points, [temp_coeff], [callback=])](#module_salesman..solve) ⇒ <code>Array.&lt;Number&gt;</code>
* [~solve(points, [temp_coeff], [callback], [callback])](#module_salesman..solve) ⇒ <code>Array.&lt;number&gt;</code>

<a name="module_salesman..Point"></a>

### salesman~Point
**Kind**: inner class of <code>[salesman](#module_salesman)</code>
**Kind**: inner class of [<code>salesman</code>](#module_salesman)
<a name="new_module_salesman..Point_new"></a>

#### new Point(x, y)
Represents a point in two dimensions.
Represents a point in two dimensions. Used as the input for `solve`.


| Param | Type | Description |
| --- | --- | --- |
| x | <code>Number</code> | abscissa |
| y | <code>Number</code> | ordinate |
| x | <code>number</code> | abscissa |
| y | <code>number</code> | ordinate |

<a name="module_salesman..solve"></a>

### salesman~solve(points, [temp_coeff], [callback=]) ⇒ <code>Array.&lt;Number&gt;</code>
### salesman~solve(points, [temp_coeff], [callback], [callback]) ⇒ <code>Array.&lt;number&gt;</code>
Solves the following problem:
Given a list of points and the distances between each pair of points,
what is the shortest possible route that visits each point exactly
once and returns to the origin point?

**Kind**: inner method of <code>[salesman](#module_salesman)</code>
**Returns**: <code>Array.&lt;Number&gt;</code> - An array of indexes in the original array. Indicates in which order the different points are visited.
**Kind**: inner method of [<code>salesman</code>](#module_salesman)
**Returns**: <code>Array.&lt;number&gt;</code> - An array of indexes in the original array. Indicates in which order the different points are visited.

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| points | <code>Array.&lt;Point&gt;</code> | | The points that the path will have to visit. |
| [temp_coeff] | <code>Number</code> | <code>0.999</code> | changes the convergence speed of the algorithm: the closer to 1, the slower the algorithm and the better the solutions. |
| [callback=] | <code>function</code> | | An optional callback to be called after each iteration. |
| [temp_coeff] | <code>number</code> | <code>0.999</code> | changes the convergence speed of the algorithm. Smaller values (0.9) work faster but give poorer solutions, whereas values closer to 1 (0.99999) work slower, but give better solutions. |
| [callback] | <code>function</code> | | An optional callback to be called after each iteration. |
| [callback] | <code>function</code> | <code>euclidean</code> | An optional argument to specify how distances are calculated. The function takes two Point objects as arguments and returns a number for distance. Defaults to simple Euclidean distance calculation. |

**Example**
```js
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "salesman.js",
"scripts": {
"test": "node test.js",
"prepare": "node salesman.js && node node_modules/jsdoc-to-markdown/bin/cli.js --src salesman.js > README.md"
"prepare": "node salesman.js && node node_modules/jsdoc-to-markdown/bin/cli.js --files salesman.js > README.md"
},
"repository": {
"type": "git",
Expand All @@ -27,6 +27,6 @@
},
"homepage": "https://github.com/lovasoa/salesman.js",
"devDependencies": {
"jsdoc-to-markdown": "1.3"
"jsdoc-to-markdown": "^6.0.1"
}
}
42 changes: 42 additions & 0 deletions perf_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const {
performance,
PerformanceObserver
} = require('perf_hooks');
const salesman = require("./salesman.js");

const width = 100;
const height = 100;
const size = 5000;
const perfTestCount = 500;

function createPoint(id) {
return {id, x: width * Math.random(), y: height * Math.random()};
}

const durations = [];

function arraySum(arr) {
return arr.reduce((a,b) => a + b, 0);
}

function arrayAvg(arr) {
return arraySum(arr) / arr.length;
}

for (let i = 1; i <= perfTestCount; i++) {
console.log(`Running test ${i}`);

const testPoints = [...Array(size).keys()].map((index) => (createPoint(index)));

const startTime = performance.now();
const result = salesman.solve(testPoints);
const duration = (performance.now() - startTime) / 1000; // Milliseconds
durations.push(duration);
console.log(`Test ${i} done, took ${duration}`);
}

console.log('RESULTS');
console.log('-------');
console.log(`* Average Time: ${arrayAvg(durations)}`);
console.log(`* Max Time: ${Math.max(...durations)}`);
console.log(`* Min Time: ${Math.min(...durations)}`);
Loading