{"id":13411933,"url":"https://github.com/monora/rgl","last_synced_at":"2025-03-14T17:31:18.832Z","repository":{"id":425148,"uuid":"1806785","full_name":"monora/rgl","owner":"monora","description":"RGL is a framework for graph data structures and algorithms in Ruby.","archived":false,"fork":false,"pushed_at":"2024-04-18T14:04:31.000Z","size":641,"stargazers_count":415,"open_issues_count":0,"forks_count":59,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-10-08T13:41:02.388Z","etag":null,"topics":["directed-graphs","dot","edges","graph","graph-algorithms","graph-library","rgl","ruby","vertex"],"latest_commit_sha":null,"homepage":"https://monora.github.io/rgl/","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/monora.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2011-05-26T21:38:18.000Z","updated_at":"2024-10-02T18:02:45.000Z","dependencies_parsed_at":"2023-07-05T14:53:31.599Z","dependency_job_id":"7732c05b-f439-4157-847b-03413b0ae270","html_url":"https://github.com/monora/rgl","commit_stats":{"total_commits":255,"total_committers":26,"mean_commits":9.807692307692308,"dds":"0.43137254901960786","last_synced_commit":"832bffef3057175a1c69cc546b70b2248a03c4bc"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monora%2Frgl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monora%2Frgl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monora%2Frgl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monora%2Frgl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monora","download_url":"https://codeload.github.com/monora/rgl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243307496,"owners_count":20270263,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["directed-graphs","dot","edges","graph","graph-algorithms","graph-library","rgl","ruby","vertex"],"created_at":"2024-07-30T20:01:18.815Z","updated_at":"2025-03-14T17:31:15.348Z","avatar_url":"https://github.com/monora.png","language":"Ruby","readme":"# Ruby Graph Library (RGL)\n[![Test](https://github.com/monora/rgl/actions/workflows/test.yml/badge.svg)](https://github.com/monora/rgl/actions/workflows/test.yml) [![Doc](https://github.com/monora/rgl/actions/workflows/doc.yml/badge.svg)](https://github.com/monora/rgl/actions/workflows/doc.yml)\n[![Version](https://badge.fury.io/rb/rgl.svg)](https://badge.fury.io/rb/rgl)\n[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/monora/rgl)\n[![Code Climate](https://img.shields.io/codeclimate/maintainability/monora/rgl)](https://codeclimate.com/github/monora/rgl)\n\nRGL is a framework for graph data structures and algorithms.\n\nThe design of the library is much influenced by the Boost Graph Library (BGL)\nwhich is written in C++. Refer to https://www.boost.org/libs/graph/doc for\nfurther links and documentation on graph data structures and algorithms and\nthe design rationales of BGL.\n\nA comprehensive summary of graph terminology can be found in the graph section\nof the *Dictionary of Algorithms and Data Structures* at\nhttps://www.nist.gov/dads/HTML/graph.html or\n[Wikipedia](https://en.wikipedia.org/wiki/Graph_%28discrete_mathematics%29).\n\n* [GitHub Repository](https://github.com/monora/rgl)\n* [API Reference](https://monora.github.io/rgl/) generated from master branch\n* [API Reference](https://www.rubydoc.info/github/monora/rgl) at\n    https://rubydoc.info for the latest release\n\n## Design principles\n\nThis document concentrates on the special issues of the implementation in\nRuby. The main design goals directly taken from the BGL design are:\n\n*   An interface for how the structure of a graph can be accessed using a\n    generic interface that hides the details of the graph data structure\n    implementation. This interface is defined by the module {RGL::Graph},\n    which should be included in concrete classes.\n\n*   A standardized generic interface for traversing graphs\n    {RGL::GraphIterator}\n\nRGL provides some general purpose graph classes that conform to this\ninterface, but they are not meant to be the **only** graph classes. As in BGL\nI believe that the main contribution of the RGL is the formulation of this\ninterface.\n\nThe BGL graph interface and graph components are generic in the sense of the\nC++ Standard Template Library (STL). In Ruby other techniques are available to\nexpress the generic character of the algorithms and data structures mainly\nusing mixins and iterators. The BGL documentation mentions three means to\nachieve genericity:\n\n*   Algorithm/Data-Structure Interoperability\n*   Extension through Function Objects and Visitors\n*   Element Type Parameterization\n*   Vertex and Edge Property Multi-Parameterization\n\nThe first is easily achieved in RGL using mixins, which of course is not as\nefficient than C++ templates (but much more readable :-). The second one is\neven more easily implemented using standard iterators with blocks or using the\n[stream](https://www.rubydoc.info/github/monora/stream) module. The third one\nis no issue since Ruby is dynamically typed: Each object can be a graph\nvertex. There is no need for a vertex (or even edge type). In the current\nversion of RGL properties of vertices are simply attached using hashes. At\nfirst there seems to be not much need for the graph property machinery.\n\n### Algorithms\n\nRGL current contains a core set of algorithm patterns:\n\n*   Breadth First Search {RGL::BFSIterator}\n*   Depth First Search {RGL::DFSIterator}\n\nThe algorithm patterns by themselves do not compute any meaningful quantities\nover graphs, they are merely building blocks for constructing graph\nalgorithms. The graph algorithms in RGL currently include:\n\n*   Topological Sort {RGL::TopsortIterator}\n*   Connected Components {RGL::Graph#each_connected_component}\n*   Strongly Connected Components {RGL::Graph#strongly_connected_components}\n*   Transitive Closure {RGL::Graph#transitive_closure}\n*   Dijkstras Shortest Path Algorithm {RGL::DijkstraAlgorithm}\n*   Bellman Ford Algorithm {RGL::BellmanFordAlgorithm}\n\n### Data Structures\n\nRGL currently provides two graph classes that implement a generalized\nadjacency list and an edge list adaptor.\n\n*   {RGL::AdjacencyGraph}\n*   {RGL::ImplicitGraph}\n\nThe AdjacencyGraph class is the general purpose _swiss army knife_ of graph\nclasses. It is highly parameterized so that it can be optimized for different\nsituations: the graph is directed or undirected, allow or disallow parallel\nedges, efficient access to just the out-edges, fast vertex insertion and\nremoval at the cost of extra space overhead, etc.\n\n### Differences to BGL\n\nThe concepts of IncidenceGraph, AdjacencyGraph and VertexListGraph\n(see [IncidenceGraph](https://www.boost.org/libs/graph/doc/IncidenceGraph.html)) are\nbundled in RGL's base graph module. Most methods of IncidenceGraph\nshould be standard in the base module Graph. The complexity guarantees\ncan not necessarily provided (see [BGL's Graph Concepts](https://www.boost.org/libs/graph/doc/graph_concepts.html)).\n\n## Installation\n\n    % gem install rgl\n\nor download the latest sources from the [git\nrepository](https://github.com/monora/rgl).\n\nIf you are going to use the drawing functionalities install [Graphviz](https://www.graphviz.org/).\n\n## Running tests\n\nCheckout RGL git repository and go to the project directory. First, install\nRGL dependencies with bundler:\n\n    % bundle install\n\nAfter that you can run the tests:\n\n    % rake test\n\n## Example irb session with RGL\n\n    % irb -Ilib\n\n    irb\u003e require 'rgl/adjacency'\n    irb\u003e dg=RGL::DirectedAdjacencyGraph[1,2 ,2,3 ,2,4, 4,5, 6,4, 1,6]\n    # Use DOT to visualize this graph:\n    irb\u003e require 'rgl/dot'\n    irb\u003e dg.write_to_graphic_file('jpg')\n    \"graph.jpg\"\n\nThe result:\n\n![Example](images/example.jpg)\n\nYou can control the graph layout by passing layout parameters to `write_to_graphic_file`. See\n`TestDot::test_to_dot_digraph_with_options` for an example using a feature implemented by Lia\nSkalkos (see [PR #41](https://github.com/monora/rgl/pull/41)).\n\n    irb\u003e dg.directed?\n    true\n    irb\u003e dg.vertices\n    [5, 6, 1, 2, 3, 4]\n    irb\u003e dg.has_vertex? 4\n    true\n\nEvery object could be a vertex (there is no class Vertex), even the class\nobject *Object*:\n\n    irb\u003e dg.has_vertex? Object\n    false\n    irb\u003e dg.edges.sort.to_s\n    \"(1-2)(1-6)(2-3)(2-4)(4-5)(6-4)\"\n    irb\u003e dg.to_undirected.edges.sort.to_s\n    \"(1=2)(1=6)(2=3)(2=4)(5=4)(6=4)\"\n\nAdd inverse edge (4-2) to directed graph:\n\n    irb\u003e dg.add_edge 4,2\n\n(4-2) == (2-4) in the undirected graph:\n\n    irb\u003e dg.to_undirected.edges.sort.to_s\n    \"(1=2)(1=6)(2=3)(2=4)(5=4)(6=4)\"\n\n(4-2) != (2-4) in directed graphs:\n\n    irb\u003e dg.edges.sort.to_s\n    \"(1-2)(1-6)(2-3)(2-4)(4-2)(4-5)(6-4)\"\n    irb\u003e dg.remove_edge 4,2\n    true\n\nCheck whether a path exists between vertices 1 and 5\n\n    irb\u003e require 'rgl/path'\n    irb\u003e dg.path?(1, 5)\n    true\n\n*Topological sort* is implemented as an iterator:\n\n    require 'rgl/topsort'\n    irb\u003e dg.topsort_iterator.to_a\n    [1, 2, 3, 6, 4, 5]\n\nA more elaborated example showing *implicit graphs*:\n\n    require 'rgl/implicit'\n    def module_graph\n      RGL::ImplicitGraph.new { |g|\n        g.vertex_iterator { |b|\n          ObjectSpace.each_object(Module, \u0026b)\n        }\n        g.adjacent_iterator { |x, b|\n          x.ancestors.each { |y|\n            b.call(y) unless x == y || y == Kernel || y == Object\n          }\n        }\n        g.directed = true\n      }\n    end\n\nThis function creates a directed graph, with vertices being all loaded\nmodules:\n\n    g = module_graph\n\nWe only want to see the ancestors of {RGL::AdjacencyGraph}:\n\n    require 'rgl/traversal'\n    tree = g.bfs_search_tree_from(RGL::AdjacencyGraph)\n\nNow we want to visualize this component of g with DOT.  We therefore create a\nsubgraph of the original graph, using a filtered graph:\n\n    g = g.vertices_filtered_by {|v| tree.has_vertex? v}\n    g.write_to_graphic_file('jpg')\n\ncreates the following graph image with DOT:\n\n![Module graph](images/module_graph.jpg)\n\nThis graph shows all loaded RGL modules:\n\n![RGL Modules](images/rgl_modules.png)\n\nLook for more in\n[examples](https://github.com/monora/rgl/tree/master/examples) directory.\n\n## (Optional) Configuring Graphviz DOT output options\n\nThe default graph will use standard DOT output visuals.\n\nIf you wish to configure the styling of the diagram, module {RGL::DOT} adds the methods {RGL::Graph#set_edge_options} and {RGL::Graph#set_vertex_options} for this purpose. You can use any options from the {RGL::DOT::NODE_OPTS} and {RGL::DOT::EDGE_OPTS} constants in {RGL::DOT}. Use the exact option name as an argument in your method call.\n\nYou can also configure the overall appearance of the graph by passing a hash of options from {RGL::DOT::GRAPH_OPTS} to the output method. The example below shows styling of vertices, edges and setting some basic graph options.\n\nThe available options are described in the [GraphViz DOT Spec](https://www.graphviz.org/pdf/dotguide.pdf)\n\n![colored diagram](images/styled_graph.png \"Colored DOT graph\")\n\n```ruby\nrequire 'rgl/adjacency'\nrequire 'rgl/dot'\n\ngraph = RGL::DirectedAdjacencyGraph['a','b', 'c','d', 'a','c']\n\ngraph.set_vertex_options('a', label: 'This is A', shape: 'box3d', fontcolor: 'green', fontsize: 16)\ngraph.set_vertex_options('b', label: 'This is B', shape: 'tab', fontcolor: 'red', fontsize: 14)\ngraph.set_vertex_options('c', shape: 'tab', fontcolor: 'blue')\n\ngraph.set_edge_options('a', 'b', label: 'NotCapitalEdge', style: 'dotted', dir: 'back', color: 'magenta')\ngraph.set_edge_options('a', 'c', weight: 5, color: 'blue')\n\ngraph_options = {\n    \"rankdir\"  =\u003e \"LR\",\n    \"labelloc\" =\u003e \"t\",\n    \"label\"    =\u003e \"Graph\\n (generated #{Time.now.utc})\"\n}\n\ngraph.write_to_graphic_file('png', 'graph', graph_options)\n\n```\n\n## Credits\n\nMany thanks to Robert Feldt which also worked on a graph library\n(https://rockit.sf.net/subprojects/graphr) who pointed me to BGL and many other\ngraph resources.\n\nRobert kindly allowed to integrate his work on graphr, which I did not yet\nsucceed. Especially his work to output graphs for\n[GraphViz](https://www.graphviz.org) is much more elaborated than the minimal\nsupport in dot.rb.\n\nJeremy Siek one of the authors of the nice book [The Boost Graph\nLibrary](https://www.boost.org/libs/graph/doc) kindly allowed to use the BGL\ndocumentation as a *cheap* reference for RGL. He and Robert also gave feedback\nand many ideas for RGL.\n\nDave Thomas for [RDoc](https://rdoc.sourceforge.net) which generated what you\nread and matz for Ruby. Dave included in the latest version of RDoc (alpha9)\nthe module {RGL::DOT} which is used instead of Roberts module to visualize\ngraphs.\n\nJeremy Bopp, John Carter, Sascha Doerdelmann, Shawn Garbett, Andreas Schörk, Dan\nČermák, Kirill Lashuk and Markus Napp for contributing additions, test cases and\nbugfixes. The complete list of contributers is\n[here](https://github.com/monora/rgl/contributors).\n\n## Links\n\n- See {file:CHANGELOG.md} for major/breaking updates.\n- To **contribute**, please read {file:.github/CONTRIBUTING.md} first.\n- Please [open an issue](https://github.com/monora/rgl/issues/new) if anything\n  is missing or unclear in this documentation.\n\n## Copying\n\nRGL is Copyright (c) 2002,2004,2005,2008,2013,2015,2019,2020,2022,2023 by Horst\nDuchene. It is free software, and may be redistributed under the {file:LICENSE}\nand terms specified in the LICENSE file.\n","funding_links":[],"categories":["Ruby","Scientific"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonora%2Frgl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonora%2Frgl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonora%2Frgl/lists"}