Crate gryf

Crate gryf 

Source
Expand description

Gryf is a graph data structure library aspiring to be convenient, versatile, correct and performant.

A graph is made up of vertices (also called nodes) which are connected by edges. Both vertices and edges might have attributes. Graphs can be used to model pairwise relations between objects and have many applications in various areas like computer science (packet routing in the internet), transportation (navigation in a city), linguistics (lexical semantics relationships), physics and chemistry (processing of molecular structures) or social sciences (social network analysis), among others.

Gryf implements various storages to hold the graph data and structure and encapsulations that guarantee specific semantics. Then it provides common graph traversal methods and a collection of algorithms on graphs. The algorithms are organized into the problems they solve. For specifying the parameters of an algorithm the builder pattern is utilized.

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO2dV1PjyFx1MDAxNoDf91dMsa+LbuewbzhcdTAwMTCHZNLA1i2XsIUtcMKBMLf2v99uXHUwMDAzVmrJkoPQ1GBXTVxysixcdTAwMWa3TvjO6dPt//3x7dvG+HXgbPz9bcN5adhcdTAwMWS3ObSfN/7Sx5+c4cjt99RLaPr3qD9cdTAwMTk2pme2x+PB6O///MdcdTAwMWVcZizvXVaj3317p9Nxuk5vPFLn/qP+/vbtf9N/1StuU7+/WapcXI1cdTAwMGX3R7RbI/Y9rdz06GRz+tbpSVx1MDAxZlx1MDAwMlxyncbY7rU6jvfSizpcdTAwMGUhg7NcdTAwMDOv6lx1MDAwMGV49vez21x1MDAxY7f1SVx1MDAwNFjS/yCzU9qO22qP1TmMWsD/8K769ql/f1x1MDAwM7Mjo/Gw/+CU+53+UIv2J5RcdTAwMWM2kCfYrd14aFxy+5Nec3bOeGj3Rlx1MDAwM3uoRsI7787tdM7Gr9Orq1x1MDAxMVUjt1x1MDAxMfqMq/dvgELH496lPrTV7jkjPdreN+hcdTAwMGbshjvWo1x1MDAwM4H3LbSEg73m9Mb815NpaHedPX1nepNOZ3bY7TVcdTAwMWQ93lx1MDAxYjZcYnxar/n+aVx1MDAxZnfVu2X4/ci/nuyOoy9MXHUwMDExl1x1MDAxMEHAZy942lx1MDAwNTFcZlx1MDAxZj3q96aapmRHXHUwMDFjXCLBqSfVqKLUazy96p3dXHUwMDE5Od4t0KJVw6rnV7+Ado2dXHUwMDE37774lHNz77Q62dx8qZ43m/X6/fH9T8nvN2bn/fuX+bJvb665nYPXc37x4yd5fXg5/l7Zv7x+XG5+ysfn28Nh/zntdeVz97CKX8uPz1X09H1Yvrhqt6rprvv+P+92T1x1MDAwNk37bfwgR1hcci+hhEo5e73j9lx1MDAxZcK60Ok3XHUwMDFlvCH/wydwyLTNo1x1MDAxNzHtwOC/W7VAXHUwMDE2oEHDXHUwMDE2UcOWwpJRU0b0y3bNtlx1MDAwYs22XHUwMDFiOPvdSCVcIlx1MDAxYyhrNFx1MDAxYSmKNVJEXGKRXHUwMDEwXHUwMDEyuICNXHUwMDA2xIgoJsSUS5RBMT090/qlvn5paI/dUcd+sn23sd9cdTAwMWKfuT+nooPA0W2763amilx1MDAxN7jQVsdt6THYaCipneGGfyDGrlxuf7NcdTAwMTO6brPpXHUwMDBmV1xydVHb7TnDvTRxrz90W27P7pwnXGJvT8b9mjN6XHUwMDEzfzycOP7RcXY/7Fx1MDAwMVqIXHUwMDFhrTQhtno3W8Q7ZMlcdTAwMTjHgPpipadqPpOK14A3N1E6uuCVSq9MNunVgdORt/3OznNRLC3qQfT341x1MDAxMlhB96QsxVx1MDAxMth7ILZyl7NcdTAwMWGcebdvqFxmlVx1MDAwYoyI51UzOZWssX9FXHUwMDAx+fpcdTAwMTJcdTAwMWVU6MvDvri4PD45vG/s19yntIFzz2mNJu3e9SGhT9dP1Vx1MDAxZj9OjuFoXHUwMDA1XHUwMDAxeV2BvtZ/OqtIvvn4Mlx1MDAxOJb5mbxrnVFUrEBvjuGpvFx1MDAwNydYMCakyXvg9N7DrFx1MDAxMYX2XHUwMDFlXHUwMDAycYtcdTAwMDKft1xielx1MDAxMpybJ2HMkv6P8lx1MDAwNDHB1IfnkETJLlx1MDAxMfS+/MKeI/BCxEUkai/AmGTQ3sUjvlx1MDAxZcWTod2a+MLjSklgTvxcdTAwMGKTQFiWXFwoXHUwMDAwolxiXGJ+XHUwMDE4slx1MDAwNFx1MDAxMiApvNc9MybpzXhSOlx1MDAxZXc3+yUhWk83L+dHI3HwXFwrtlx1MDAxOStEXHUwMDBlQVx1MDAwMCVB08UhWYrGXHUwMDAwXHUwMDFjKO/CXHUwMDEwXYEl58lcdTAwMDDnP7vN7cH+gOzYT/zsrlLe5d9zSJ5cdTAwMTOvW59UqFxyzmmj+nJwu9c4q/Sve3efy1x1MDAwMInXvbwtV+rD8U+Ka+f7Qrw2L1x1MDAxZeuvv1x1MDAxNlskpKFQUiBcdTAwMTlcdTAwMDe+moHnlWhcdTAwMDa4MKpasb1cdTAwMTIjXHUwMDE2p55cdTAwMTfyPvmtPJqXh2LAXCKBTzJ4KFx1MDAwM1xcQMqRWEVSslx1MDAxY1rwXGbKu1x1MDAxY1pcXLpOr2evXHQt5kTVMFqEZclcdTAwMDctgIgzY51cdTAwMWVIxKDJill6K1x1MDAxZWyDevn5uH+AXHUwMDA2d9uXVz97O+T0othWTHWKXHUwMDEwtFxcXHUwMDBlfym2IIxKijn/tdiiXd5cdTAwMWK47ilvXHUwMDFlg0mJwdJcdTAwMGYyLPfTxtRcdTAwMWZcdTAwMDePo9tqrTo5/DnCm49Xz1x1MDAwZvDiscBssXOyNThcdTAwMWPvXFzUXHUwMDA0OH788aIg/vr75S/GXHUwMDAwXHUwMDAwh4/OXHUwMDE4gEnIMFx1MDAxNj4hPO/B03tcdTAwMGazSlx1MDAxNNt7qMRehTH14FxmSSxDnkTm5UlcdTAwMTi2gHYggnCiZ/xMnsTAXHUwMDAwVDBdYeDejfskXG5cdTAwMTBcdTAwMTnUdzlcbjic9NxGe01cdTAwMTQwJ/6FKSAsSz5cdTAwMTTgXHUwMDAz1fCcXHUwMDEyXCJcdTAwMTJcdTAwMDOOTYVCkYFcdTAwMDLqz1uvZNy8P92qXHUwMDBmXHUwMDFlJ6Xa+XZrVGw7JpJbkPlcdTAwMWWhSiGPfbmYTKB8McdcdTAwMTiAX2vOgbedvYf9cke6u7btVlx1MDAxZrdPXkfnnz3nsFx1MDAwNGvMj92ccOar3K8rdif0enCVXHUwMDAzXG7o11x1MDAxNM/mZXqbN9+6Qts8hdLi2pipsjkuOFx1MDAwZpp8vEdYtclLalx0bcZcdTAwMThQyCn36UNC7Fx1MDAxNkRcdTAwMDDiq1x1MDAxNedcdTAwMWa4M+vucoH7aDJ0urfOsLWu2J1cdTAwMWO1wrHbIE4+4ZvS8NHZ/Fx1MDAwMFx1MDAxNFx1MDAxYzFcdTAwMTOEb6U35OPy01x1MDAxZFx1MDAxYT53XHUwMDFmXFx5XXJbXHUwMDEw4dpZqdiGzIBcZqXwnFxu35FihmhcdTAwMDYgXHUwMDExXHUwMDEwrcKEc1xm0dvtXHUwMDFlPL1cdTAwMWVcItKv7z6MXsfDauf1NIc0OPG69UewN+KVyU7/8qz/vcfLN6c37lfp/s1dxKbtiFwixFx1MDAxOKCmyF9K7zDMXHUwMDFhUWyHoVxmXHUwMDE4+Cr3nv1OnVx1MDAwN1+n8+DSXHUwMDEymTtcdTAwMDGwYISLlUxcdTAwMWYuXHUwMDFj7lx1MDAxN29cdTAwMGJcXCjcb6vBdLSirifaz1x0c+FoXHUwMDFmlSanZoDYYFx1MDAwZoHkilx1MDAxOFx0NCXr5fTme9m67pT5K75kt6P6YW+72r23XHUwMDBmXG5uvjJcdTAwMWPvZaCIX8h4LyRcdTAwMDXa6/9aXHUwMDE5eU06XHUwMDA37tVZv8tqk9b5w/XpzW2lk0NYLkz49DmskFx1MDAwMVx1MDAxMiio7ukw8XYlvf2ZR7jQ9sdcdFHKXHUwMDFl11UnyTptkcJQI126QjdgXHUwMDEyXHUwMDEzScln5ss5XHUwMDA30Fq/u67gOSdmhINnUJJlXHUwMDAzZ5pqX8ivXHUwMDA0tVdcdTAwMTBcdTAwMGIjXHUwMDAwqURcdTAwMDJApVx1MDAxM1x1MDAwMe3FKnPEXFx4T0M0QFx1MDAxNkFcZkEpXHUwMDA0Q5RBXHUwMDFh1UB1XG4gXHUwMDFjqjRUUIiZr8lh/jpcdTAwMTl0J1x1MDAxZEKyW0h6T0FCxz9xnUx1w2hj0Vxih1wiXHUwMDEx7t20iVB3QPBohXNjTt9cdTAwMTLiUt1ov/te91x1MDAxYbfW/bh99bRzOFx1MDAxMre1nUP3XHUwMDA1yJObaqagJyBcdTAwMDR0oY6ZQd9ccsv+j09C4Fx1MDAxN1x1MDAxN8z+/9+/jGdvxtuAfkS037te5Ct27NG43O923bH6oidayPBcdTAwMTdcdTAwMWGN7eG4pFTG7bWCqvG+4DVNb+/UXTYmelx1MDAwMICFOOaAUCAxRlx1MDAxMlxi4TupZVx1MDAwZjTMWZBLQVx1MDAxNK9JoU5cZpxx575cdTAwMDRcdTAwMDWNKKbTa85cdTAwMTc3udpcdTAwMThcdTAwMTRcdTAwMTdzJa5CSqGZXHUwMDA3Slx1MDAxNpFcdTAwMTdbXHUwMDFjeU9cdTAwMDFoJnmnXHUwMDAzvKVcdTAwMWRl27Ejtqq+Tfxrndv+c6pcdTAwMDWKZtWPuOvoXHUwMDAyRY6pXHUwMDA1MaZcYlx1MDAwYlx1MDAwNVx1MDAxNlxmhry1ylx1MDAwNHzRflx1MDAwNlx01FwiunavLFxcIIyIXHUwMDE3dD1GSIKc/F1ygZYuVi/NPtm0dlx1MDAxMWLAOVK2XHUwMDFlSVOngTI+d1x1MDAwNURKjHzueUWLXHUwMDE3oVT3XS7UTfDBTUjyb1x1MDAwZl3fTfTgXHUwMDBissDRdS9cXJzDOGHMXG5cdTAwMGK+XHUwMDFh0EpecpVcdTAwMDRaXHUwMDEyXHUwMDEyi1xiqPwsxZRcdTAwMDHqRdqp6WpcZjMvvvkwY6SSaqq8nlx1MDAwNIRcdTAwMTEsXHTwTpnZMWTc8s/ScU/pvpYkXHUwMDA37Hp7adRS0KxsXHUwMDE2Y25iLVx1MDAxYYtaXHUwMDFjXG7EqfT5iLWT1pDVcXk46Te26jv34+9X53fHL/WM5Vx1MDAwNYAx81vMp5BWvFx06EdU+Vx1MDAwYkZaXHUwMDAwIKngULt7lVhhXHUwMDAyo+xcdTAwMDKtbLSSiq6Sl3xcdTAwMDfpXG5MM1x1MDAwMSaQVm7h7ZXhSVxiM1x0mFx1MDAwN06Z9TtcdTAwMDVOQZXxKp6SVM/fKzpcbm7pQnw+esZSzGK6wVx1MDAxMVKk0iwhTU44XHUwMDEzTP1eTjdcdTAwMDNM6U5cdTAwMTRCmVx0pWT42IykhG48VXnWqkFqXHUwMDA1u0BgJFxuXHUwMDAyUnNcdTAwMTgmXGZSYcFXXHUwMDAzUsnr4ZJAXG4q21x1MDAwYtgp9d2YXHUwMDBmOzV1XHJRiyuVkiqHUlx1MDAwNkxcYvNG/ctMXHUwMDAzZrq7NFx1MDAxYjGm+6HMaERiV/TqXHUwMDFlXHUwMDEwKlx1MDAxOM5cdTAwMTGNYGvv+6TBq7y7u9NcdTAwMTKt2sVRd3yWXHUwMDFkjVxuUIRcdTAwMTLQf/5mRNnzYKHUoLGpYEjdbahcdTAwMTIhpmhDkVx1MDAxMIzWnaT/jashoeR1aUFYg1x1MDAxOFx1MDAwMqRSaKKSNVx1MDAwMKTX8ThcdTAwMTOQZoS1PFjIrNCpWEhSXHUwMDBiTZNPRTaMsPAyMP8s84ebJcSi03RV6G2bODC1b3zRUJybzVJaonp6XHUwMDE1SmNhP3ZcdTAwMWQjpLpcdTAwMWWFOCpcIlx1MDAxMHFZXHUwMDEwXHUwMDFlmoNcImFcdTAwMWVcbsm9XHUwMDFhXHUwMDFjSm6rT8IhyoElOZJA2SBXLjVYV1wiRFiU+57Rulx1MDAxMmRcdTAwMTZXd1x1MDAxM1xuSVXAoMhUVkLQXCLC98xSVvqtZvD2li8rMcqkulxyxlx1MDAxYXJ0W7xcdTAwMTk7XHUwMDExKFx1MDAwNFx1MDAwN3SRXHUwMDFh8oLsRG+e97c2sV26uqzvbJ7tXlx1MDAxZJZcdTAwMWVG2dZ7MFx1MDAwNshC5emVslOsXHUwMDA1TF+M6H5cdTAwMWUklWFCXGYgjlx1MDAwMVDcLLlgXHUwMDA0UW9cbv+bN4NHgPSeeFxyNabktX4h9OOEceWZOJRcdTAwMTJhwWREYGhx/1x1MDAxY56X8Fx1MDAxNYazzMqfgrNcdTAwMTjEXHUwMDE2mM7HXHUwMDAxXGaE8K31nIY40/xcdTAwMWS05Nf83aJcdTAwMGU5XHUwMDAzZFx0lS5xio01J1x1MDAxONv5pt6h0FmQlTNcdTAwMTaUXHUwMDEwXHUwMDEzvlx1MDAxNGNBXHUwMDBlXG5cdTAwMDJZc1x1MDAwMCdcZllhwVdDWclcdTAwMWJcdTAwMWEkz95cdTAwMDXXw1EhdJdcdTAwMDEhKm1cdTAwMDJcbr2iVuvvbfVAiltcXPe9UlxyapIpc/5Kjsx2u780SFx0QdVdIzCy4kNcdTAwMTNjfCM5plx1MDAxMmBcdGCOnVCVw/ZcdTAwMDOub1xyXHUwMDBmNrfEnruFXt2zXHUwMDA2zl6EytL+u1x1MDAxZZDa9Cm9fkTVPVx1MDAwZnZKXeTRKKKyWJVWXHUwMDBiKJFeXHUwMDAxoygqwlwifFx1MDAxZFNyqXFJT8khyYGAalx1MDAxOKVUjFx1MDAxN6WlXCLWocw6nYKPOONcdTAwMTac8lx1MDAxMYFcYlNcdTAwMWMqQym/K1x1MDAwNWNYjcq07Fx1MDAxNKUlXHLzmpYgp0iqoVuSln4vr5ulJKVX21x1MDAwMG04XHUwMDA2XHUwMDA3XHUwMDFiO0XHVXKLfTelOPUoXHUwMDAyUEFYaVx1MDAwZaaEWSks+GpYKXl1alx1MDAxMiupnN5cdTAwMTJcdTAwMThJhlx1MDAwMdPOP9ikqFdcdTAwMWL6O52iv65AhFx1MDAwNVx1MDAxOVx1MDAwN5hJZeCcUGaqSEGweKPTb1WROlhcdTAwMWGkIOdEqNjNTSSF4ovPiDBKOCSLXHUwMDE4+4IktdffvnePKm3e20fyzrm4O6pvXvyKJFx1MDAxNW9cdTAwMDP6XHUwMDEx1f48uCpcdTAwMDOzqNiAXHUwMDA1w1x1MDAxMkogOEB+PPno0V5cdTAwMDNUJa9iXHKCn1x1MDAxYUJdgZGIMVx1MDAwNfwyKmFW7MtcdTAwMDOqzOqdXHUwMDAyqlx1MDAxOIBcdTAwMTaeUlx1MDAxMaWMM1x1MDAxNExmmWCGuT1KLayVS9k+I5wwQ0fFV9kp1utmXHUwMDAwKVx1MDAwNLCAXHUwMDAyQGO3RHyvXHUwMDEzIFx1MDAwNFx1MDAxMFx1MDAwMNk66k5cdTAwMDD64vJcdTAwMDIsxVxiK1xiS83BmDBLhVx1MDAwNV9R3Slx6W9cIkvJID1cdENjODdYpvzioVx1MDAxOMv8vjxcdTAwMGZcdEqx3inS9Fx1MDAxYlXxe4spMydcdTAwMTIy5N9bbN08NHi5kdc/+o+STcpX+7uUiVx1MDAxMjnOwkOQXHUwMDAz4F83+Fk8xFx1MDAwM91NMlx1MDAxN95JjVx1MDAxM4omMFx1MDAxMCpcdTAwMWJGkEiKXHUwMDExh1GcQOtcdTAwMDCe5JXHXHUwMDAxXHRcdTAwMTGjiE03TpGYc1x1MDAwZZavc+VcdTAwMDE8Zv1NXHUwMDAxPFxcXHUwMDAxXHUwMDBm5TRmJ1ph+LFOhTuCzNsz9ot3YrzqYYbGbs71XvswXHUwMDFi7VDMJadELuI8k2lncVx1MDAwZjdbI8eL0to9XHUwMDA3NFwia+T4Olq7k386JIl2hN5cdTAwMGVcbjGpPKnKO3jolzhTrJHTu1RcdTAwMTKEpEpXlC1Db6myf4ncV/U3xoiPlkYjXHQ41kvETbZcdTAwMWS/d4xKwFU2XHUwMDFl+EW2dYPR1fZ9rT46hq82e9o9YVxiXHUwMDFl9sVN9kLR5/cuxWq8fihdz1x1MDAwM5SyLIGDXFxwPXsjXHUwMDAwVnGW5rRcdTAwMDIuS983QSqvRlJvXHUwMDA2r1x1MDAxM3NcdTAwMTiRMGvtKlx1MDAwZlAy63NcblCSXHUwMDAwWFjGTbdcdTAwMTFDvyhlXHUwMDE2+ppgW9TFZur5lnpfXHUwMDE2XHUwMDEwbVZIJCW9XHUwMDE3XHUwMDE4XHUwMDEyXHUwMDE0XHUwMDE2cY5NoXhBSGlcdTAwMGWkRHdcdTAwMTPAayCl5Fx1MDAxZFVcdTAwMTP7kVx1MDAwNNRcdTAwMWK3YFx1MDAwMqVQaEyCXYRcZpI5c2xcYjFcdTAwMGJIqDdcdTAwMTJcdTAwMDFY14RNoCSVofueXz9vXHUwMDFlY9THS3OTgFx1MDAwMjLi64T1byVcdTAwMTDfqyQppYRcdTAwMDCWY69cdTAwMTL8MeJcdTAwMTeNXHUwMDFlZJelXHUwMDA391SI9lx1MDAxMzzPuMk/R9LXL/d5vUpxJqBcdTAwMWZR5c9cdTAwMDOksnQuqdxNO1x1MDAwMMpUWqS7vvNcdTAwMDGpXGY1MZXkXHUwMDEzqfu8uSSEwGjbXHUwMDEysZjW+48nziRtLmvpjLqeXHUwMDAyqlx1MDAwNIFcdTAwMTbU/WTv6+KCzllcIvNsXHUwMDFi0zs5XHUwMDEyTFx1MDAwMVx1MDAxNXTp6tNv5YBPMlSfMJbS35ubXHUwMDAyqVx1MDAwNFx1MDAxM0S7gJXXnlZAVIJcdTAwMTWFqObATJiowoKvhqiOLvcnotauXtxcdTAwMWb14d2jc4bZvmFbXHUwMDAxp9NxXHUwMDA3IydotcryXHUwMDAyhooomldvwt47ZmaKM5mpo5/rNFNcdTAwMTg6vqiZLm2ktaUpSffpUkZRdFx1MDAxM/+NaUdYLCdcdTAwMTHCtKWh1Vx1MDAxYjDhSqQsq/+Nulx1MDAxYquW/lx1MDAxZi1KWPpcdTAwMDdcdTAwMDTCkJu2XvYt/Z639XLrXHUwMDAyvVx1MDAxY59dyapbenR3KrVcdTAwMDbaPTwuhsaZN15Wt1x1MDAxNVrGLOctrPi22FqV2aW0+9lvkUKil3j55oRXuMt51Ewy/c4gx1x1MDAwMmah8DfF/eOdezfsweBsrC45XHUwMDEzbePJdZ5L0XH882760CnCVFKtSM70XHUwMDFi/fvHv/9cdTAwMDddYzi+In0= BratislavaPragueViennaMunichNurembergFlorenceRome297 km328 km79 km170 km402 km646 km278 km293 km863 km
use gryf::{algo::ShortestPaths, Graph};

