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

Add shortest path algorithm #368

Merged
merged 4 commits into from
May 20, 2023
Merged

Conversation

acombretrenouard
Copy link
Contributor

Related to issue #365.

I added a new file ./xgi/algorithms/shortest_path.py containing two functions (single_source_shortest_path and shortest_path_length).
There is also a new function in ./xgi/utils/utilities.py.

The functions are structured as in networkx and implement the Disjkstra algorithm.
Naming could be improved.

Corresponding test (for algorithms and utilities) and documentation are written. The changelog is up to date as well.
I successfully run pytest, isort ., pylint xgi/ --disable all --enable W0611 and black ..

@codecov
Copy link

codecov bot commented May 19, 2023

Codecov Report

Patch coverage: 100.00% and project coverage change: +0.16 🎉

Comparison is base (9318be2) 90.58% compared to head (43669cc) 90.74%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #368      +/-   ##
==========================================
+ Coverage   90.58%   90.74%   +0.16%     
==========================================
  Files          41       42       +1     
  Lines        3060     3113      +53     
==========================================
+ Hits         2772     2825      +53     
  Misses        288      288              
Impacted Files Coverage Δ
xgi/algorithms/__init__.py 100.00% <100.00%> (ø)
xgi/algorithms/shortest_path.py 100.00% <100.00%> (ø)
xgi/utils/utilities.py 100.00% <100.00%> (ø)

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Collaborator

@nwlandry nwlandry left a comment

Choose a reason for hiding this comment

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

Overall, looks great @acombretrenouard! Clean code, nice comments, and good testing! My biggest question is on the data structure of the path lengths. Thanks for the contribution!

README.md Outdated
@@ -104,3 +104,4 @@ This library may not meet your needs and if this is this case, consider checking
* [HyperGraphs.jl](https://github.com/lpmdiaz/HyperGraphs.jl): A package in Julia for representing, analyzing, and generating hypergraphs which may be oriented and weighted.
* [hyperG](https://cran.r-project.org/package=HyperG): A package in R for storing and analyzing hypergraphs
* [NetworkX](https://networkx.org/): A package in Python for representing, analyzing, and visualizing networks.
![](![https://github.com/acombretrenouard/xgi.git](![https://github.com/acombretrenouard/xgi.git](https://github.com/acombretrenouard/xgi.git)))
Copy link
Collaborator

Choose a reason for hiding this comment

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

What's the reason for this line?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I don't know. I saw it appearing after the pull request.
Just delete it !

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks great. My biggest question would be whether it makes more sense to store the path lengths as a numpy array with a dict mapping node IDs to matrix row/columns.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to reproduce the signature of shortest_path_length in networkx.
In particular the returns are structured as explained here :

If the source and target are both specified, return the length of the shortest path from the source to the target.
If only the source is specified, return a dict keyed by target to the shortest path length from the source to that target.
If only the target is specified, return a dict keyed by source to the shortest path length from that source to the target.
If neither the source nor target are specified, return an iterator over (source, dictionary) where dictionary is keyed by target to shortest path length from source to that target.

I think returning a generator instead of an array is great for computing shortest paths on-the-fly and saving memory. I guess with time people figured out this was the best way (?).

Thanks for the feedback :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Gotcha. Thanks for the explanation! I think I'm good with merging this. And I guess that it only makes sense to take advantage of the $d(n_1, n_2) = d(n_2, n_1)$ symmetry if a matrix is outputted. Nice work!

@acombretrenouard
Copy link
Contributor Author

I restored README.md as requested by @nwlandry.

@nwlandry nwlandry merged commit 5cff847 into xgi-org:main May 20, 2023
18 checks passed
@nwlandry
Copy link
Collaborator

Congrats on your first XGI contribution, @acombretrenouard ! Excited to start computing some shortest paths! 😁

@maximelucas
Copy link
Collaborator

Thanks @acombretrenouard, and congrats !!

What are the details of this generalization to hypergraphs? Are you looking at paths between nodes through hyperedges of any size? When you compute the shortest path, a pairwise edge and a triangle would both count as "length 1" in the path?

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