diff --git a/.gitignore b/.gitignore index bdaab25..c2e4259 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,105 @@ env/ + +# Created by https://www.gitignore.io/api/python + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# End of https://www.gitignore.io/api/python diff --git a/cyclic_contracts.py b/cyclic_contracts.py index 7c1552e..cd897a1 100644 --- a/cyclic_contracts.py +++ b/cyclic_contracts.py @@ -1,3 +1,4 @@ +from cyclic_utils import CYCLE_LIMIT,rem_routes class Route(object): """docstring for Route.""" @@ -66,69 +67,6 @@ class Transporter(object): if len(unfulfilled) > 0: print "Contracts from ",repr(unfulfilled) -CYCLE_LIMIT = 3 - -def rem_routes(routes): - loop_routes = routes - while len(loop_routes)>0: - circ,paths,loop_routes = largest_loop(loop_routes) - if not circ: - break - partial_paths = [] - partial_routes = loop_routes - while len(partial_routes)>0: - lp = longest_path(partial_routes) - partial_paths.append((lp[-1].dst,lp[0].src)) - partial_routes = filter(lambda x:x not in lp,partial_routes) - return partial_paths - -def route_deps(routes): - routes_map = {} - for r in routes: - if routes_map.has_key(r.src): - routes_map[r.src].append(r) - else: - routes_map[r.src]= [r] - if not routes_map.has_key(r.dst): - routes_map[r.dst]= [] - return routes_map - -def largest_loop(routes): - deps = route_deps(routes) - 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])) - # print filter(lambda p:not p[0],circ_paths) - rem_paths = filter(lambda x:x not in paths,routes) - return (circ,paths,rem_paths) - -def longest_path(routes): - def route_path(r,deps): - if not deps.has_key(r.dst) or len(deps[r.dst])==0: - return [r] - all_dep_paths = [([r]+route_path(rt,deps)) for rt in deps[r.dst]] - rp = max(all_dep_paths,key=lambda p:len(p)) - return rp - deps = route_deps(routes) - all_paths = [route_path(r,deps) for r in routes] - longest = max(all_paths,key=len) - return longest - -def find_loop(elem,dep_elem,deps,checked,path): - found_loop = False - if dep_elem not in checked and deps.has_key(dep_elem): - 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 - (loop,path) = find_loop(elem,c.dst,deps,checked,path) - if loop: - found_loop = True - break - else: - del(path[-1]) - return (found_loop,path) # Transporter.from_file('./contracts.txt').contracts_required() diff --git a/cyclic_utils.py b/cyclic_utils.py new file mode 100644 index 0000000..40dcf55 --- /dev/null +++ b/cyclic_utils.py @@ -0,0 +1,64 @@ + +CYCLE_LIMIT = 3 + +def rem_routes(routes): + loop_routes = routes + while len(loop_routes)>0: + circ,paths,loop_routes = largest_loop(loop_routes) + if not circ: + break + partial_paths = [] + partial_routes = loop_routes + while len(partial_routes)>0: + lp = longest_path(partial_routes) + partial_paths.append((lp[-1].dst,lp[0].src)) + partial_routes = filter(lambda x:x not in lp,partial_routes) + return partial_paths + +def route_deps(routes): + routes_map = {} + for r in routes: + if routes_map.has_key(r.src): + routes_map[r.src].append(r) + else: + routes_map[r.src]= [r] + if not routes_map.has_key(r.dst): + routes_map[r.dst]= [] + return routes_map + +def largest_loop(routes): + deps = route_deps(routes) + 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])) + # print filter(lambda p:not p[0],circ_paths) + rem_paths = filter(lambda x:x not in paths,routes) + return (circ,paths,rem_paths) + +def longest_path(routes): + def route_path(r,deps): + if not deps.has_key(r.dst) or len(deps[r.dst])==0: + return [r] + all_dep_paths = [([r]+route_path(rt,deps)) for rt in deps[r.dst]] + rp = max(all_dep_paths,key=lambda p:len(p)) + return rp + deps = route_deps(routes) + all_paths = [route_path(r,deps) for r in routes] + longest = max(all_paths,key=len) + return longest + +def find_loop(elem,dep_elem,deps,checked,path): + found_loop = False + if dep_elem not in checked and deps.has_key(dep_elem): + 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 + (loop,path) = find_loop(elem,c.dst,deps,checked,path) + if loop: + found_loop = True + break + else: + del(path[-1]) + return (found_loop,path)