Spaces:
Sleeping
Sleeping
| """ | |
| Generators for the small graph atlas. | |
| """ | |
| import gzip | |
| import importlib.resources | |
| import os | |
| import os.path | |
| from itertools import islice | |
| import networkx as nx | |
| __all__ = ["graph_atlas", "graph_atlas_g"] | |
| #: The total number of graphs in the atlas. | |
| #: | |
| #: The graphs are labeled starting from 0 and extending to (but not | |
| #: including) this number. | |
| NUM_GRAPHS = 1253 | |
| #: The path to the data file containing the graph edge lists. | |
| #: | |
| #: This is the absolute path of the gzipped text file containing the | |
| #: edge list for each graph in the atlas. The file contains one entry | |
| #: per graph in the atlas, in sequential order, starting from graph | |
| #: number 0 and extending through graph number 1252 (see | |
| #: :data:`NUM_GRAPHS`). Each entry looks like | |
| #: | |
| #: .. sourcecode:: text | |
| #: | |
| #: GRAPH 6 | |
| #: NODES 3 | |
| #: 0 1 | |
| #: 0 2 | |
| #: | |
| #: where the first two lines are the graph's index in the atlas and the | |
| #: number of nodes in the graph, and the remaining lines are the edge | |
| #: list. | |
| #: | |
| #: This file was generated from a Python list of graphs via code like | |
| #: the following:: | |
| #: | |
| #: import gzip | |
| #: from networkx.generators.atlas import graph_atlas_g | |
| #: from networkx.readwrite.edgelist import write_edgelist | |
| #: | |
| #: with gzip.open('atlas.dat.gz', 'wb') as f: | |
| #: for i, G in enumerate(graph_atlas_g()): | |
| #: f.write(bytes(f'GRAPH {i}\n', encoding='utf-8')) | |
| #: f.write(bytes(f'NODES {len(G)}\n', encoding='utf-8')) | |
| #: write_edgelist(G, f, data=False) | |
| #: | |
| # Path to the atlas file | |
| ATLAS_FILE = importlib.resources.files("networkx.generators") / "atlas.dat.gz" | |
| def _generate_graphs(): | |
| """Sequentially read the file containing the edge list data for the | |
| graphs in the atlas and generate the graphs one at a time. | |
| This function reads the file given in :data:`.ATLAS_FILE`. | |
| """ | |
| with gzip.open(ATLAS_FILE, "rb") as f: | |
| line = f.readline() | |
| while line and line.startswith(b"GRAPH"): | |
| # The first two lines of each entry tell us the index of the | |
| # graph in the list and the number of nodes in the graph. | |
| # They look like this: | |
| # | |
| # GRAPH 3 | |
| # NODES 2 | |
| # | |
| graph_index = int(line[6:].rstrip()) | |
| line = f.readline() | |
| num_nodes = int(line[6:].rstrip()) | |
| # The remaining lines contain the edge list, until the next | |
| # GRAPH line (or until the end of the file). | |
| edgelist = [] | |
| line = f.readline() | |
| while line and not line.startswith(b"GRAPH"): | |
| edgelist.append(line.rstrip()) | |
| line = f.readline() | |
| G = nx.Graph() | |
| G.name = f"G{graph_index}" | |
| G.add_nodes_from(range(num_nodes)) | |
| G.add_edges_from(tuple(map(int, e.split())) for e in edgelist) | |
| yield G | |
| def graph_atlas(i): | |
| """Returns graph number `i` from the Graph Atlas. | |
| For more information, see :func:`.graph_atlas_g`. | |
| Parameters | |
| ---------- | |
| i : int | |
| The index of the graph from the atlas to get. The graph at index | |
| 0 is assumed to be the null graph. | |
| Returns | |
| ------- | |
| list | |
| A list of :class:`~networkx.Graph` objects, the one at index *i* | |
| corresponding to the graph *i* in the Graph Atlas. | |
| See also | |
| -------- | |
| graph_atlas_g | |
| Notes | |
| ----- | |
| The time required by this function increases linearly with the | |
| argument `i`, since it reads a large file sequentially in order to | |
| generate the graph [1]_. | |
| References | |
| ---------- | |
| .. [1] Ronald C. Read and Robin J. Wilson, *An Atlas of Graphs*. | |
| Oxford University Press, 1998. | |
| """ | |
| if not (0 <= i < NUM_GRAPHS): | |
| raise ValueError(f"index must be between 0 and {NUM_GRAPHS}") | |
| return next(islice(_generate_graphs(), i, None)) | |
| def graph_atlas_g(): | |
| """Returns the list of all graphs with up to seven nodes named in the | |
| Graph Atlas. | |
| The graphs are listed in increasing order by | |
| 1. number of nodes, | |
| 2. number of edges, | |
| 3. degree sequence (for example 111223 < 112222), | |
| 4. number of automorphisms, | |
| in that order, with three exceptions as described in the *Notes* | |
| section below. This causes the list to correspond with the index of | |
| the graphs in the Graph Atlas [atlas]_, with the first graph, | |
| ``G[0]``, being the null graph. | |
| Returns | |
| ------- | |
| list | |
| A list of :class:`~networkx.Graph` objects, the one at index *i* | |
| corresponding to the graph *i* in the Graph Atlas. | |
| See also | |
| -------- | |
| graph_atlas | |
| Notes | |
| ----- | |
| This function may be expensive in both time and space, since it | |
| reads a large file sequentially in order to populate the list. | |
| Although the NetworkX atlas functions match the order of graphs | |
| given in the "Atlas of Graphs" book, there are (at least) three | |
| errors in the ordering described in the book. The following three | |
| pairs of nodes violate the lexicographically nondecreasing sorted | |
| degree sequence rule: | |
| - graphs 55 and 56 with degree sequences 001111 and 000112, | |
| - graphs 1007 and 1008 with degree sequences 3333444 and 3333336, | |
| - graphs 1012 and 1213 with degree sequences 1244555 and 1244456. | |
| References | |
| ---------- | |
| .. [atlas] Ronald C. Read and Robin J. Wilson, | |
| *An Atlas of Graphs*. | |
| Oxford University Press, 1998. | |
| """ | |
| return list(_generate_graphs()) | |