Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Redesign How Rapids Are Handled #101

Open
JeffThorslund opened this issue Jan 3, 2021 · 2 comments
Open

Redesign How Rapids Are Handled #101

JeffThorslund opened this issue Jan 3, 2021 · 2 comments
Assignees

Comments

@JeffThorslund
Copy link
Owner

Rivers, Sections, and Rapids as Data Structures

Rivers can be imagined as an arrays of sections. They are an ordered sequence of rapid properties where the order is relevant. The rapids within a section can be viewed the same way. They are an ordered sequence of information. This would make traversing arrays of rapids very easy. A method to traverse to the next rapid (or downstream) would simply be Navigate to current index + 1 and going backwards (or upstream) would just be Navigate to current index - 1. This is ideal, because the order of the sections array and the rapids array also inherently contain all information about their layout in space.

This ALMOST always works.

In some cases, a river will fork into 2 simultaneous sections and rejoin. Likewise, within a section, the river can fork, creating several simultaneous rapids that reconnect within that same section.

How do we convey this in a way that is both logical and scalable?

How Navigating Between Rapids is Currently Handled

Even though rapids are currently stored in an array, the benefits of an ordered list are not taken advantage of.

  1. A "next rapid" button has an associated "target id".
  2. All elements in the array are searched for the "target id" property.
  3. "next rapid" button links to that the rapid with matching id.

A Better Way?

Warning: Another git reference.

Rivers are actually extremely similar to the following git screenshot. They branch and reconnect.

image

What would be IDEAL is a data structure that would be able to hold this pattern as part of its inherent structure. This would also mean that it would be able to programmatically be able to generate a diagram as seen above for each river.

Ideas

I am a bit hesitant to say this, but could it be a directed graph? The entire river could have a property of an adjacency matrix OR every rapid could have an adjacency list property. It seems a bit too complicated, but it would be really cool if it worked perfectly for our use case 😀

@alexandrehassan
Copy link
Collaborator

I love the git reference it really seems to sum up what I would have looked for (plus the graphs they create look like rivers). I've spent some time reading about directed graphs and discovered that Git uses a fancy implementation of a Directed Acyclic Graph (DAG, wikipedia).

This is a case of a graph where there are no cycles (rivers can't go back up), directed, connected, Root Node ( can have multiple ).

I don't know how easy it is to implement/use but this seems to really describe what we are trying to accomplish.

@JeffThorslund
Copy link
Owner Author

Great find! I just read up on DAGs and I think I found the cherry on top. Edge weights used to represent distance between rapids.

This is just too cool not to try 💯

I'm imagining it like this, where...

image

Would be...

const rapids = [
  {
    id: "rapid_1",
    adjacent: [
      {
        node: "rapid_2",
        edge: 3,
      },
    ],
  },
  {
    id: "rapid_2",
    adjacent: [
      {
        node: "rapid_3",
        edge: 1,
      },
      {
        node: "rapid_4",
        edge: 1,
      },
    ],
  },
  {
    id: "rapid_3",
    adjacent: [
      {
        node: "rapid_5",
        edge: 2,
      },
    ],
  },
  {
    id: "rapid_4",
    adjacent: [
      {
        node: "rapid_5",
        edge: 2,
      },
    ],
  },
  {
    id: "rapid_5",
    adjacent: [],
  },
];

We would then write some utilities...

  • Check that it's directed.
  • Check that it's acyclic.
  • Check for unconnected nodes.

I mean is that it?? Seems like its a pretty reasonable implementation :)

What do you think of this? Any other utilities, or properties, or things that could go horribly wrong?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants