I develop a routing system to find the best routes by using several mobility offers, e. g. public transport or car pooling. Basically I have nodes, that represent bus stops, train stops etc. These stops include time schedules for each day. Additionally I have pedestrian stops. These stops are connected by relations. If I change from pedestrian to bus, or between bus lines, the relation is called SWITCH_TO. If I drive several stops without changing the service line, the stops are connected by a relation called CONNECTED_TO. If I want to go from point A to point Z and I have to change at bus stop C to another service line at bus stop D the path would look like this:
(A:Stop:Pedestrian)-[SWITCH_TO{switchTime:2}]->
(A:Stop:Bus{serviceLine:1})-[CONNECTED_TO{travelTime:5}]->
(B:Stop:Bus{serviceLine:1})-[CONNECTED_TO{travelTime:6}]->
(C:Stop:Bus{serviceLine:1})-[SWITCH_TO{switchTime:2}]->
(C:Stop:Pedestrian)-[CONNECTED_TO{travelTime:7}]->
(D:Stop:Pedestrian)-[SWITCH_TO{switchTime:2}]->
(D:Stop:Bus{serviceLine:2})-[CONNECTED_TO{travelTime:8}]->(Z:Stop:Bus{serviceLine:2})-[SWITCH_TO{switchTime:2}]->
(Z:Stop:Pedestrian)
I want to calculate based on a desired departure time (alternatively a desired arrival time) of the user the full travel time and get the 5 best connections (less time). In the example above you can see, that the SWITCH_TO relation has a switchTime of 2. This means that I need 2 minutes to switch from the current place to the bus stop (e.g. I have to look for it). The CONNECTED_TO relation travelTimes are the time periods, that the bus needs to go from one stop to another. Lets assume that I want to start at 7:00. The first switch needs 2 minutes. Therefore I have to look at the schedule of (A:Stop:Bus) if there is a departure after 7:02. Lets assume the next departure is at 7:10. then I have to wait 8 minutes. This waiting time is no fixed value but a variable time period for each specific request. I start at 7:10. I need 5+6=11 minutes to go to stop (C:Stop:Bus) and 2 minutes to go off the bus (switch to). Then I have to go 7 minutes by foot. So if have to check the schedule of service line 2. If there is a departure after 7:00+2+8+5+6+2+7+2 = 7:32, take this. If the next departure is at 7:35 I will reach my destination at 7:00+2+8+5+6+2+7+2+3+8+2= 7:45. I know, I bit complex. :)
I prepared an example here:
CREATE (newStop:Stop:Pedestrian {
stopName : 'A-Pedestrian',
mode : 'Pedestrian'
})
RETURN newStop;
CREATE (newStop:Stop:Bus {
stopName : 'A-Bus',
mode : 'Bus',
serviceLine : '1',
monday:[510,610,710,810,835,910],
tuesday:[510,610,710,810,835,910],
wednesday:[510,610,710,810,835,910],
thursday:[510,610,710,810,835,910],
friday:[510,610,710,810,835,910],
saturday:[510,610,710,810,835,910],
sunday:[510,610,710,810,835,910]
})
RETURN newStop;
CREATE (newStop:Stop:Bus {
stopName : 'B-Bus',
mode : 'Bus',
serviceLine : '1',
monday:[515,615,715,815,840,915],
tuesday:[515,615,715,815,840,915],
wednesday:[515,615,715,815,840,915],
thursday:[515,615,715,815,840,915],
friday:[515,615,715,815,840,915],
saturday:[515,615,715,815,840,915],
sunday:[515,615,715,815,840,915]
})
RETURN newStop;
CREATE (newStop:Stop:Bus {
stopName : 'C-Bus',
mode : 'Bus',
serviceLine : '1',
monday:[521,621,711,821,846,921],
tuesday:[521,621,711,821,846,921],
wednesday:[521,621,711,821,846,921],
thursday:[521,621,711,821,846,921],
friday:[521,621,711,821,846,921],
saturday:[521,621,711,821,846,921],
sunday:[521,621,711,821,846,921]
})
RETURN newStop;
CREATE (newStop:Stop:Pedestrian {
stopName : 'C-Pedestrian',
mode : 'Pedestrian'
})
RETURN newStop;
CREATE (newStop:Stop:Pedestrian {
stopName : 'D-Pedestrian',
mode : 'Pedestrian'
})
RETURN newStop;
CREATE (newStop:Stop:Bus {
stopName : 'D-Bus',
mode : 'Bus',
serviceLine : '2',
monday:[535,635,735,835,935],
tuesday:[535,635,735,835,935],
wednesday:[535,635,735,835,935],
thursday:[535,635,735,835,935],
friday:[535,635,735,835,935],
saturday:[535,635,735,835,935],
sunday:[]
})
RETURN newStop;
CREATE (newStop:Stop:Bus {
stopName : 'Z-Bus',
mode : 'Bus',
serviceLine : '2',
monday:[543,643,743,843,943],
tuesday:[543,643,743,843,943],
wednesday:[543,643,743,843,943],
thursday:[543,643,743,843,943],
friday:[543,643,743,843,943],
saturday:[543,643,743,843,943],
sunday:[]
})
RETURN newStop;
CREATE (newStop:Stop:Pedestrian {
stopName : 'Z-Pedestrian',
mode : 'Pedestrian'
})
RETURN newStop;
MATCH (s1:Stop), (s2:Stop)
WHERE s1.stopName = 'A-Pedestrian' AND s2.stopName = 'A-Bus'
CREATE
(s1)-[r:SWITCH_TO{ switchTime : 2 } ]->(s2)
RETURN s1, s2, r;
MATCH (s1:Stop), (s2:Stop)
WHERE s1.stopName = 'A-Bus' AND s2.stopName = 'B-Bus'
CREATE
(s1)-[r:CONNECTED_TO{ travelTime : 5 } ]->(s2)
RETURN s1, s2, r;
MATCH (s1:Stop), (s2:Stop)
WHERE s1.stopName = 'B-Bus' AND s2.stopName = 'C-Bus'
CREATE
(s1)-[r:CONNECTED_TO{ travelTime : 6 } ]->(s2)
RETURN s1, s2, r;
MATCH (s1:Stop), (s2:Stop)
WHERE s1.stopName = 'C-Bus' AND s2.stopName = 'C-Pedestrian'
CREATE
(s1)-[r:SWITCH_TO{ switchTime : 2 } ]->(s2)
RETURN s1, s2, r;
MATCH (s1:Stop), (s2:Stop)
WHERE s1.stopName = 'C-Pedestrian' AND s2.stopName = 'D-Pedestrian'
CREATE
(s1)-[r:CONNECTED_TO{ travelTime : 7 } ]->(s2)
RETURN s1, s2, r;
MATCH (s1:Stop), (s2:Stop)
WHERE s1.stopName = 'D-Pedestrian' AND s2.stopName = 'D-Bus'
CREATE
(s1)-[r:SWITCH_TO{ switchTime : 2 } ]->(s2)
RETURN s1, s2, r;
MATCH (s1:Stop), (s2:Stop)
WHERE s1.stopName = 'D-Bus' AND s2.stopName = 'Z-Bus'
CREATE
(s1)-[r:CONNECTED_TO{ travelTime : 8 } ]->(s2)
RETURN s1, s2, r;
MATCH (s1:Stop), (s2:Stop)
WHERE s1.stopName = 'Z-Bus' AND s2.stopName = 'Z-Pedestrian'
CREATE
(s1)-[r:SWITCH_TO{ switchTime : 2 } ]->(s2)
RETURN s1, s2, r;
As you can see, in some stops, the int array of departure times could be empty too (if no connection is provided on these days). Pedestrian stops dont include an schedule of course. My question is: How can I do this query by cypher? I have to sum up these times to choose the correct next departure time. I have to know when I am at my destination. And I want to show the user the best 5 connections. Is there a way to do this? If not, any suggestions how to solve this?
Thank you very much! Stefan
Edit1: Is there a way to develop this in Java? In the simplest case it could be just one shortest path but with an intelligent cost function? Instead of using fix values using a function to calculate the cost of one specific edge? Any help would be appreciated!