因此,我列出了公交车可以通过的路线以及每条路线的距离:
routes = {'AB':5, 'BC':4, 'CD':8, 'DC':8, 'DE':6, 'AD':5, 'CE':2, 'EB':3, 'AE':7}
或仅作为列表,因为距离尚不重要:
paths = ['AB', 'BC', 'CD', 'DC', 'DE', 'AD', 'CE', 'EB', 'AE']
现在,我正在尝试获取给定起点和终点的公交车可能采取的路线列表,然后我想尝试合并最大停靠点以限制数据输出。目前为止,我已经有了一个功能:
def route_variations(first_stop, last_stop, max_stops):
possiblepaths = []
for path in paths:
x = path[0] #first letter of each route
if first_stop == x:
possiblepaths.append(path)
for path in paths:
y = path[-1] #last letter of each route
if last_stop == y:
possiblepaths.append(path)
return possiblepaths
例如,如果我想以C开头和结尾
route_variations('C','C', 10)
将返回以C开头并以C结束的路由列表,即。 -> ['CD','CE','BC','DC']
所以现在我也需要连接路由。路线C-E-B-C需要输出中缺少的E-B路线。任何想法如何开始实施?然后加入他们以实现CDC之类的完整路线,而不是CD和DC?
答案 0 :(得分:0)
图论中有众所周知的算法可以找到路径,正如对您的问题的评论所暗示的那样。
但是,仅出于学习目的(严重的是,仅出于学习目的,此代码实际上并不适合此任务的一般情况),我将尝试提供一个结构类似于您的简单示例代码,因此您可以查看获得这些“连接路线”所缺少的内容
基本原理是,当您找到正确的路径(通过比较第一个字母)时,您将查找此路径开头的所有路径,通过从自身内部(即递归)再次调用该函数,并找到第二个字母路径。
paths = ['AB', 'BC', 'CD', 'DC', 'DE', 'AD', 'CE', 'EB', 'AE']
def route_variations(first_stop, last_stop, max_stops):
possible_routes = []
if max_stops == 0 or first_stop == last_stop:
return possible_routes
for path in paths:
x,y = path
if first_stop == x:
if last_stop == y:
possible_routes.append([path])
routes_from_this_stop = route_variations(y, last_stop, max_stops - 1)
possible_routes.extend([[path] + route for route in routes_from_this_stop])
return possible_routes
print(route_variations('A', 'C', 10))
输出为:
[['AB', 'BC'], ['AD', 'DC'], ['AD', 'DE', 'EB', 'BC'], ['AE', 'EB', 'BC']]
注意::如果路线中有圆圈,您会在圆圈中绕过许多类似的路线(长度受max_stops
限制)。
注意2::当开始和停止相同时,这将不起作用,您将得到一个空结果,因此您的特定示例在这里无效:(
答案 1 :(得分:0)
我用itertools和置换解决了它。如果要在大量公交车站上运行它,它可能不是最快的方法,但是在8站以下的组合中,它运行起来相当快。
作为输出,您将获得具有简化路线和总距离的字典:
import itertools
paths = ['AB', 'BC', 'CD', 'DC', 'DE', 'AD', 'CE', 'EB', 'AE']
routes = {'AB':5, 'BC':4, 'CD':8, 'DC':8, 'DE':6, 'AD':5, 'CE':2, 'EB':3, 'AE':7}
def route_variations(first_stop, last_stop, max_length):
valid_routes = []
for n in list(range(2, max_length+1)):
combinations = itertools.product(paths, repeat=n)
for combination in combinations:
print (combination)
for i in list(range(n)):
if i == 0:
if combination[i][0] != first_stop:
break
elif i != 0 and i != n-1:
if combination[i][0] != combination[i-1][1]:
break
elif i == n-1:
if combination[i][0] == combination[i-1][1] and combination[i][1] == last_stop:
valid_routes.append(combination)
else:
break
result = {}
for route in valid_routes:
route_simple = ""
dist = 0
for j in route:
dist += routes.get(j)
if route.index(j) == 0:
route_simple += str(j)
else:
route_simple += str(j[1])
result[route_simple] = dist
return result
print(route_variations('A', 'C', 6))