busroute.py

Mon, 11 Dec 2017 12:55:00 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 11 Dec 2017 12:55:00 +0200
changeset 77
83cd29dee853
parent 75
4f8a67d5d79e
child 87
9139a94e540c
permissions
-rw-r--r--

stop_week

#!/usr/bin/env python3

from configparser import ConfigParser
from math import inf
from misc import profile
region_info = ConfigParser()
region_info.read('regions.ini')

def simplify_name(name):
	name = profile['replacements'].get(name, name)
	return name

def reduce_schedule(route, trip_length, whole = False, long = False):
	priorities = profile['priorities']
	length = ((trip_length / 600) * 3 + len(route) * 2) / 5
	if not route:
		return ''
	have_already = set()
	i = 0
	while i < len(route):
		if route[i] in profile['replacements']:
			route[i] = profile['replacements'][route[i]]
		if route[i] in have_already:
			del route[i]
		else:
			have_already.add(route[i])
			i += 1
	from_place = route[0]
	destination = route[-1]
	reitti_arvot = {}
	f = lambda i: i**-0.3
	factor = 1 / max(f(i + 1) for i in range(len(route)))
	while float(priorities.get(route[-1], 0)) < 0:
		del route[-1]
		destination = route[-1]
	for i, stop in enumerate(route):
		# muunna indeksi siten että myöhemmät alueet korostuvat
		i = f(i + 1) * factor
		# ota prioriteetti huomioon, jotkin alueet ovat tärkeämpiä kyltissä kuin toiset
		i *= float(priorities.get(stop, 1))
		reitti_arvot[stop] = i
	# nollaa lähtöpaikan arvo ettei se mitenkään tule kylttiin
	if from_place in reitti_arvot:
		reitti_arvot[from_place] = 0
	# varmista että destination tulee kylttiin
	reitti_arvot[destination] = 1e10
	# muodosta sign-tiedot järjestettynä reittiarvon mukaan
	weights = sorted([
		(stop, reitti_arvot[stop], i) \
		for i, stop in enumerate(route) \
		if reitti_arvot[stop] >= 1
		], key = lambda stop: -stop[1])
	if long:
		weights = weights[:4]
	else:
		# enintään neljä tulee kylttiin
		weights = weights[:3]
		# jos kolmas kylttiarvo ei ole tarpeeksi merkittävä suhteessa reitin pituuteen niin otetaan se pois
		try:
			if weights[2][0] != destination and weights[2][1] < (725 / length ** 0.8):
				del weights[2]
		except IndexError:
			pass
		try:
			if weights[1][0] != destination and weights[1][1] < (500 / length ** 1.15):
				del weights[1]
		except IndexError:
			pass
	# lajitellaan painoarvot uudestaan reittijärjestykseen jotta sign tulee oikeinpäin
	weights = sorted(weights, key = lambda weight_data: weight_data[2])
	# muodostetaan sign..
	sign = [paino[0] for paino in weights]
	to_place = sign[-1]
	old_sign = sign.copy()
	sign = []
	for place in old_sign:
		if place not in sign:
			sign.append(place)
	if whole:
		sign = [from_place] + sign
	if not sign:
		sign = [destination]
	return sign

mercurial