// Default storage is adjacency list, but that can be simply changed by
// using `Graph::new_undirected_in`.
let mut graph = Graph::new_undirected();

let prague = graph.add_vertex("Prague");
let bratislava = graph.add_vertex("Bratislava");
let vienna = graph.add_vertex("Vienna");
let munich = graph.add_vertex("Munich");
let nuremberg = graph.add_vertex("Nuremberg");
let florence = graph.add_vertex("Florence");
let rome = graph.add_vertex("Rome");

graph.extend_with_edges([
    (prague, bratislava, 328u32),
    (prague, nuremberg, 297),
    (prague, vienna, 293),
    (bratislava, vienna, 79),
    (nuremberg, munich, 170),
    (vienna, munich, 402),
    (vienna, florence, 863),
    (munich, florence, 646),
    (florence, rome, 278),
]);

// As the edge weights are unsigned and there is a specific goal, Dijktra's
// algorithm is applied. For signed edges, Bellman-Ford would be used.
let shortest_paths = ShortestPaths::on(&graph).goal(prague).run(rome).unwrap();
let distance = shortest_paths[prague];
let path = shortest_paths
    .reconstruct(prague)
    .map(|v| graph[v])
    .collect::<Vec<_>>()
    .join(" - ");

println!("{distance} km from Prague through {path}");
// 1391 km from Prague through Nuremberg - Munich - Florence - Rome

