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
Determine if a vertex is a cut vertex #13289
Comments
comment:1
I'm not fully satisfied of this patch, but I have no better implementation in mind. For digraphs, this patch considers weakly connected components, but it could also considers strongly connected components. I'm not sure of the most relevant definition. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
comment:3
I'm not sure of the most relevant definition either, but blocks_and_cut_vertices also uses the underlying graph for directed graphs. I tried using blocks and cut vertices to write is_cut_vertex, but it appears to be much slower (as expected). I'm not sure of a better way to implement this. The tests all ran fine, maybe it's a good idea to add a digraphs test/example? |
comment:4
I added a test on a digraph. I don't know how to make this patch faster. So unless someone has a better proposition now, you can validate this patch, and future improvements will go to a new patch. Thanks. |
comment:5
Good, all the tests ran fine. When I built the documentation I noticed a colon is missing in line 4026 so the example with giving a vertex not in the graph isn't showing up properly. Once that is fixed I'll give a positive review. |
comment:6
Oups. That's the default of working remotely. I don't always notice such mistakes. |
comment:8
Thanks for the review ! |
comment:9
Please fill in your real name as Reviewer. |
comment:10
There is major problem with this patch. It modifies the given graph. While it tries to revert the effect, this is still a bad idea. If an exception occurs between the removal of the vertex and the addition of the edges then the graph will end up modified (just think of CTRL+C or out of memory). Also the reversal doesn't work for directed graphs currently. Just check the number of edges of D in your test case. I'd argue that you shouldn't try to fix the reversal, but get rid of it. I don't now much about the problem, so can't suggest a better algorithm that what a quick google search would reveal. If you can't find a better algorithm, make a copy of the graph and modify this copy. |
comment:11
That's right, the patch should not modify the graph. Unfortunately I have no got implementation to propose. In particular, it is impossible to use the blocks and cuts procedure since it is way to slow (should be cythonized some day). I have changed the patch. I'm not happy with this implementation but it's working. One may later propose a faster implementation. |
comment:12
If fact the running time of the function is largely dominated by the copy of the graph. This is boring. |
comment:13
At least for the undirected case you could perform two DFSs and count the visited vertices. The first search would start at v and run on the orginal graph. The second one would ignore all edges incident to v and start at any neighbor of v. If v is not a cut vertex, the number of visited vertices should decrese only by 1. For the first search you could call connected_component_containing_vertex. For the second run you need to inline the code and add the ability to ignore edges. |
comment:14
I fact, only one DFS is required for undirected graphs (or weak connectivity), and two for the strong connectivity of directed graphs. I don't need to copy the graph anymore and the running time of the resulting algorithm is acceptable.
The only way to be faster is to use cython, as for the is_strongly_connected function. But I'm not sure it is worth the effort. |
comment:15
Nice work!
should be:
should be:
i.e. store them in a set and call discard on the set whenever you add a vertex to 'seen'. Then abort the dfs when the set is empty. |
comment:16
You are right for 1 and 3. It's not obvious for me to write such stuff. 2: it's just that both are working. I changed to is_directed() which is cleaner. 4: I did it. So far I have not seen any difference but it could be interesting for some graphs, and it is strongly dependent on the dfs ordering. I have also changed seen from set to dict. It could be faster to access a cell of a dictionary than to test is a elt is in a set. Furthermore, I avoid testing w!=u by initializing seen[u] to True, so it will never be considered. Thanks for the comments. |
comment:17
I changed the position of the targets.discard(w) to discard when it enters the queue and not when it is removed. That's better. |
comment:18
Replying to @dcoudert:
IIRC they are both implemented as hash maps, which should make the set faster. I think it has something to do with the fact that the "v in s" has to catch the KeyError and return False instead of just raising the exception. That's exactly what happens with your dict here. It doesn't catch KeyError, but that's fine because it never occurs. Making it faster. In contrast, if you let it catch the exception aka "seen.get(w, False)", the dict is a lot slower.
Good idea. Once I checked the manual and ptestlong, I'll give it a positive review. |
comment:19
I found a bug in the directed case.
Edit: Possible solution: Check only those neighbors which are in the same strong component as v. |
comment:20
Ouppss. This is solved in this new version. I'm using a set of vertices to restrict the DFS to the vertices in the connected or strongly connected component containing u. I have also restored the I hope everything is in order now ;-) Don't forget to put your name as reviewer. |
comment:21
Replying to @dcoudert:
Is this really necessary for the undirected case? Aren't all neighbors of v in the same connected component as v? |
Reviewer: Sebastian Luther |
comment:23
Yes, all neighbors of v are in the same connected component. I have replaced the code with I did several tests to see if it would be faster to duplicate the code to avoid the test |
comment:24
Tests pass, documentation looks good. Positiv review! |
comment:25
Thanks for the review and all the comments. The patch is much better now. |
comment:26
This needs to be rebased to sage-5.3.beta1. |
Attachment: trac_13289_is_cut_vertex.patch.gz rebased for sage-5.3.beta1 |
comment:27
Hello, I have rebased the patch to sage-5.3.beta1, so it should be easily reviewed. Best, |
comment:28
For a trivial rebase, you can change the status yourself to |
comment:29
I didn't know that. |
Merged: sage-5.4.rc0 |
This patch test if a given vertex is a cut vertex, that is if its removal from the (di)graph increases the number of (weakly) connected components.
CC: @sagetrac-lkeough
Component: graph theory
Author: David Coudert
Reviewer: Sebastian Luther
Merged: sage-5.4.rc0
Issue created by migration from https://trac.sagemath.org/ticket/13289
The text was updated successfully, but these errors were encountered: