Skip to main content

Python bindings for various graph genus and embedding tools

Project description

K3,3 embedding: logo for graph genus repo

Graph Genus

DOI arXiv PyPI Version 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 source build_wheels.sh, check with source build_wheels_test.sh, 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.1.tar.gz (94.5 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.1-py3-none-win_amd64.whl (270.8 kB view details)

Uploaded Python 3Windows x86-64

graph_genus-0.1.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (127.2 kB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

graph_genus-0.1.1-py3-none-macosx_15_0_arm64.whl (120.4 kB view details)

Uploaded Python 3macOS 15.0+ ARM64

File details

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

File metadata

  • Download URL: graph_genus-0.1.1.tar.gz
  • Upload date:
  • Size: 94.5 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.1.tar.gz
Algorithm Hash digest
SHA256 df0e4a164ca5b25f661c44e22c1ee88d950d63e405881e61c251b4c52d4d9cd0
MD5 27f2f9f7de55d6e20888ddbdda3c1a85
BLAKE2b-256 3b1a69fb63202970207778d29bbd544fd709e490a35d76b83a85aea32a804aaf

See more details on using hashes here.

File details

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

File metadata

  • Download URL: graph_genus-0.1.1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 270.8 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.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 798b55fd53315da66c3cd413d7b1e92284dbecf924153f15aa9ccf4b38150f0a
MD5 1b4564fdfbef7955d0a791249f47810f
BLAKE2b-256 9ac460682bd12af656d4e458e3df09d2fbb39b7c50be8a3318509b7358173a59

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for graph_genus-0.1.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 ce1acbff90a4ecad5bfa0575542eac89498b2b8a0b611bac76fc520ebe5cdb72
MD5 c960300c280cdb8241700a03f52ad3f8
BLAKE2b-256 b249ac2239c316858c379975042cf98d9d59b8f6c2b913702e46483576fd8d33

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for graph_genus-0.1.1-py3-none-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 437c20865433b690a487a15a8f4edb3cb18dc2846ce1ab87bc033f8d89b7789d
MD5 60b5e26b02656d8401a59370d81bcb01
BLAKE2b-256 765d45845f5ca00872b2dcea449c498166aad4e97bdf9d457df005b844c43a2c

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