busroute.py

Wed, 26 Sep 2018 13:12:11 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 26 Sep 2018 13:12:11 +0300
changeset 128
7a55abeab5fd
parent 98
c07a77c8a070
permissions
-rw-r--r--

refactor

#!/usr/bin/env python3

from misc import profile
regions = {}

def priority(region_name):
	if region_name in regions:
		return float(regions[region_name]['priority'])
	else:
		return 0

def simplify_name(region_name, replace = False):
	region = regions.get(region_name)
	if region:
		if replace and 'replacement' in region:
			return simplify_name(region['replacement'])
		return region.get('short_name', region_name)
	else:
		return region_name

def greatly_simplify_name(region_name):
	region = regions.get(region_name)
	if region:
		if 'greater_replacement' in region:
			return simplify_name(region['greater_replacement'])
		if 'replacement' in region:
			return simplify_name(region['replacement'])
		else:
			return simplify_name(region_name)
	else:
		return region_name

def reduce_schedule(route, trip_length, whole = False, format = 'medium'):
	length = ((trip_length / 600) * 3 + len(route) * 2) / 5
	have_already = set()
	i = 0
	if not route:
		return ''
	while i < len(route):
		region = regions.get(route[i])
		if region and region.get('replacement'):
			route[i] = region['replacement']
		if not route[i] or route[i] in have_already:
			del route[i]
		else:
			have_already.add(route[i])
			i += 1
	from_place = route[0]
	destination = route[-1]
	route_weights = {}
	f = lambda i: i**-0.3
	factor = 1 / max(f(i + 1) for i in range(len(route)))
	while priority(route[-1]) < 0:
		del route[-1]
		if not route:
			return ''
		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 *= priority(stop)
		route_weights[stop] = i
	# nollaa lähtöpaikan arvo ettei se mitenkään tule kylttiin
	if from_place in route_weights:
		route_weights[from_place] = 0
	# varmista että destination tulee kylttiin
	route_weights[destination] = 1e10
	# muodosta sign-tiedot järjestettynä reittiarvon mukaan
	weights = sorted([
		(stop, route_weights[stop], i) \
		for i, stop in enumerate(route) \
		if route_weights[stop] >= 1
		], key = lambda stop: -stop[1])
	if format == 'long':
		weights = weights[:4]
	elif format == 'short':
		weights = weights[:2]
		# repeat for the second sign value
		try:
			if weights[1][0] != destination and weights[1][1] < (500 / length ** 1.15):
				del weights[1]
		except IndexError:
			pass
	else:
		# enintään neljä tulee kylttiin
		weights = weights[:3]
		# if the third sign value is not significant enough, drop it
		try:
			if weights[2][0] != destination and weights[2][1] < (725 / length ** 0.8):
				del weights[2]
		except IndexError:
			pass
		# repeat for the second sign value
		try:
			if weights[1][0] != destination and weights[1][1] < (500 / length ** 1.15):
				del weights[1]
		except IndexError:
			pass
	# reorder to get the sign the right way around
	weights = sorted(weights, key = lambda weight_data: weight_data[2])
	# form the sign..
	sign = [paino[0] for paino in weights]
	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