Skip to content

Graphs Pattern #68

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
wants to merge 9 commits into from
Closed

Conversation

jbgriesner
Copy link

An idiomatic way to implement graphs in Rust.

```rust
// A node of the graph.
pub struct Node<T> {
parent: Option<NodeId>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a node can have at most one parent, then the data structure is a tree, not a graph. Nodes in a graph can have more than one parent.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks more like a forest, since this code allows for multiple roots 😉

@nrc
Copy link
Collaborator

nrc commented Feb 6, 2018

This is a way to have a graph in Rust, I'm not sure if its the best way. It's also possible to use Rc and RefCell with some kind of cycle tracking/detection, or unsafe code in numerous ways.

@jbgriesner
Copy link
Author

I made a distinction.
I will code different ways to have graph.

@lambda-fairy
Copy link
Collaborator

Found this while going through old PRs.

In my view, the intention of this patterns repo is to document situations where there is usually one "best" solution. So an overview of many different graph implementations, while valuable, would not belong here.

I will close this PR. Thanks!

@simonsan simonsan added C-needs discussion Area: Something that is not clear to everyone if it fixes something/adds valuable content C-zombie Category: A PR/an Issue that might be still useful but was closed labels Dec 31, 2020
@simonsan
Copy link
Collaborator

In my view, the intention of this patterns repo is to document situations where there is usually one "best" solution. So an overview of many different graph implementations, while valuable, would not belong here.

I will close this PR. Thanks!

Imho a best solution is developed over time, I think it could be valuable, as this content doesn't exist in the repository already, to state explicitly that it's not sure to be the best solution but that PRs are welcome to improve the examples or encourage discussion on it to come to a better solution, so I'm reopening it for further inspection.

@simonsan simonsan reopened this Dec 31, 2020
@simonsan simonsan added C-addition Category: Adding new content, something that didn't exist in the repository before and removed C-zombie Category: A PR/an Issue that might be still useful but was closed labels Dec 31, 2020
@simonsan simonsan marked this pull request as draft January 4, 2021 07:42
@simonsan
Copy link
Collaborator

simonsan commented Jan 4, 2021

But yeah, I know what lambda-fairy wanted to state, it's hard to tell this is a good solution or this not. My guess with the book would probably be a subchapter with graphs and then give some examples

or

probably better to explain the internal graph data structures as a pattern, something like that:
https://doc.rust-lang.org/1.1.0/src/rustc_data_structures/graph/mod.rs.html#11-403

and give input on how you would do that on not give some custom implementation. But maybe some recommended crates with already implemented data structures to use, to not reinvent the wheel.

Hmm, thoughts?

@fade2black
Copy link
Contributor

fade2black commented Jan 14, 2021

I think Graph data structure, on its own, is too wide topic to cover in a couple of pages. As a rule, complexity of algorithms on graphs directly depends their representation. What kind of representation we will choose depends on our use case. Factors to take into account:

  • type of graphs: complete graph, trees, directed, undirected, etc.
  • compute intensive: speed/complexity of algorithms is important, for example depending on representation DFS algorithm may work in O(n^2) or O(n + m).
  • scarce memory (embedded systems for example)
  • what kind of algorithm we implement: parallel, distributed...
  • Is graph dynamic?: we constantly add/remove vertices/edges...
  • amortised cost: for example amortised costs are given in documentations for some data structures.

Let me give a simple example. Say, I know my graph changes (new edges or vertex) once a day, but the graph is almost complete and in my algorithms I traverse neighbours of a single vertex not too often. I'd probably use adjacency matrix.

Or another example. If we know that our graph has too few edges and we do extensive DFS then matrix is a bad choice since it would have O(n^2) complexity, while using adj list we could reduce it to linear time O(n) if say m is liner in n.

@simonsan
Copy link
Collaborator

I think as well, that it should be a complete chapter of different graph structures, would you agree?

@fade2black
Copy link
Contributor

@simonsan I agree. We could categorise into use cases or representations, or anything else what people think. But not everything in a single page. Of course the Rust way should be put on the first place.

@simonsan simonsan mentioned this pull request Jan 14, 2021
@simonsan
Copy link
Collaborator

@simonsan I agree. We could categorise into use cases or representations, or anything else what people think. But not everything in a single page. Of course the Rust way should be put on the first place.

I opened an issue for discussions, it's easier going forward I guess

@pickfire
Copy link
Contributor

This is too wide and there are few patterns to solve this. But there are also many cases of graph, I think we may need a category rather than writing it like this. For example:

  • self-referencing graphs (there are even multiple ways to solve this IIRC and this is a common pitfall I think)
  • struct of array vs array of structure
  • allocate memory somewhere else and keep reference/index

@simonsan
Copy link
Collaborator

This is too wide and there are few patterns to solve this. But there are also many cases of graph, I think we may need a category rather than writing it like this. For example:

* self-referencing graphs (there are even multiple ways to solve this IIRC and this is a common pitfall I think)

* struct of array vs array of structure

* allocate memory somewhere else and keep reference/index

Let's use issue #202 to discuss it, I'll mark this as zombie for the future and close it for now.

@simonsan simonsan closed this Jan 15, 2021
@simonsan simonsan added the C-zombie Category: A PR/an Issue that might be still useful but was closed label Jan 15, 2021
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-addition Category: Adding new content, something that didn't exist in the repository before C-needs discussion Area: Something that is not clear to everyone if it fixes something/adds valuable content C-zombie Category: A PR/an Issue that might be still useful but was closed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants