我有多个管道名称列表和相应的联结名称列表。
我还有两个包含上游和下游的列表 管道的连接处(To和From)。
例如
Pipes = [4000111858, 4000111839, 4000111848, 4000111871]
Junction = [4000068991, 4000068981, 4000069000, 4000069012, 4000237981]
From = [4000068991, 4000068981, 4000069000, 4000069012]
To = [4000069012, 4000068991, 4000069012, 4000237981]
我能够找到序列中的最后一个结点,因为它不会从列表(插座)中找到,然后从这里找到最后一个管道。
Outlet = []
Outlet_Pipe = []
for j in Junction:
if j not in From:
Outlet.append(j)
for j, value in enumerate(Junction, -1):
if value in Outlet:
Outlet_Pipe.append(Pipes[j])
我需要构建从上游到下游的所有可能管道序列的列表(或多个列表)。 即:
[4000111839,4000111858, 4000111871] and [4000111848, 4000111871]
答案 0 :(得分:0)
我稍微调整了一下你的网络,看看我的代码如何对抗分叉
import collections
import itertools
Pipe = collections.namedtuple('Pipe', 'pipe start end')
all_pipes = [Pipe(pipe='A', start='a', end='d'),
Pipe(pipe='B', start='b', end='a'),
Pipe(pipe='C', start='c', end='d'),
Pipe(pipe='D', start='d', end='e'),
Pipe(pipe='E', start='d', end='f'),
]
如果您只有Pipes
,From
和To
的列表,则可以像这样创建该列表:
all_pipes = [Pipe(*pipe) for pipe in zip(Pipes, From, To)]
class PipeNetwork():
def __init__(self, pipes):
self.pipes = pipes
names, start, end = list(zip(*pipes))
self.junctions = set(start + end) # ['a', 'b', 'c', 'd', 'e', 'f']
self.end_points = [k for k, v in collections.Counter(start + end).items() if v == 1]
# ['b', 'c', 'e', 'f']
self.pipes_started = collections.defaultdict(set)
self.pipes_ended = collections.defaultdict(set)
for pipe in pipes:
self.pipes_started[pipe.start].add(pipe)
self.pipes_ended[pipe.end].add(pipe)
这是一个单向管道类。您需要对双向管道稍作调整
检查从point
开始在管道另一端开始的路径的所有管道
def find_routes_from(self, point, route=None):
# print(route)
if route is None:
route = [point]
elif point in route:
raise ValueError('circular route')
# or `return None`
else:
route = route + [point]
if point not in self.pipes_started:
return [route] if len(route) > 1 else None
# print(self.pipes_started[point])
return [r for p in self.pipes_started[point] for r in self.find_routes_from(p.end, route) if r]
这会询问从所有端点开始的路径,这些端点有管道离开它们(返回一个可迭代的
) @property
def all_routes(self):
return itertools.chain().from_iterable(self.find_routes_from(p) for p in self.end_points if p in self.pipes_started)
net = PipeNetwork(pipes=all_pipes)
list(net.all_routes)
产量
[['b', 'a', 'd', 'f'], ['b', 'a', 'd', 'e'], ['c', 'd', 'f'], ['c', 'd', 'e']]