-
Notifications
You must be signed in to change notification settings - Fork 249
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
DFS and DFS iterator #315
DFS and DFS iterator #315
Conversation
Alright, I implemented two things:
I also added tests to for these guys and also one test for There is one thing I am not quite sure about in terms of API. Since I didn't understand it I did not add any Otherwise ready to merge. |
Thanks a lot for this PR! Yes, the problem with BFS and DFS in general is that the "pythonic" way of doing these is via iterators or generator functions, and neither of them can be connected with the C interface because the C core is fundamentally different (it calculates the whole BFS / DFS in advance). That's why we have I'll start reviewing this soon. |
src/igraph/__init__.py
Outdated
while stack: | ||
vid = stack[-1] | ||
if mode == IN: | ||
edges = self.vs[vid].in_edges() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we simply use self.neighbors(vid, mode=mode)
here? This would avoid creating a Vertex
object (the output of self.vs[vid]
) and would also simplify the code that comes later when we have to figure out which is the "other" endpoint of the edge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another trick that comes into my mind: we could have another stack where we push the retrieved neighbors of vid
when it is visited for the first time. Then, whenever we need to find the next neighbor of vid
to visit, we simply pop off the last element of the list. If the list is empty, there are no more neighbors of vid
to visit so we can backtrack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright I use neighbors now, good catch.
I tried playing a little with a different stack with all new neighbors, but it didn't make much of a change in terms of speed. I guess we could use a heap to keep the things sorted by distance and parent, but I'm not sure it improves a lot considering it's pure Python anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good - the only suggestion that should seriously be considered is the usage of self.neighbors(vid)
instead of self.vs[vid].out_edges()
(or .in_edges()
) to retrieve the neighbors. This is a low-hanging fruit that would also simplify some of the code that follows after it.
Good, I made the neighbors and all other changes, ready to merge. If you want to elaborate a bit on the "second stack" idea I'm happy to hear, else let's merge. |
Okay, let's merge this now and I might experiment a bit with the idea that I outlined above. |
FYI, this is what I was thinking about: 5e4a5e2 |
I see, you're caching the function call, looks good
…On Tue, Aug 4, 2020, at 21:51, Tamás Nepusz wrote:
FYI, this is what I was thinking about: 5e4a5e2
<5e4a5e2>
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#315 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAJFEABT2MGBYXKVI6V4S43R67Y4NANCNFSM4PLFPIFA>.
|
This PR aims at addressing #295.
In that issue a trivial Python implementation using recursion is proposed. That would be simplest, of course, but potentially runs into a few issues:
The way BFS is coded is via a two-tier system:
igraph_i_bfs
Both live at the C API interface with Python and are not recursive, therefore should be more performant than an equivalent, pure Python recursive call.
This PR aims at either of the following three:
Any preferences out there among these?