§Common operations

See the core module documentation.

§Goals

The main goals of gryf are to be

  • convenient, that is, “making the common case straightforward and natural”,
  • versatile, that is, “offering simplicity as well as flexibility and striving for a good balance if in conflict”,
  • correct, that is, “using extensive fuzzing and property-based testing to increase confidence about correctness”, and
  • performant, that is, “writing the code with performance and memory efficiency in mind”.

Failing in any of these should be considered an issue to be reported.

§Design

For more details, see the design document.

§Problems instead of algorithms

It may not be obvious which algorithm should (or even can) be used to solve the given problem at hand, especially for users without much experience or knowledge in graph theory and algorithms. Instead, gryf organizes the algorithms into the problem they solve (e.g., ShortestPaths) instead of requiring to call the algorithms directly (dijkstra, bellman_ford).

Organizing algorithms into problems brings a number of benefits, among which the most important are:

  • It is convenient for the user, especially if they are a beginner. It allows them not to care about details if they don’t want to care.
  • Having a specific type instead of a generic one such as Vec or HashMap gives the opportunity to provide additional functionality (like path reconstruction for shortest paths or “is perfect?” query on matching).
  • Not specifying the algorithm enables the use of automatic algorithm selection, which makes the decision based on the properties of the input graph.
let shortest_paths = ShortestPaths::on(&graph).run(rome).unwrap();

