Skip to content

Commit 29ce133

Browse files
committedSep 18, 2017
Added object pool for regular A*
1 parent fab10c0 commit 29ce133

7 files changed

+146
-98
lines changed
 

‎a-star/NodeSearchState.js

-23
This file was deleted.

‎a-star/a-greedy-star.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
module.exports = aStarBi;
77

88
var NodeHeap = require('./NodeHeap');
9-
var NodeSearchState = require('./NodeSearchState');
9+
var makeSearchStatePool = require('./makeSearchStatePool');
1010
var heuristics = require('./heuristics');
1111
var defaultSettings = require('./defaultSettings');
1212

@@ -27,9 +27,7 @@ Object.assign(module.exports, heuristics);
2727
*
2828
* @param {Object} options that configures search
2929
* @param {Function(a, b)} options.heuristic - a function that returns estimated distance between
30-
* nodes `a` and `b`. This function should never overestimate actual distance between two
31-
* nodes (otherwise the found path will not be the shortest). Defaults function returns 0,
32-
* which makes this search equivalent to Dijkstra search.
30+
* nodes `a` and `b`. Defaults function returns 0, which makes this search equivalent to Dijkstra search.
3331
* @param {Function(a, b)} options.distance - a function that returns actual distance between two
3432
* nodes `a` and `b`. By default this is set to return graph-theoretical distance (always 1);
3533
*
@@ -45,6 +43,7 @@ function aStarBi(graph, options) {
4543

4644
var distance = options.distance;
4745
if (!distance) distance = defaultSettings.distance;
46+
var pool = makeSearchStatePool();
4847

4948
return {
5049
find: find
@@ -60,6 +59,8 @@ function aStarBi(graph, options) {
6059

6160
if (from === to) return [from]; // trivial case.
6261

62+
pool.reset();
63+
6364
// Maps nodeId to NodeSearchState.
6465
var nodeState = new Map();
6566

@@ -74,7 +75,7 @@ function aStarBi(graph, options) {
7475
});
7576

7677

77-
var startNode = new NodeSearchState(from);
78+
var startNode = pool.createNewState(from);
7879
nodeState.set(fromId, startNode);
7980

8081
// For the first node, fScore is completely heuristic.
@@ -84,7 +85,7 @@ function aStarBi(graph, options) {
8485
openSetFrom.push(startNode);
8586
startNode.open = BY_FROM;
8687

87-
var endNode = new NodeSearchState(to);
88+
var endNode = pool.createNewState(to);
8889
endNode.fScore = heuristic(to, from);
8990
endNode.distanceToSource = 0;
9091
openSetTo.push(endNode);
@@ -155,7 +156,7 @@ function aStarBi(graph, options) {
155156
function visitNode(otherNode, link, cameFrom) {
156157
var otherSearchState = nodeState.get(otherNode.id);
157158
if (!otherSearchState) {
158-
otherSearchState = new NodeSearchState(otherNode);
159+
otherSearchState = pool.createNewState(otherNode);
159160
nodeState.set(otherNode.id, otherSearchState);
160161
}
161162

‎a-star/a-star.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
module.exports = aStarPathSearch;
99

1010
var NodeHeap = require('./NodeHeap');
11-
var NodeSearchState = require('./NodeSearchState');
11+
var makeSearchStatePool = require('./makeSearchStatePool');
1212
var heuristics = require('./heuristics');
1313
var defaultSettings = require('./defaultSettings.js');
1414

@@ -41,6 +41,7 @@ function aStarPathSearch(graph, options) {
4141

4242
var distance = options.distance;
4343
if (!distance) distance = defaultSettings.distance;
44+
var pool = makeSearchStatePool();
4445

4546
return {
4647
/**
@@ -56,6 +57,7 @@ function aStarPathSearch(graph, options) {
5657
if (!from) throw new Error('fromId is not defined in this graph: ' + fromId);
5758
var to = graph.getNode(toId);
5859
if (!to) throw new Error('toId is not defined in this graph: ' + toId);
60+
pool.reset();
5961

6062
// Maps nodeId to NodeSearchState.
6163
var nodeState = new Map();
@@ -66,7 +68,7 @@ function aStarPathSearch(graph, options) {
6668
setNodeId: defaultSettings.setHeapIndex
6769
});
6870

69-
var startNode = new NodeSearchState(from);
71+
var startNode = pool.createNewState(from);
7072
nodeState.set(fromId, startNode);
7173

7274
// For the first node, fScore is completely heuristic.
@@ -94,7 +96,7 @@ function aStarPathSearch(graph, options) {
9496
function visitNeighbour(otherNode, link) {
9597
var otherSearchState = nodeState.get(otherNode.id);
9698
if (!otherSearchState) {
97-
otherSearchState = new NodeSearchState(otherNode);
99+
otherSearchState = pool.createNewState(otherNode);
98100
nodeState.set(otherNode.id, otherSearchState);
99101
}
100102

‎a-star/makeSearchStatePool.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* This class represents a single search node in the exploration tree for
3+
* A* algorithm.
4+
*
5+
* @param {Object} node original node in the graph
6+
*/
7+
function NodeSearchState(node) {
8+
this.node = node;
9+
10+
// How we came to this node?
11+
this.parent = null;
12+
13+
this.closed = false;
14+
this.open = 0;
15+
16+
this.distanceToSource = Number.POSITIVE_INFINITY;
17+
// the f(n) = g(n) + h(n) value
18+
this.fScore = Number.POSITIVE_INFINITY;
19+
20+
// used to reconstruct heap when fScore is updated.
21+
this.heapIndex = -1;
22+
};
23+
24+
function makeSearchStatePool() {
25+
var currentInCache = 0;
26+
var nodeCache = [];
27+
28+
return {
29+
createNewState: createNewState,
30+
reset: reset
31+
};
32+
33+
function reset() {
34+
currentInCache = 0;
35+
}
36+
37+
function createNewState(node) {
38+
var cached = nodeCache[currentInCache];
39+
if (cached) {
40+
// TODO: This almost duplicates constructor code. Not sure if
41+
// it would impact performance if I move this code into a function
42+
cached.node = node;
43+
// How we came to this node?
44+
cached.parent = null;
45+
46+
cached.closed = false;
47+
cached.open = 0;
48+
49+
cached.distanceToSource = Number.POSITIVE_INFINITY;
50+
// the f(n) = g(n) + h(n) value
51+
cached.fScore = Number.POSITIVE_INFINITY;
52+
53+
// used to reconstruct heap when fScore is updated.
54+
cached.heapIndex = -1;
55+
56+
} else {
57+
cached = new NodeSearchState(node);
58+
nodeCache[currentInCache] = cached;
59+
}
60+
currentInCache++;
61+
return cached;
62+
}
63+
}
64+
module.exports = makeSearchStatePool;

‎a-star/nba.js ‎a-star/nba/index.js

+5-64
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,9 @@
11
module.exports = nba;
22

3-
var NodeHeap = require('./NodeHeap');
4-
var heuristics = require('./heuristics');
5-
var defaultSettings = require('./defaultSettings.js');
6-
7-
function makeSearchStatePool() {
8-
var currentInCache = 0;
9-
var nodeCache = [];
10-
11-
return {
12-
createNewState: createNewState,
13-
reset: reset
14-
};
15-
16-
function reset() {
17-
currentInCache = 0;
18-
}
19-
20-
function createNewState(node) {
21-
var cached = nodeCache[currentInCache];
22-
if (cached) {
23-
cached.node = node;
24-
25-
// How we came to this node?
26-
cached.p1 = null;
27-
cached.p2 = null;
28-
29-
cached.closed = false;
30-
31-
cached.g1 = Number.POSITIVE_INFINITY;
32-
cached.g2 = Number.POSITIVE_INFINITY;
33-
cached.f1 = Number.POSITIVE_INFINITY;
34-
cached.f2 = Number.POSITIVE_INFINITY;
35-
36-
// used to reconstruct heap when fScore is updated.
37-
cached.h1 = -1;
38-
cached.h2 = -1;
39-
} else {
40-
cached = new NBASearchState(node);
41-
nodeCache[currentInCache] = cached;
42-
}
43-
currentInCache++;
44-
return cached;
45-
}
46-
}
47-
48-
function NBASearchState(node) {
49-
this.node = node;
50-
51-
// How we came to this node?
52-
this.p1 = null;
53-
this.p2 = null;
54-
55-
this.closed = false;
56-
57-
this.g1 = Number.POSITIVE_INFINITY;
58-
this.g2 = Number.POSITIVE_INFINITY;
59-
this.f1 = Number.POSITIVE_INFINITY;
60-
this.f2 = Number.POSITIVE_INFINITY;
61-
62-
// used to reconstruct heap when fScore is updated.
63-
this.h1 = -1;
64-
this.h2 = -1;
65-
}
3+
var NodeHeap = require('../NodeHeap');
4+
var heuristics = require('../heuristics');
5+
var defaultSettings = require('../defaultSettings.js');
6+
var makeNBASearchStatePool = require('./makeNBASearchStatePool.js');
667

678
var NO_PATH = defaultSettings.NO_PATH;
689

@@ -78,7 +19,7 @@ function nba(graph, options) {
7819

7920
var distance = options.distance;
8021
if (!distance) distance = defaultSettings.distance;
81-
var pool = makeSearchStatePool();
22+
var pool = makeNBASearchStatePool();
8223

8324
return {
8425
/**

‎a-star/nba/makeNBASearchStatePool.js

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
module.exports = makeNBASearchStatePool;
2+
3+
function makeNBASearchStatePool() {
4+
var currentInCache = 0;
5+
var nodeCache = [];
6+
7+
return {
8+
createNewState: createNewState,
9+
reset: reset
10+
};
11+
12+
function reset() {
13+
currentInCache = 0;
14+
}
15+
16+
function createNewState(node) {
17+
var cached = nodeCache[currentInCache];
18+
if (cached) {
19+
// TODO: This almost duplicates constructor code. Not sure if
20+
// it would impact performance if I move this code into a function
21+
cached.node = node;
22+
23+
// How we came to this node?
24+
cached.p1 = null;
25+
cached.p2 = null;
26+
27+
cached.closed = false;
28+
29+
cached.g1 = Number.POSITIVE_INFINITY;
30+
cached.g2 = Number.POSITIVE_INFINITY;
31+
cached.f1 = Number.POSITIVE_INFINITY;
32+
cached.f2 = Number.POSITIVE_INFINITY;
33+
34+
// used to reconstruct heap when fScore is updated.
35+
cached.h1 = -1;
36+
cached.h2 = -1;
37+
} else {
38+
cached = new NBASearchState(node);
39+
nodeCache[currentInCache] = cached;
40+
}
41+
currentInCache++;
42+
return cached;
43+
}
44+
}
45+
46+
function NBASearchState(node) {
47+
this.node = node;
48+
49+
// How we came to this node?
50+
this.p1 = null;
51+
this.p2 = null;
52+
53+
this.closed = false;
54+
55+
this.g1 = Number.POSITIVE_INFINITY;
56+
this.g2 = Number.POSITIVE_INFINITY;
57+
this.f1 = Number.POSITIVE_INFINITY;
58+
this.f2 = Number.POSITIVE_INFINITY;
59+
60+
// used to reconstruct heap when fScore is updated.
61+
this.h1 = -1;
62+
this.h2 = -1;
63+
}

‎index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = {
22
aStar: require('./a-star/a-star.js'),
33
aGreedy: require('./a-star/a-greedy-star'),
4-
nba: require('./a-star/nba'),
4+
nba: require('./a-star/nba/index.js'),
55
}

0 commit comments

Comments
 (0)
Please sign in to comment.