-
Notifications
You must be signed in to change notification settings - Fork 214
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 rank spanning branchings routine for possible inclusion in library. #82
base: develop
Are you sure you want to change the base?
Conversation
I'm helping out with the PR backlog. Looks like you have feature additions, new documentation, no test, and new examples will be needed. Please add tests for your added features. This is to let you know and help me prioritize PR's. |
Thanks for the update. There are two examples included in the pull request: example/rank-branchings1.cpp and example/rank-branchings2.cpp Once compiled, they are executed as: ./rank-branchings1 and (for example) ./rank-branchings2 branching_input.txt -10 I've included the compilation of these in the example/Jamfile.v2. There is also a test: test/rank_branchings_test.cpp Once compiled, this can be executed as (for example) ./rank_branchings_test 4 10 I've included it in the test/Jamfile.v2 file. I notice above that two Travis builds failed on my complex graph for clang on linux. I can't find anything wrong with my file and have succeeded compiling and running the test code with clang-4.0 on a linux computer, so I wonder if there is an issue with the compiler on the test machine. Nevertheless, I suppose this needs to be addressed. Best wishes. |
I'm in the process of dealing with some other build and test failures. When I'm done with those, I'll have you rebase your changes on upstream and that may fix your problems. Thank you for following up! |
Can you rebase your PR? |
I've squashed and reworded commits. I've rebased to boostorg:develop. I'm still seeing a couple of travis-ci failures that I can't reproduce on my end. Thanks, and best wishes. |
You test around line 820 has a template faux pas, and is causing timeout errors. Better, but you still need to put in just a little more work. You're close! |
ed7585b
to
613a5f5
Compare
I'll get to a proper review when I can. This week got really busy for me, sorry! |
@mbradle It appears that you're still not rebased on boostorg/graph's devel branch. Please do so. |
@mbradle Looking more closely now. It looks like you've done your job and everything does appear clear. I'll need to take more time to look through though. Please be patient while I catch up! |
Sorry, I rebased again before I saw your last message. I hope that's ok. Best wishes. |
|
||
Edge e; | ||
|
||
heap::fibonacci_heap<BranchingEntry<Edge, WeightMap, Compare> > Q; |
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.
In the same tradition of other Boost.Graph algorithms, I would recommend trying to allow the user to choose what type of property map and min heap to use, and provide these choices as defaults.
Some users will have special-case problems where different data structures are better, and in the future there might simply be a better property map, or min heap in general.
You'll have to experiment to find the best way to do it, but in general by making these data structures parameters to the algorithm so that users can pass them in by reference and an overload without those parameters that chooses the defaults. It will require some experimentation and might have to be all or nothing.
The other benefit of letting the client pass in data structures by reference is that the final result of computation is in them for the client to query afterwards if they like. (Think, for example, the open and closed sets in A*.)
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.
I'm going to sit back and see how someone more experienced reviews these.
So a default of a Fibonacci heap, but are there any extra concepts which must be true for a data structure to be viable that can be checked for?
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.
Thanks for this. I use two priority queues--one to keep track of branchings in the ranking routine and one to keep track of edge weights in the best and next routines. The former is just a regular priority queue (PriorityQueue concept), but the latter needs to be mergeable (MergablePriorityQueue concept). Neither one is "visible" to the user, and the former queue will have had all its entries popped off if all branchings have been found, but I do think it makes sense to allow the user to choose, with the Fibonacci heap as the default. I'll experiment with this (I think there are some examples in Boost Graph), and with the desirability of distinguishing between the two queues (as input--that is, pq1 for the branchings and pq2 for the graph edge weights).
|
||
vertex_idx_t n = num_vertices(g); | ||
|
||
disjoint_sets<Rank, Pred> W( rank, pred1 ), S( rank, pred2 ); |
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.
I understand the motivation for single-letter variable names like W
, S
, C
, etc, but in my experience, it's better to use a descriptive name. Not everyone has the algorithm paper on hand to look up what the letters mean. And it makes the variables awfully hard to text search for in a file, such as in this review.
g
for graph, u
and v
for vertices, etc I think is fine... there is no perfect rule about it.
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.
Thanks, I agree with this suggestion. Going through and making the changes will probably only reinforce your point.
|
||
unordered_set<Edge> best_branching, empty_set; | ||
|
||
shared_ptr< std::pair<Edge, weight_t> > p; |
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.
Why shared_ptr
? Is that really necessary?
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.
Why avoid a shared pointer? What is bad about them?
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.
Like any programming construct they are not bad intrinsically, but they are often misused when a simpler construct would suffice.
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.
Thanks for this. I used pointers to check for uninitialized or not found objects, but I think maybe boost::optional is better. For example,
shared_ptr< std::pair<Edge, weight_t> > p; | |
boost::optional< std::pair<Edge, weight_t> > p; |
The NEXT routine could then return the appropriate pair, if found. If not found, p will be null (I guess really boost::none), as in the current implementation. I have a branch that does that successfully. Are there any caveats to boost::optional?
else | ||
{ | ||
return; | ||
} |
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.
Some of the indentation here seems to have gone awry?
unordered_set<Edge>& include_edges, | ||
unordered_set<Edge>& exclude_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.
This function, next_spanning_branching
, is very long. I recommend you break it up along the lines of major sequences, loops and/or conditions.
I have a couple of big, no change PR's you might want to keep an eye on. |
…f queues in implementation routine. Rename some variables.
Hello,
I am opening a new version of this pull request (previous version). I've squashed all the development commits into a single commit (but have included the development history in the commit message).
The documentation file (rank_spanning_branchings.html) describes the added code (rank_spanning_branchings.hpp). I've included two examples (rank-branchings1.cpp and rank-branchings2.cpp), the second of which reads an input file (branching_input.txt). I've also included a test routine (rank_branchings_test.cpp). I added the examples and the test to the corresponding Jam files. These have small conflicts with the development branch that I thought it might be better for the maintainers to resolve.
Thanks for your consideration, and best wishes.
Brad Meyer