2017-07-03 11:36:18 +00:00
|
|
|
|
|
|
|
|
CYCLE_LIMIT = 3
|
|
|
|
|
|
2017-07-03 11:55:08 +00:00
|
|
|
|
2017-07-03 11:36:18 +00:00
|
|
|
def rem_routes(routes):
|
|
|
|
|
loop_routes = routes
|
2017-07-03 11:55:08 +00:00
|
|
|
while len(loop_routes) > 0:
|
|
|
|
|
circ, paths, loop_routes = largest_loop(loop_routes)
|
2017-07-03 11:36:18 +00:00
|
|
|
if not circ:
|
|
|
|
|
break
|
|
|
|
|
partial_paths = []
|
|
|
|
|
partial_routes = loop_routes
|
2017-07-03 11:55:08 +00:00
|
|
|
while len(partial_routes) > 0:
|
2017-07-03 11:36:18 +00:00
|
|
|
lp = longest_path(partial_routes)
|
2017-07-03 11:55:08 +00:00
|
|
|
partial_paths.append((lp[-1].dst, lp[0].src))
|
2017-07-03 11:59:37 +00:00
|
|
|
partial_routes = [x for x in partial_routes if x not in lp]
|
2017-07-03 11:36:18 +00:00
|
|
|
return partial_paths
|
|
|
|
|
|
2017-07-03 11:55:08 +00:00
|
|
|
|
2017-07-03 11:36:18 +00:00
|
|
|
def route_deps(routes):
|
|
|
|
|
routes_map = {}
|
|
|
|
|
for r in routes:
|
2017-07-03 11:59:37 +00:00
|
|
|
if r.src in routes_map:
|
2017-07-03 11:36:18 +00:00
|
|
|
routes_map[r.src].append(r)
|
|
|
|
|
else:
|
2017-07-03 11:55:08 +00:00
|
|
|
routes_map[r.src] = [r]
|
2017-07-03 11:59:37 +00:00
|
|
|
if r.dst not in routes_map:
|
2017-07-03 11:55:08 +00:00
|
|
|
routes_map[r.dst] = []
|
2017-07-03 11:36:18 +00:00
|
|
|
return routes_map
|
|
|
|
|
|
2017-07-03 11:55:08 +00:00
|
|
|
|
2017-07-03 11:36:18 +00:00
|
|
|
def largest_loop(routes):
|
|
|
|
|
deps = route_deps(routes)
|
2017-07-03 11:55:08 +00:00
|
|
|
circ_paths = [find_loop(r.src, r.src, deps, set(), []) for r in routes]
|
|
|
|
|
circ, paths = max(circ_paths, key=lambda p: len(p[1]))
|
2017-07-03 11:36:18 +00:00
|
|
|
# print filter(lambda p:not p[0],circ_paths)
|
2017-07-03 11:59:37 +00:00
|
|
|
rem_paths = [x for x in routes if x not in paths]
|
2017-07-03 11:55:08 +00:00
|
|
|
return (circ, paths, rem_paths)
|
|
|
|
|
|
2017-07-03 11:36:18 +00:00
|
|
|
|
|
|
|
|
def longest_path(routes):
|
2017-07-03 11:55:08 +00:00
|
|
|
def route_path(r, deps):
|
2017-07-03 11:59:37 +00:00
|
|
|
if r.dst not in deps or len(deps[r.dst]) == 0:
|
2017-07-03 11:36:18 +00:00
|
|
|
return [r]
|
2017-07-03 11:55:08 +00:00
|
|
|
all_dep_paths = [([r] + route_path(rt, deps)) for rt in deps[r.dst]]
|
|
|
|
|
rp = max(all_dep_paths, key=lambda p: len(p))
|
2017-07-03 11:36:18 +00:00
|
|
|
return rp
|
|
|
|
|
deps = route_deps(routes)
|
2017-07-03 11:55:08 +00:00
|
|
|
all_paths = [route_path(r, deps) for r in routes]
|
|
|
|
|
longest = max(all_paths, key=len)
|
2017-07-03 11:36:18 +00:00
|
|
|
return longest
|
|
|
|
|
|
2017-07-03 11:55:08 +00:00
|
|
|
|
|
|
|
|
def find_loop(elem, dep_elem, deps, checked, path):
|
2017-07-03 11:36:18 +00:00
|
|
|
found_loop = False
|
2017-07-03 11:59:37 +00:00
|
|
|
if dep_elem not in checked and dep_elem in deps:
|
2017-07-03 11:36:18 +00:00
|
|
|
checked.add(dep_elem)
|
|
|
|
|
for c in deps[dep_elem]:
|
|
|
|
|
path.append(c)
|
|
|
|
|
if elem == c.dst and len(path) <= CYCLE_LIMIT:
|
|
|
|
|
found_loop = True
|
|
|
|
|
break
|
2017-07-03 11:55:08 +00:00
|
|
|
(loop, path) = find_loop(elem, c.dst, deps, checked, path)
|
2017-07-03 11:36:18 +00:00
|
|
|
if loop:
|
|
|
|
|
found_loop = True
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
del(path[-1])
|
2017-07-03 11:55:08 +00:00
|
|
|
return (found_loop, path)
|