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

Fix BFSWithDepth visit callback invoked with incorrect depth #154

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

s111
Copy link

@s111 s111 commented Sep 20, 2023

Hi,

Thanks for making this library, awesome work!

I tried to use BFSWithDepth today and it would seem that the depth is not correctly being supplied to the callback. I see that an issue is already reported here #153.

This pull request is my attempt at resolving this bug, I hope that it looks good.
I've added an inner for-loop which ensures that all vertices at the current depth is visited before incrementing the depth again at the start of the outer loop.

It looks like the test that was added with #120 doesn't actually verify the depth, so I've extracted a new test function for BFSWithDepth.

(I also took the liberty to remove what looks like some forgotten debug print statements, I hope that's OK.)

This commit fixes BFSWithDepth such that it stops after visiting all
nodes at the depth the visit callback first returned false.

Note: This also affects BFS as it invokes the BFSWithDepth
function.
@dominikbraun
Copy link
Owner

Thanks for your PR! I'm currently having a busy time at work but I'm take a look as soon as I can.

@GZGavinZhao
Copy link

You don't need an extra loop. An extra map depth map[K]int to keep track of the actual depth of the node should be enough.

diff --git a/traversal.go b/traversal.go
index d7e232c..196dfe2 100644
--- a/traversal.go
+++ b/traversal.go
@@ -126,25 +127,26 @@ func BFSWithDepth[K comparable, T any](g Graph[K, T], start K, visit func(K, int
 
        queue := make([]K, 0)
        visited := make(map[K]bool)
+       depths := make(map[K]int)
 
        visited[start] = true
        queue = append(queue, start)
-       depth := 0
+       depths[start] = 0
 
        for len(queue) > 0 {
                currentHash := queue[0]
 
                queue = queue[1:]
-               depth++
 
                // Stop traversing the graph if the visit function returns true.
-               if stop := visit(currentHash, depth); stop {
+               if stop := visit(currentHash, depths[currentHash]); stop {
                        break
                }
 
                for adjacency := range adjacencyMap[currentHash] {
                        if _, ok := visited[adjacency]; !ok {
                                visited[adjacency] = true
+                               depths[adjacency] = depths[currentHash] + 1
                                queue = append(queue, adjacency)
                        }
                }

@jamesl33
Copy link

jamesl33 commented Oct 3, 2024

Apologies for the bump but I've just stubbed my toe on this and it'd be great to see if we can drive it across the line, if someone could review that'd be much appreciated 🙏

If the PR has stagnated or needs review comments addressing I'd be more than happy to do-so but generally things look good, and they're working nicely while using a replace directive.

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.

4 participants