Skip to main content

Graph analysis – the lazy (evaluation) way: Analysis on the fly, for graphs, that are computed and/or adapted on the fly.

Project description

PyPI version PyPI status PyPI pyversions PyPI license CI CodeCov Documentation Status Code style GitHub issues

NoGraphs: Graph analysis on the fly

NoGraphs simplifies the analysis of graphs that can not or should not be fully computed, stored or adapted, e.g. infinite graphs, large graphs and graphs with expensive computations. (Here, the word graph denotes the thing with vertices and edges, not with diagrams.)

The approach: Graphs are computed and/or adapted in application code on the fly (when needed and as far as needed). Also, the analysis and the reporting of results by the library happen on the fly (when, and as far as, results can already be derived).

Think of it as graph analysis - the lazy (evaluation) way.

Documentation

Feature overview

  • Unidirectional traversal algorithms: DFS, BFS, topological search, Dijkstra, A* and MST.

  • Bidirectional search algorithms: BFS and Dijkstra.

  • Results: Reachability, depth, distance, paths and trees. Paths can be calculated with vertices, edges, or attributed edges, and can be iterated in both directions.

  • Flexible graph notion:

    • Infinite directed multigraphs with loops and attributes (this includes multiple adjacency, cycles, self-loops, directed edges, weighted edges and attributed edges).

    • Infinite graphs are supported, but need to be locally finite (i.e., a vertex has only finitely many outgoing edges).

  • Generic API:

    • Vertices: Can be anything except for None. Hashable vertices can be used directly, unhashable vertices can be used together with hashable identifiers.

    • Edge weights and distances: Wide range of data types supported (float, int, Decimal, mpmath.mpf and others), e.g., for high precision computations.

    • Edge attributes: Any object, e.g, a container with further data.

    • Identity and equivalence of vertices can be chosen / defined.

    • Bookkeeping: Several sets of bookkeeping data structures are predefined, optimized for different situations (data types used by the application, hashing vs. indexing, collections for Python objects or C native data types,…); Adaptable and extendable, e.g., specialized collections of 3rd party libraries can be integrated easily and runtime efficiently

  • Flexible API: The concept of implicit graphs that NoGraphs is based on allows for an API that eases operations like graph pruning, graph abstraction, the typical binary graph operations (union, intersection, several types of products), the computation of search-aware graphs, the combination of problem reduction with lazy evaluation, and traversals of vertex equivalence classes on the fly. Bookkeeping data can be pre-initialized and accessed during computations.

  • Typing: The API can be used fully typed (optionally).

  • Implementation: Pure Python (>=3.9). It introduces no further dependencies.

  • CI tests: For all supported versions of Python and both supported interpreters CPython and PyPy, both code and docs, 100% code coverage.

  • Runtime and memory performance: Have been goals (CPython). In its domain, it often even outperforms Rust- and C-based libraries. Using PyPy improves its performance further.

Extras (outside of the core of NoGraphs)

  • Computation of exact solutions for (small) traveling salesman problems (shortest / longest route, positive / zero / negative edge weights, graph does not need to be complete)

  • Dijkstra shortest paths algorithm for infinitely branching graphs with locally sorted edges.

  • Gadget functions for test purposes. They make the easy task of adapting existing explicit test graphs a no brainer, may they be stored in edge indices or edge iterables or in arrays.

Example

Our graph is directed, weighted and has infinitely many edges. These edges are defined in application code by the following function. For a vertex i (here: an integer) as the first of two parameters, it yields the edges that start at i as tuples (end_vertex, edge_weight). What a strange graph - we do not know how it looks like…

>>> def next_edges(i, _):
...     j = (i + i // 6) % 6
...     yield i + 1, j * 2 + 1
...     if i % 2 == 0:
...         yield i + 6, 7 - j
...     elif i % 1200000 > 5:
...         yield i - 6, 1

We would like to find out the distance of vertex 5 from vertex 0, i.e., the minimal necessary sum of edge weights of any path from 0 to 5, and (one of) the shortest paths from 0 to 5.

We do not know which part of the graph is necessary to look at in order to find the shortest path and to make sure, it is really the shortest. So, we use the traversal strategy TraversalShortestPaths of NoGraphs. It implements the well-known Dijkstra graph algorithm in the lazy evaluation style of NoGraphs.

>>> import nographs as nog
>>> traversal = nog.TraversalShortestPaths(next_edges)

We ask NoGraphs to traverse the graph starting at vertex 0, to calculate paths while doing so, and to stop when visiting vertex 5.

>>> traversal.start_from(0, build_paths=True).go_to(5)
5

The state data of this vertex visit contains our results:

>>> traversal.distance
24
>>> traversal.paths[5]
(0, 1, 2, 3, 4, 10, 16, 17, 11, 5)

We learn that we need to examine the graph at least till vertex 17 to find the shortest path from 0 to 5. It is not easy to see that from the definition of the graph…

A part of the graph, the vertices up to 41, is shown in the following picture. Arrows denote directed edges. The edges in red show shortest paths from 0 to other vertices.

https://nographs.readthedocs.io/en/latest/_images/nographs_example_graph.PNG

And now?

Can you imagine…

  • An infinite generator of primes, defined by just a graph and a call to a standard graph algorithm?

  • Or a graph that defines an infinite set of Towers of Hanoi problems in a generic way, without fixing the number of towers, disk sizes, and the start and goal configuration - and a specific problem instance is solved by just one library call?

  • Or a way for computing an exact solution for traveling salesman problems, that is based on just a graph and a call of the Dijkstra single source shortest path algorithm?

  • Or graphs that are dynamically computed based on other graphs, or on analysis results about other graphs, or even on partial analysis results for already processed parts of the same graph?

Let’s build it.

Welcome to NoGraphs!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nographs-3.3.1.tar.gz (105.5 kB view details)

Uploaded Source

Built Distribution

nographs-3.3.1-py3-none-any.whl (79.6 kB view details)

Uploaded Python 3

File details

Details for the file nographs-3.3.1.tar.gz.

File metadata

  • Download URL: nographs-3.3.1.tar.gz
  • Upload date:
  • Size: 105.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.0

File hashes

Hashes for nographs-3.3.1.tar.gz
Algorithm Hash digest
SHA256 4b4d41abc0802c16f64c94b8332033852ff42106e6fe5ca0629362c33c8dc825
MD5 57d76936d13e96e2da76111e8709719a
BLAKE2b-256 7ff637ac85f1f3e325a02e144ca0ab467643b7b3cfb3aedaeff0bc9c731d6d37

See more details on using hashes here.

File details

Details for the file nographs-3.3.1-py3-none-any.whl.

File metadata

  • Download URL: nographs-3.3.1-py3-none-any.whl
  • Upload date:
  • Size: 79.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.0

File hashes

Hashes for nographs-3.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6f5f1623733019724ca9af0c9d383407a1b3ff4264d6edb19cca7e2c4d6b8366
MD5 4908c4eedc5ebb3cc5723d6913bbe71f
BLAKE2b-256 e82e216c597c125120d00b641a1ac9c6ee51862dd15af074ed2809bd07eccec8

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page