summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Pérez-Cerezo <gabriel@gpcf.eu>2021-01-24 01:08:59 +0100
committerGabriel Pérez-Cerezo <gabriel@gpcf.eu>2021-01-24 01:08:59 +0100
commit47c4f164ca6e0e7e6adca32dd4afc551d6482693 (patch)
tree238824f1395535b373e9d4afa1d1d82ff510b009
downloadlifotripplanner-47c4f164ca6e0e7e6adca32dd4afc551d6482693.tar.gz
lifotripplanner-47c4f164ca6e0e7e6adca32dd4afc551d6482693.tar.bz2
lifotripplanner-47c4f164ca6e0e7e6adca32dd4afc551d6482693.zip
proof of concept
-rw-r--r--tripplan.py130
1 files changed, 130 insertions, 0 deletions
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))
+