2

I am trying to obtain all possible ways to go from a city A to a city B on a given day by plane, with a maximum of 2 stops.

I have as input a list of dictionaries:

flights = [
        ...
        {'dep': 'FRA', 'arr': 'AMS', 'dep_dt': '2017-05-01 12:00:00', 'arr_dt': '2017-05-01 13:15:00', 'price': 100},
        {'dep': 'FRA', 'arr': 'CPH', 'dep_dt': '2017-05-01 10:00:00', 'arr_dt': '2017-05-01 12:00:00', 'price': 80},
        {'dep': 'FRA', 'arr': 'MAD', 'dep_dt': '2017-05-01 09:00:00', 'arr_dt': '2017-05-01 10:50:00', 'price': 30},
        {'dep': 'CPH', 'arr': 'AMS', 'dep_dt': '2017-05-01 15:00:00', 'arr_dt': '2017-05-01 16:30:00', 'price': 60},
        {'dep': 'CPH', 'arr': 'MAD', 'dep_dt': '2017-05-01 14:15:00', 'arr_dt': '2017-05-01 17:10:00', 'price': 70},
        {'dep': 'MAD', 'arr': 'AMS', 'dep_dt': '2017-05-01 19:00:00', 'arr_dt': '2017-05-01 21:40:00', 'price': 20},
       ...
    ]

With thousands of records between many cities on many dates.

Example

Let's say I want all possibilities to go from FRA to AMS. To find all possible trips, I've split the problem in 3:

  • Direct flights
  • Flights with 1 stopover
  • Flights with 2 stopovers

(I ommit the date constrains below for simplicity)

In order to get the direct flights, I can do:

direct_flights = [f for f in flights if f['dep']=='FRA' and f['arr']=='AMS']

To get trips with one stopover, I've gone for a nested loop. Not optimal, but it works:

first_segment = [f for f in flights if f['dep']=='FRA']
second_segment = [f for f in flights if f['arr']=='AMS']

flights_w_1stop = []
for s1 in first_segment:
    for s2 in second_segment:
        if (s1['arr'] == s2['dep'] and
            s1['arr_dt'] < s2['dep_dt']):
            flights_w_1stop.append((s1, s2))

Now, to get all trips with two stopovers, I can only come up with a similar approach than above, but this makes two nested loops, which looks horrible and will be very slow when I have many flights.

first_segment = [f for f in flights if f['dep']=='FRA']
second_segment = [f for f in flights]
third_segment = [f for f in flights if f['arr']=='AMS']

flights_w_2stops = []
for s1 in first_segment:
    for s2 in second_segment:
        for s3 in third_segment:
            if (s1['arr'] == s2['dep'] and
                s2['arr'] == s3['dep'] and
                s1['arr_dt'] < s2['dep_dt'] and
                s2['arr_dt'] < s3['dep_dt']):
                flights_w_2stops.append((s1, s2, s3))

Finally, I would merge all 3 different lists with the same data structure and sort them either by price or by total duration.

Question

How could this be done without nested loops?

Note: I have read about graphs, but I don't think I will ever want to consider more than two stopovers. In addition, it would mean learning a new methodology. It is always good to learn, so if it is the best option I would invest the time. But if a similar thing can be done in another way (rearranging the nested loops somehow?), I would prefer so.

I found also this SO question, but I do not see how to apply that to my case.

Community
  • 1
  • 1
J0ANMM
  • 7,849
  • 10
  • 56
  • 90
  • Does your code work at present? If so, it might be better placed at CodeReview rather than here. – asongtoruin Mar 15 '17 at 09:49
  • I'm voting to close this question as off-topic because it belongs to https://codereview.stackexchange.com/ – shad0w_wa1k3r Mar 15 '17 at 09:50
  • Following your advice, I posted the question at CodeReveiw: http://codereview.stackexchange.com/questions/158020/flight-combinations-between-two-cities – J0ANMM Mar 20 '17 at 10:19

0 Answers0