k Shortest Paths

Point-in-time, weighted, shortest paths between two endpoints.

The Setup

Finally, we take a moment to run a few weighted shortest path queries. For this, we will use a specific historical version of the graph - the one at the end of the Create section. This graph has Kenny wrongly marked as reporting to Kyle. Let us look at the graph again (reproduced below):

How many paths are there from Kenny to Stan?

Let us first manually enumerate the number of undirected paths (with unique vertices) that go from Kenny to Stan. They are as follows:

#

Path

Length

1

KY -> M -> S

2

2

KY -> KL -> E -> S

3

3

KY -> KL -> M -> S

3

4

KY -> M -> E -> S

3

5

KY -> KL -> E -> M -> S

4

6

KY -> KL -> M -> E -> S

4

7

KY -> M -> KL -> E -> S

4

Let us run some shortest path queries on this past version to see if get the results we expect.

No Weight Function (weight = 1)

Undirected Paths

We have not provided a weight function for the edges. This means every edge carries a default weight of 1. We allow traversing in any direction over all edges. We fix the max depth to 4, and set k = 2 to return the 2 shortest paths.

Request:

Param

Value

timestamp

1588769414.948146

svid

employees/44799683

evid

employees/44794453

depth

4

limit

2

body

{ "edges": {"reporting": "any", "membership": "any"} }

Response:

We get 2 paths, one of length 2, and one of length 3, viz:

#

Path

Length

1

KY -> M -> S

2

2

KY -> M -> E -> S

3

circle-exclamation

Directed Paths

Let us now change the traversal criteria by adding an inbound constraint on the membership edge.

Request:

Param

Value

timestamp

1588769414.948146

svid

employees/44799683

evid

employees/44794453

depth

4

limit

2

body

{ "edges": { "reporting": "any", "membership": "inbound" } }

Response:

We are left with just 1 path that goes exclusively over the reporting edges, of length 3.

Weight as a Function of Edge Collection

Let us cook up an artificial weight function that assigns a heavier weight to the membership edges, say 2. We can do this using the weight function shown in the sections below.

circle-info

Weight functions are defined using the same constructs that are used to build post-filters.

No Vertex/Edge Filters

Request:

Param

Value

timestamp

1588769414.948146

svid

employees/44799683

evid

employees/44794453

depth

4

limit

2

body

{ "edges": { "reporting": "any", "membership": "any" }, "weightExpr": "_id.split('/')[0] === 'membership' ? 2 : 1" }

circle-info

You can go real crazy with post-filter-like expressions, but it is probably best to keep them simple for the sake of readability.

Response:

The 2-hop path now incurs a cost of 4! It is therefore, 2nd in the list.

#

Path

Length

Cost

1

KY -> KY -> E -> S

3

3

2

KY -> M -> S

2

4

No Cartman

Finally, let us add a vertex filter that rejects any path containing Eric as a vertex.

circle-info

Vertex and edge filters also use post-filter syntax.

Request:

Param

Value

timestamp

1588769414.948146

svid

employees/44799683

evid

employees/44794453

depth

4

limit

2

body

{ "edges": { "reporting": "any", "membership": "any" }, "weightExpr": "_id.split('/')[0] === 'membership' ? 2 : 1", "vFilter": "_key !== '44794449'" }

Response:

With Eric out of the loop, our 2-hop path (still with cost 4) emerges on top again!

Eric doesn't like being left out!

Last updated