Skip to main content

Python bindings for various graph genus and embedding tools

Project description

EmbeddedArena logo

Graph Genus

DOI arXiv maintenance-status

State of the art practical algorithms for computing the minimum genus of graphs and the corresponding embeddings. Contains standalone C programs, python bindings, and a web version with 2D and 3D visualizations.

Motivation

A famous problem at the intersection of topology and combinatorial graph theory is the Utility Problem. Say you have three houses and three utilities and you need to connect each house to each utility via a wire. Is there a way to do this without the wires crossing? In terms of graph theory, this is asking whether K3,3 is planar. It is known that it is not. In fact K3,3 is toroidal meaning while it cannot be embedded on a plane without edges crossing, it can be embedded on a torus:

K3,3 Torus Embedding

The characterizing property of a torus that allows us to embed K3,3 is that it has a hole (unlike surfaces such as a plane or a sphere). This motivates classifying surfaces by their number of holes, that is, their genus g. The genus of a graph G is then simply the genus of the minimum genus surface on which G can be embedded without edges crossing. For genus zero we use the special name planar and for genus one we use toroidal. Calculating the genus of a graph has a number of applications, particularly in the design of integrated circuits, study of graph minors, VLSI design, infrastructure planning, and more. For an interactive visualization of graph embedding check here.

Usage

The easiest way is to use the web version. This won't be as fast as running it locally and I can't guarantee it will always be up, but it should allow you to explore the algorithm. You can also self-host the web application by installing docker and running cd app followed by . ./run-dev.sh. This will start the web application on localhost:8080.

The easiest way to run locally, is with the graph-genus Python package. Make sure you have Python 3. Then pip install graph-genus and you can use the Python API:

import graph_genus as gg

adjacency_list = [[3, 4, 5], [3, 4, 5], [3, 4, 5],
                  [0, 1, 2], [0, 1, 2], [0, 1, 2]]
genus, rotation_system = gg.embed(adjacency_list)
  • As an optional parameter to embed, you can use algorithm="page" (default), algorithm="multi_genus", and algorithm="none". "page" is especially fast for high girth graphs and scales well in general too. "multi_genus" is included with permission from Gunnar Brinkmann, is faster for some graph families, and uses less resources, but handles at most 128 vertices and 512 undirected edges. "none" treats adjacency_list as an already chosen rotation system.
  • You can also use output_format="rotation_system" (default), output_format="drawing" for TikZ/LaTeX output of the fundamental polygon, and output_format="3D" for OBJ output of the 3D surface with the graph drawn on it.
  • Use gg.cite(algorithm, output_format) to retrieve the relevant BibTeX entries.

For local development, install with make -C PAGE all && make -C MultiGenus all && pip install -e . then test with python tests/test_graph_genus_package.py (should take ~2 minutes). Build with pipx run build, check with pipx run twine check dist/*, and upload with pipx run twine upload dist/*.

To run the algorithms directly without the Python bindings, take a look at the instructions for PAGE and MultiGenus.

Acknowledgements

Austin contributed equally to the ideas behind PAGE. Professor Steinerberger provided guidance on the PAGE publication. Professor Brinkmann provided a fast alternative algorithm, multi_genus, and useful code for visualizing embeddings.

License

This project is licensed under the terms of the GNU General Public License v2.0 (GPLv2). See the LICENSE file for the full text.

Citation

If you use the PAGE algorithm or other code/visualizations from this repository, python package, or webapp, please cite:

@article{Metzger_2026,
   title={An efficient genus algorithm based on graph rotations},
   volume={349},
   ISSN={0012-365X},
   url={http://doi.org/10.1016/j.disc.2026.115308},
   DOI={10.1016/j.disc.2026.115308},
   number={12},
   journal={Discrete Mathematics},
   publisher={Elsevier BV},
   author={Metzger, Alexander and Ulrigg, Austin},
   year={2026},
   month=Dec, pages={115308}
}

If you use multi_genus, please cite

@article{article,
    author = {Brinkmann, Gunnar},
    year = {2022},
    month = {07},
    pages = {#P4.01},
    title = {A practical algorithm for the computation of the genus},
    volume = {22},
    journal = {Ars Mathematica Contemporanea},
    doi = {10.26493/1855-3974.2320.c2d}
}

And if you use the fundamental polygon drawings or 3D visualizations, please additionally cite

@misc{brinkmann2025drawingmapsorientedsurfaces,
    title={Drawing maps on oriented surfaces}, 
    author={Gunnar Brinkmann},
    year={2025},
    eprint={2505.01480},
    archivePrefix={arXiv},
    primaryClass={cs.CG},
    url={https://arxiv.org/abs/2505.01480}, 
}

You may also want to check out the literature this work is based on.

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

graph_genus-0.1.0.tar.gz (820.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

graph_genus-0.1.0-py3-none-win_amd64.whl (270.7 kB view details)

Uploaded Python 3Windows x86-64

graph_genus-0.1.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (127.1 kB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

graph_genus-0.1.0-py3-none-macosx_15_0_arm64.whl (120.3 kB view details)

Uploaded Python 3macOS 15.0+ ARM64

File details

Details for the file graph_genus-0.1.0.tar.gz.

File metadata

  • Download URL: graph_genus-0.1.0.tar.gz
  • Upload date:
  • Size: 820.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for graph_genus-0.1.0.tar.gz
Algorithm Hash digest
SHA256 21c2ceb34fe72fdb0d0646a76274a95a89386402a46542343dd131b9de91950d
MD5 88ebfeed296c6f1e1332e323ed511337
BLAKE2b-256 dc97e25056aca4efb6bc677a486786f8851ca747255b92daac7d072a8102a7e7

See more details on using hashes here.

File details

Details for the file graph_genus-0.1.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: graph_genus-0.1.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 270.7 kB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for graph_genus-0.1.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 a54363ce702edc7ce3502cdc3a9e2e1a4e17b7926eb5b4458b07b247eca9a0f0
MD5 859d2354ac553e4a23460b557ffdc00c
BLAKE2b-256 94fa98d0bb30519bdc96d6a46e0b72099d0fa54e29bcab10783206fc9cd905f4

See more details on using hashes here.

File details

Details for the file graph_genus-0.1.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for graph_genus-0.1.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 e8d1c41044b97677cd37305aa1e07446d40f9bd2ecd08bd92570c2094cdeffe7
MD5 37c65d5332f1e38ade41d49d3347ce99
BLAKE2b-256 a6768777ac39c09ef3458104cec10185c0691b38026be94daab59b7ac4d787f6

See more details on using hashes here.

File details

Details for the file graph_genus-0.1.0-py3-none-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for graph_genus-0.1.0-py3-none-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 97242b82fd530122f104b260284386bcc653fc9a316b2f6d445d487a3b26a74b
MD5 3f060f7998898c1cd2d48d7fdf5359f2
BLAKE2b-256 0798ededef5519cacee2221e24c6e362eeae4f0ef1971342b2019016e07fc61c

See more details on using hashes here.

Supported by

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