From 47c4f164ca6e0e7e6adca32dd4afc551d6482693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20P=C3=A9rez-Cerezo?= Date: Sun, 24 Jan 2021 01:08:59 +0100 Subject: proof of concept --- tripplan.py | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 tripplan.py diff --git a/tripplan.py b/tripplan.py new file mode 100644 index 0000000..d0cc182 --- /dev/null +++ b/tripplan.py @@ -0,0 +1,130 @@ +#!/usr/bin/python3 +import glob +import os +import sys +TRANSFER_TIME = 2 + +class Line (dict): + def __init__(self, name): + self.name = name + self.stations = [] +def get_next_freq(L, p, tm, rev=False) : + off = L.stations[p][1] + o = "offset" + if rev : + off = L.stations[-1][1] - L.stations[p][1] + o = "roffset" + k = (L[o] + off) % L["frequency"] + while k < tm : + k += L["frequency"] + return k +class Station (dict) : + def __init__(self, code, line, pos): + self.code = code + self.lines = [(line,pos)] + def getlines(self): + return [i[0] for i in self.lines] + def nexttrains(self, tm): + # find next trains departing at stn around tm + trains = [] + for l,p in self.lines : + L = lines[l] + if p < L.nstations-1 : + trains.append((get_next_freq(L,p,tm), l,False)) + if L["rev"] and p > 0: + trains.append((get_next_freq(L,p,tm,True), l,True)) + trains.sort(key=lambda x: x[1]) + return trains + def reachablestations(self, tm, exclude=[]) : + stns = [] + for l,p in self.lines : + if l in exclude: + continue + L = lines[l] + if p < L.nstations-1 : + dep = get_next_freq(L,p,tm) + ors = L.stations[p] + for k in range(p+1,L.nstations) : + stn = L.stations[k] + arr = stn[1] - ors[1] + dep + stns.append((stn[0],dep,arr,L.name,False)) + if L["rev"] and p > 0: + dep = get_next_freq(L,p,tm,True) + ors = L.stations[p] + for k in range(0,p) : + stn = L.stations[k] + arr = ors[1] - stn[1] + dep + stns.append((stn[0],dep,arr,L.name,True)) + + stns.sort(key=lambda x: x[2]) + return stns + + +lines = {} +stations = {} +for k in glob.glob("lines/*") : + if k.endswith("~") : + continue + f = open(k,"r") + l = Line(os.path.basename(k)) + for j in f : + o = j.split() + if j.startswith(" ") : + l[o[0].lower()] = int(o[1]) + else : + l.stations.append((o[0],int(o[1]))) + if not o[0] in stations : + stations[o[0]] = Station(o[0], l.name, len(l.stations)-1) + else : + stations[o[0]].lines.append((l.name, len(l.stations)-1)) + l.nstations = len(l.stations) + lines[l.name] = l +time = 10 + +start = sys.argv[1] +end = sys.argv[2] +end = sys.argv[2] + +if len(sys.argv) > 3 : + TRANSFER_TIME = int(sys.argv[3]) + + + + + +#print(stations["Mar"].reachablestations(49)) +#print(stations["MoC"].reachablestations(49)) + + +Q = stations[start].reachablestations(time) +klines = stations[start].getlines() +prev = {} +d = {} +for k in Q : + prev[k[0]] = (start, k[1], k[2],k[3],k[4]) + d[k[0]] = k[2] +while Q : + u = Q.pop(0) + if u[0] == end : + break + stu = stations[u[0]] + if len(stu.lines)>1 : + R = stu.reachablestations(u[2]+TRANSFER_TIME,klines) + for k in R : + if k[0] not in d or k[2] < d[k[0]] : + prev[k[0]] = (u[0], u[1],u[2],u[3],u[4]) + d[k[0]] = k[2] + Q.append(k) + klines += stu.getlines() + Q.sort(key=lambda i: i[2]) + +translist = [] +while True : + translist.insert(0,u) + u = prev[u[0]] + if u[0] == start : + break +print("Number of Changes: %d, Time needed: %d minutes" % (len(translist)-1, translist[-1][2]-translist[0][1])) +for j in translist : + print("Take line %s to %s at :%02d, arrival :%02d" % (j[3],j[0],j[1] %60,j[2] %60)) + -- cgit v1.2.3