proof of concept

This commit is contained in:
Gabriel Pérez-Cerezo 2021-01-24 01:08:59 +01:00
commit 47c4f164ca

130
tripplan.py Normal file
View File

@ -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))