§Builder pattern for algorithms

Specifying arguments for algorithms is done using the builder pattern. This avoids the need to pass dummy values (like None) to parameters that are not useful for the use case. On the other hand, it allows tweaking the algorithm with many optional arguments. Moreover, new optional parameters can be added in a backward-compatible way. A lot of care is taken to make the error feedback from the compiler helpful and obvious.

let shortest_paths = ShortestPaths::on(&graph)
    .edge_weight_fn(|e| e.distance)
    .goal(prague)
    .run(rome)
    .unwrap();

§Separation of graph storage and semantics

High-level semantics provided by user-facing types are strictly separated from the underlying storage/representation. The graph data can be stored in a common representation (e.g., adjacency list or adjacency matrix), but it can also be stored in or represented by a custom, problem-tailored implementation, as long as it implements provided interfaces.

On top of storage, there is an encapsulation with clear semantics. The most general is a generic graph, but restricted forms include simple graphs (without parallel edges), paths, bipartite graphs and so on. Among the advantages of restrictive encapsulations are:

  • The type of graph clearly communicates the intention and structure.
  • The API is limited such that it is impossible to violate the rules of the user-desired class of graph.
  • The guaranteed properties of a restricted graph can be utilized in choosing a more efficient algorithm.
use gryf::storage::AdjMatrix;

