Spaces:
Running
Running
""" | |
Read graphs in LEDA format. | |
LEDA is a C++ class library for efficient data types and algorithms. | |
Format | |
------ | |
See http://www.algorithmic-solutions.info/leda_guide/graphs/leda_native_graph_fileformat.html | |
""" | |
# Original author: D. Eppstein, UC Irvine, August 12, 2003. | |
# The original code at http://www.ics.uci.edu/~eppstein/PADS/ is public domain. | |
__all__ = ["read_leda", "parse_leda"] | |
import networkx as nx | |
from networkx.exception import NetworkXError | |
from networkx.utils import open_file | |
def read_leda(path, encoding="UTF-8"): | |
"""Read graph in LEDA format from path. | |
Parameters | |
---------- | |
path : file or string | |
File or filename to read. Filenames ending in .gz or .bz2 will be | |
uncompressed. | |
Returns | |
------- | |
G : NetworkX graph | |
Examples | |
-------- | |
G=nx.read_leda('file.leda') | |
References | |
---------- | |
.. [1] http://www.algorithmic-solutions.info/leda_guide/graphs/leda_native_graph_fileformat.html | |
""" | |
lines = (line.decode(encoding) for line in path) | |
G = parse_leda(lines) | |
return G | |
def parse_leda(lines): | |
"""Read graph in LEDA format from string or iterable. | |
Parameters | |
---------- | |
lines : string or iterable | |
Data in LEDA format. | |
Returns | |
------- | |
G : NetworkX graph | |
Examples | |
-------- | |
G=nx.parse_leda(string) | |
References | |
---------- | |
.. [1] http://www.algorithmic-solutions.info/leda_guide/graphs/leda_native_graph_fileformat.html | |
""" | |
if isinstance(lines, str): | |
lines = iter(lines.split("\n")) | |
lines = iter( | |
[ | |
line.rstrip("\n") | |
for line in lines | |
if not (line.startswith(("#", "\n")) or line == "") | |
] | |
) | |
for i in range(3): | |
next(lines) | |
# Graph | |
du = int(next(lines)) # -1=directed, -2=undirected | |
if du == -1: | |
G = nx.DiGraph() | |
else: | |
G = nx.Graph() | |
# Nodes | |
n = int(next(lines)) # number of nodes | |
node = {} | |
for i in range(1, n + 1): # LEDA counts from 1 to n | |
symbol = next(lines).rstrip().strip("|{}| ") | |
if symbol == "": | |
symbol = str(i) # use int if no label - could be trouble | |
node[i] = symbol | |
G.add_nodes_from([s for i, s in node.items()]) | |
# Edges | |
m = int(next(lines)) # number of edges | |
for i in range(m): | |
try: | |
s, t, reversal, label = next(lines).split() | |
except BaseException as err: | |
raise NetworkXError(f"Too few fields in LEDA.GRAPH edge {i+1}") from err | |
# BEWARE: no handling of reversal edges | |
G.add_edge(node[int(s)], node[int(t)], label=label[2:-2]) | |
return G | |