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

feat: graph module and priority queue Dijkstra implementation #52

Merged
merged 15 commits into from Feb 23, 2022

Conversation

joao-conde
Copy link
Contributor

@joao-conde joao-conde commented Feb 22, 2022

This relates to the RIPE Tech issue of multiple state transitions.

For RIPE Tech, we will need to find the shortest path between two states and make all the in-between transitions.
Instead of a bespoke solution for order states only, I thought it was better to generalize the issue at hand: finding the shortest path in the graph. Hence I decided to implement a simple Dijkstra. This will allow us to abstract that logic here and simply apply the transitions in RIPE Core. It will also work for future entities with their own states and state graphs (while a bespoke solution for Order statuses only would not).

I think this source makes sense to be added to the Appier codebase because a graph module and graph utilities by themselves are useful in many domains (maybe in the future in networking to find the shortest path between nodes).

The proposed and implemented API is:

import appier

# a list of edges which is a list of tuples
# where the first element is the source node
# the second element is the destination node
# the third element is the cost of the edge (defaults to 1)
# the fourth element indicates whether the edge is bidirectional or not (defaults to unidirectional)
edges = [
    ("A", "B"),
    ("A", "C", 6, True),
    ("B", "D"),
    ("C", "D"),
    ("D", "E", 10),
    ("D", "F", 15),
    ("E", "F", 6),
    ("E", "G", 2),
    ("F", "G", 6)
]
graph = appier.Graph()
graph.add_edges(edges)

path, cost = graph.dijkstra("A", "F")
assert(path == ['A', 'B', 'D', 'F'])
assert(cost == 17)

Initializing the graph can also be done by passing the edges as an argument:

graph = appier.Graph([
    ("A", "B"),
    ("A", "C", 6, True),
    ("B", "D"),
    ("C", "D"),
    ("D", "E", 10),
    ("D", "F", 15),
    ("E", "F", 6),
    ("E", "G", 2),
    ("F", "G", 6)
])

@joao-conde
Copy link
Contributor Author

@joamag manual tagging

@coveralls
Copy link

coveralls commented Feb 22, 2022

Coverage Status

Coverage increased (+0.4%) to 64.341% when pulling b82b929 on joao-conde:master into 97c854d on hivesolutions:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.04%) to 63.935% when pulling 5a44381 on joao-conde:master into 97c854d on hivesolutions:master.

@joamag joamag merged commit 4202b7f into hivesolutions:master Feb 23, 2022
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

Successfully merging this pull request may close these issues.

None yet

3 participants