Planning, Logistics, and Operations: Modeling the London Tube Network
Let's take a look at a tutorial that shows how to build a detailed model of a real-world system, such as the London Tube network.
Join the DZone community and get the full member experience.
Join For FreeWe know Grakn can be leveraged to model highly complex data, but how do we go about building a detailed model of a real-world system?
Here, we delve into Transport for London (TFL) data to understand and gain insights into the operation of the London Underground Network.
We go on to build surely the most desirable tool for such a network: a journey planner. (Because who doesn't want to shave 0.3 minutes off their commute?)
All of the code is written in Python and Graql, using the Grakn Python Client, and is available on GitHub as the first of a series of examples.
The Schema
In case you really want to get in deep with this example, you'll need to know the schema that we're using.
The first thing you notice about this schema (source code) is that it's compact, considering that it holds a fundamental representation of a whole transportation network.
The reason for this is that Graql is very expressive, allowing us to quickly interrelate concepts that we are already familiar with. More on how to design an intuitive schema in an upcoming article.
What Does Grakn Give Us?
Let's dive straight in to show how short Graql queries can reason to answer questions that would be strenuous to achieve with any other system.
Maybe we want to know the points where we can change to another line as a shortcut. So we have a question such as:
"Which stations are common to the Piccadilly and Victoria lines?"
Answer: Finsbury Park, King's Cross St. Pancras, Green Park
import grakn
client = grakn.Client(uri="http://localhost:4567", keyspace="tube_example")
tube_lines = client.execute(("match $s isa station, has name $n;\n"
"$v isa tube-line, has name \"Victoria\";\n"
"$p isa tube-line, has name \"Piccadilly\";\n"
"$r1(stop: $s, route-operator: $v) isa route;\n"
"$r2(stop: $s, route-operator: $p) isa route;\n"
"get $n;"))
print([tube_line["n"]["value"] for tube_line in tube_lines])
# Result:
# ['Finsbury Park Underground Station',
# "King's Cross St. Pancras Underground Station",
# 'Green Park Underground Station']
If we're an employee at TFL analyzing the tube, we might want to find discrepancies in the timetable data. Specifically, we might look for tube lines that are predicted to take different amounts of time between the same 2 stations. This might indicate a problem with one line compared to another.
# In pure Graql, to be executed using the Graql console, Grakn Dashboard or your
# choice of client
# Use the console in the Grakn dashboard to execute multi-line queries
# Do all tube lines take the same amount of time to travel between 2 stations?
match
$s1 isa station, has name $n1;
$s2 isa station, has name $n2;
$t(beginning: $s1, end: $s2) isa tunnel;
$t(service: $rs1);
$t(service: $rs2);
$rs1 isa route-section has duration $d1;
$rs2 isa route-section has duration $d2;
(section: $rs1, route-operator: $tl1) isa route;
(section: $rs2, route-operator: $tl2) isa route;
$tl1 isa tube-line, has name $tl1-name;
$tl2 isa tube-line, has name $tl2-name;
$d1 != $d2;
$tl1 != $tl2;
limit 1; get $n1, $n2, $tl1-name, $tl2-name, $d1, $d2;
# Result returned, limited to 1 for demonstration:
$n1 val "Notting Hill Gate Underground Station" isa name;
$n2 val "High Street Kensington Underground Station" isa name;
$d1 val 4 isa duration;
$d2 val 3 isa duration;
$tl1-name val "District" isa name;
$tl2-name val "Circle" isa name;
We find that there are many points on the network where this occurs. For example, from Notting Hill Gate to High Street Kensington takes 1 minute less for the Circle line than it does the District line. (Although this may not surprise you...)
Journey Planner
We can use Grakn to build rich applications, leveraging Grakn at runtime for database queries. This tool is available in the repo at visualisation/app.py
The map is built by querying for the latitude and longitude of each station and querying for tunnels that interconnect pairs of stations. Then we ask for the tube lines that pass through a tunnel in order to render a colored line for each tube-line.
You can see that although Grakn is storing complex data in a complex structure, it is quite straightforward to generate a simplified representation similar to the map issued by TFL.
Centrality
Once we have the map, we can use Grakn's distributed analytics to glean, by a certain metric, the most inter-connected stations. (For a deep dive into analytics, see Jason's blog post.)
It's very useful for research for when you realize your neighbor/flatmate is unbearable and you need to move somewhere well-connected in a hurry.
With the map running, press d
to see infographic style, the number of other stations each station is directly connected to.
Clear winners are stations such as King's Cross St. Pancras, Baker Street and Oxford Circus. There are several other methods available in Grakn to measure centrality. To query for this in Grakn is as simple as:
compute centrality of station, in [station, tunnel], using degree;
Shortest Path for Journey Planning
This app also uses Grakn to let a user visualize the shortest number of stops to get from A to B.
It's as simple as
shift+clicking
on the start and end stations. The Python app finds the IDs of the stations and asks Grakn:
compute path from "V90192", to "V1191984", in [station, tunnel];
It doesn't stop there, because clearly there may be more than one way to get make a journey in the same number of stops. Grakn returns all of them, and the app plots them all.
This way, akin to Citymapper, the user can find a variety of options, one of which might be more beneficial for them in their circumstance.
What About From A to B to C?
Shopping at Oxford Circus before you head to King's Cross St. Pancras for your Cambridge train?
Easy, just shift-click on a third station to add the path from B to C to the map.
Your Graknable Ideas
Hopefully, this use-case has given you some new thoughts on how to use Grakn to power your own projects, whether or not they're more glamorous than the tube network.
Of course, be sure to check out the code as a Python basis for your own ideas.
Published at DZone with permission of James Fletcher, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments