Skip to content

Commit

Permalink
Merge pull request #39 from bemisguided/feat/blocked-paths-with-docs
Browse files Browse the repository at this point in the history
feat: add blocked() to NBA path finder. add documentation of feature
  • Loading branch information
anvaka authored Aug 14, 2023
2 parents 7946996 + 116c912 commit 133f38e
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 0 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,47 @@ let pathFinder = aStar(graph, {
});
```

## blocked paths

In scenarios where a path might be temporarily blocked between two nodes a `blocked()` function
may be supplied to resolve blocked routes during path finding.

For example, train routes with service disruptions could be modelled as follows:

``` js
let createGraph = require('ngraph.graph');
let graph = createGraph();

// Our graph has cities:
graph.addNode('NYC');
graph.addNode('Philadelphia');
graph.addNode('Baltimore');
graph.addNode('Pittsburgh');
graph.addNode('Washington');

// and railroads:
graph.addLink('NYC', 'Philadelphia', { disruption: false });
graph.addLink('Philadelphia', 'Baltimore', { disruption: true });
graph.addLink('Philadelphia', 'Pittsburgh', { disruption: false });
graph.addLink('Pittsburgh', 'Washington', { disruption: false });
graph.addLink('Baltimore', 'Washington', { disruption: false });
```

While the Philadelphia to Baltimore route is facing a service disruption, the alternative
route to Washington is via Pittsburgh. The following is an example `blocked()` function implementation
that may be supplied to yield this result:

``` js
let path = require('ngraph.path');

let pathFinder = path.aStar(graph, {
blocked(fromNode, toNode, link) {
return link.data.disruption;
},
});
let result = pathFinder.find('NYC', 'Washington');
```

## available finders

The library implements a few A* based path finders:
Expand Down
3 changes: 3 additions & 0 deletions a-star/a-greedy-star.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ module.exports.l1 = heuristics.l1;
* @param {ngraph.graph} graph instance. See https://github.com/anvaka/ngraph.graph
*
* @param {Object} options that configures search
* @param {Function(a, b, link)} options.blocked - a function that returns `true` if the link between
* nodes `a` and `b` are blocked paths. This function is useful for temporarily blocking routes
* while allowing the graph to be reused without rebuilding.
* @param {Function(a, b)} options.heuristic - a function that returns estimated distance between
* nodes `a` and `b`. Defaults function returns 0, which makes this search equivalent to Dijkstra search.
* @param {Function(a, b)} options.distance - a function that returns actual distance between two
Expand Down
3 changes: 3 additions & 0 deletions a-star/a-star.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ module.exports.l1 = heuristics.l1;
*
* @param {ngraph.graph} graph instance. See https://github.com/anvaka/ngraph.graph
* @param {Object} options that configures search
* @param {Function(a, b, link)} options.blocked - a function that returns `true` if the link between
* nodes `a` and `b` are blocked paths. This function is useful for temporarily blocking routes
* while allowing the graph to be reused without rebuilding.
* @param {Function(a, b)} options.heuristic - a function that returns estimated distance between
* nodes `a` and `b`. This function should never overestimate actual distance between two
* nodes (otherwise the found path will not be the shortest). Defaults function returns 0,
Expand Down
10 changes: 10 additions & 0 deletions a-star/nba/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ module.exports.l1 = heuristics.l1;
*
* @param {ngraph.graph} graph instance. See https://github.com/anvaka/ngraph.graph
* @param {Object} options that configures search
* @param {Function(a, b, link)} options.blocked - a function that returns `true` if the link between
* nodes `a` and `b` are blocked paths. This function is useful for temporarily blocking routes
* while allowing the graph to be reused without rebuilding.
* @param {Function(a, b)} options.heuristic - a function that returns estimated distance between
* nodes `a` and `b`. This function should never overestimate actual distance between two
* nodes (otherwise the found path will not be the shortest). Defaults function returns 0,
Expand All @@ -37,6 +40,9 @@ function nba(graph, options) {
var oriented = options.oriented;
var quitFast = options.quitFast;

var blocked = options.blocked;
if (!blocked) blocked = defaultSettings.blocked;

var heuristic = options.heuristic;
if (!heuristic) heuristic = defaultSettings.heuristic;

Expand Down Expand Up @@ -178,6 +184,8 @@ function nba(graph, options) {

if (otherSearchState.closed) return;

if (blocked(cameFrom.node, otherNode, link)) return;

var tentativeDistance = cameFrom.g1 + distance(cameFrom.node, otherNode, link);

if (tentativeDistance < otherSearchState.g1) {
Expand Down Expand Up @@ -206,6 +214,8 @@ function nba(graph, options) {

if (otherSearchState.closed) return;

if (blocked(cameFrom.node, otherNode, link)) return;

var tentativeDistance = cameFrom.g2 + distance(cameFrom.node, otherNode, link);

if (tentativeDistance < otherSearchState.g2) {
Expand Down
23 changes: 23 additions & 0 deletions test/nba.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,29 @@ test('it can find path', t => {
t.end();
});

test('it can find path with blocked links', t => {
let graph = createGraph();

graph.addLink('a', 'b', {blocked: true});
graph.addLink('a', 'c', {blocked: false});
graph.addLink('c', 'd', {blocked: false});
graph.addLink('b', 'd', {blocked: false});


var pathFinder = nba(graph, {
blocked(a, b, link) {
return link.data.blocked;
}
});
let path = pathFinder.find('a', 'd');

t.equal(path[0].id, 'd', 'd is here');
t.equal(path[1].id, 'c', 'c is here');
t.equal(path[2].id, 'a', 'a is here');
t.end();
});


test('it can find directed path', t => {
let graph = createGraph();

Expand Down

0 comments on commit 133f38e

Please sign in to comment.