Graphs.jl icon indicating copy to clipboard operation
Graphs.jl copied to clipboard

[Port] A proposal of an all_simple_paths function implementation

Open etiennedeg opened this issue 3 years ago • 16 comments

this is a port of #1540

etiennedeg avatar Oct 29 '21 14:10 etiennedeg

Codecov Report

Merging #20 (acf0d5a) into master (6ab2160) will increase coverage by 0.00%. The diff coverage is 100.00%.

@@           Coverage Diff           @@
##           master      #20   +/-   ##
=======================================
  Coverage   99.45%   99.46%           
=======================================
  Files         106      107    +1     
  Lines        5554     5609   +55     
=======================================
+ Hits         5524     5579   +55     
  Misses         30       30           

codecov[bot] avatar Nov 07 '21 22:11 codecov[bot]

What about making the default cutoff smaller? typemax(T) is just completely impractical right? Even in 32 bit int that is ~10^10. What about min(typemax(T), nv(g)^3) or something?

Also, I think we should throw an exception if you hit the cutoff. That way people know that they should either increase the cutoff and try again or give up on enumerating all the paths in the graph. Silently giving an incomplete enumeration isn't the right answer.

jpfairbanks avatar Nov 08 '21 14:11 jpfairbanks

@etienneINSA, @matbesancon, Any thoughts on raising an exception if we don't yield all the simple paths? I've never needed all the simple paths, so I don't really know the application context, but I would expect that if I got a partial result, it would come with some return code I could check, or exception that I needed to catch.

jpfairbanks avatar Nov 13 '21 21:11 jpfairbanks

Any thoughts on raising an exception if we don't yield all the simple paths?

When does this happen? I didn't see this path in the code?

matbesancon avatar Nov 13 '21 22:11 matbesancon

Any thoughts on raising an exception if we don't yield all the simple paths?

When does this happen? I didn't see this path in the code?

This is not implemented yet, just a thought on if we need to implement it.

Silently giving an incomplete enumeration isn't the right answer.

Agreed. I don't have a strong opinion on how to do that, but it is also possible to just return a flag. Maybe we can implement this as an iterator on simple paths ? (So no cutoff needed)

etiennedeg avatar Nov 15 '21 10:11 etiennedeg

Related to #106

gdalle avatar Mar 10 '22 07:03 gdalle

What is the current status of this PR? I.e. who's turn is is to review/write code?

simonschoelly avatar Jul 24 '22 14:07 simonschoelly

What is the current status of this PR? I.e. who's turn is is to review/write code?

I was not aware we had defined turns, I thought it was more of a "whoever has time does their bit". As far as I'm concerned, I need to hand in my thesis manuscript in a month so i'm out of the equation for now

gdalle avatar Jul 24 '22 14:07 gdalle

What is the current status of this PR? I.e. who's turn is is to review/write code?

I was not aware we had defined turns, I thought it was more of a "whoever has time does their bit". As far as I'm concerned, I need to hand in my thesis manuscript in a month so i'm out of the equation for now

No of course there is no formal process, I was just trying to understand where we are :)

Good look with your manuscript,, I will try to avoid pinging you any further then for now.

simonschoelly avatar Jul 24 '22 14:07 simonschoelly

Good look with your manuscript,, I will try to avoid pinging you any further then for now.

On the contrary, do ping me when you need a quick opinion, it's the only way you'll get my attention ^^ But I won't be able to contribute lengthy reviews or code until the summer has elapsed

gdalle avatar Jul 24 '22 14:07 gdalle

@samurai-kant We need this

mschauer avatar Aug 17 '22 13:08 mschauer

By using outneighbors, does this work for directed and undirected graphs?

mschauer avatar Aug 17 '22 14:08 mschauer

Hi, I am the author of the original implementation. Thank you for being so interested in my PR. I recently found this project!

I will answer some questions.

@mschauer

By using outneighbors, does this work for directed and undirected graphs?

Yes. This support both. See the example below.

println("undir:", collect(all_simple_paths(cycle_graph(4), 1, [3])))
println("dir:", collect(all_simple_paths(cycle_digraph(4), 1, [3])))
> undir[[1, 2, 3], [1, 4, 3]]
> dir[[1, 2, 3]]

@jpfairbanks

What about making the default cutoff smaller? typemax(T) is just completely impractical right? Even in 32 bit int that is ~10^10. What about min(typemax(T), nv(g)^3) or something?

The resulting paths do not have any loop. So the cutoff upper bound is: nv(g), the paths that visit all nodes. Here, I intended to set no limit for the path length by using typemax. Note that the cutoff does not mean the number of outputs but the maximum length of each individual path, in other words, the max depth of the search path.

Also, I think we should throw an exception if you hit the cutoff. That way people know that they should either increase the cutoff and try again or give up on enumerating all the paths in the graph. Silently giving an incomplete enumeration isn't the right answer.

Would you clarify the meaning of "incomplete enumeration" in your comment? If a user set cutoff=c, the user expects the paths whose lengths are less than or equal to c, and the function returns all paths that satisfy the condition. In that sense, the enumeration is complete, I think. If the user wants to limit the iteration count and restart it afterward, the user can use Iterators.Stateful and Iterators.take. See:

g = complete_graph(5)
path_iter = Iterators.Stateful(all_simple_paths(g, 1, 2))
println("first 3:", collect(Iterators.take(path_iter, 3)))
println("rests:", collect(path_iter))
> first 3:Any[[1, 2], [1, 3, 2], [1, 3, 4, 2]]
> rests:Any[[1, 3, 4, 5, 2], [1, 3, 5, 2], [1, 3, 5, 4, 2], [1, 4, 2], [1, 4, 3, 2], [1, 4, 3, 5, 2], [1, 4, 5, 2], [1, 4, 5, 3, 2], [1, 5, 2], [1, 5, 3, 2], [1, 5, 3, 4, 2], [1, 5, 4, 2], [1, 5, 4, 3, 2]]

If you want to increase the depth gradually, we need to implement a breadth-first path search. It is possible, but I think the bfs requires much more memory footprint.

Please let me know if there is anything I can do to help you move forward with your review.

i-aki-y avatar Apr 04 '23 12:04 i-aki-y

Thank you, and sorry that this got stalled, @i-aki-y . I think this is fine, setting the cutoff to typemax(Int) just means there is no cut-off which is a reasonable default even if unsuitable for large graphs.

mschauer avatar Feb 14 '24 15:02 mschauer

I have no push access, can't proceed here (e.g. resolving the conflicts).

mschauer avatar Feb 16 '24 23:02 mschauer

It's weird, cause as a member of JuliaGraphs you should be able to work on this PR. Maybe @etiennedeg can give you access to his branch?

gdalle avatar Feb 21 '24 12:02 gdalle

Superseded by #353

gdalle avatar Apr 05 '24 18:04 gdalle