let mut graph = Graph::new_undirected_in(AdjMatrix::default());

§Graph interfaces and generic algorithms

There is a set of core traits that represent different levels of functionality that is supported by a graph representation. The levels range from basic properties like directionality of the graph over structural properties like vertex/edge count and vertex neighbors to different kinds of manipulation capability (readonly, append-only, removable). The traits require only a bare minimum of methods and provide default, overridable implementations (even if inefficient) for the remaining API to reduce the implementation burden.

Algorithms then constrain the input graph only with traits that are necessary for its function and don’t make any assumption on the specific graph representation used.

§Iteration over recursion

Iterative graph traversals are preferred over recursion. The main benefits of this choice are:

  • Traversal is lazy and can be stopped without tricks.
  • Traversal state is independent on the graph itself, allowing mutations during traversal.
  • Traversal is not limited by the size of the program stack.
use gryf::visit::{DfsEvent, DfsEvents, Visitor};

let is_cyclic = DfsEvents::new(&graph)
    .start(root)
    .into_iter(&graph)
    .any(|event| matches!(event, DfsEvent::BackEdge { .. }));

§Comparison with alternatives

Check the rusty graphs repository for a detailed comparison of gryf and other graph libraries available for Rust with examples and commentary.

Re-exports§

pub use domain::Graph;

Modules§

adapt
Various graph adapters.
algo
Collection of graph algorithms.
core
Core traits and types used in gryf.
domain
Collection of various graph types implementations.
storage
Implementations of various graph storages.
visit
Implementations of graph traversal methods.