Given a graph, I want to find all edges (if any), that if removed spilt the graph into two components.
An initial idea would have been to assign a weight of 1 to all edges, then calculate the mincut of the graph. mincut > 1 implies there is no single edge that when removed causes a split.
For mincut == 1, it would have been nice if the algorithm would provide for each mincut the edges it consists of.
Unfortunately, BGL does not seem to support that kind of thing:
The stoer_wagner_min_cut function determines exactly one of the min-cuts as well as its weight.
(http://www.boost.org/doc/libs/1_59_0/libs/graph/doc/stoer_wagner_min_cut.html)
Is there a way to make this work (i.e. to determine more than one mincut) with the BGL or will I have to come up with something different?
This may come a little bit late...
From what I see you only need to find all edges that don't belong to any cycle in the graph(assuming the graph is already connected).
This can be done by iteratively removing leaf nodes(and the edges connected to a them), much like what you do in topological sorting, until there's no leaf node left i.e. every edge in the remaining graph belongs to at least one cycle. All edges removed during the process will be the ones you want.
In pseudocode, for a connected undirected graph G=(V,E), you can do this:
S = Ø
while(there exists a node n∈V s.t. degree(n)==1)
e = edge connected to n
S = S∪{e}
E = E-{e}
V = V-{n}
return S
which can be done in O(|V|+|E|) time
Related
Here's an illustration of the steps taken thus far:
Pseudo-random rectangle generation
"Central node" insertion, rect separation, and final node selections
Delaunay triangulation (shown with previously selected nodes)
Rendering of triangle edges
At this point (Step 5), I would like to use this data to form a Minimum Spanning Tree, but there's a slight catch...
Somewhere in the graph (likely near the center, but not always) will be a node that requires between 3-5 connections to it from other unique nodes. This complicates things, since every other node should only contain a single connection, and the data structures being used make it difficult to determine "what's connected to what" in a solid, traversable format.
So, given an array of triangles in the above format, and a random vertex to use as the "root node", how could I properly traverse the network to create an MST where there are at least 3 connections to our "central node", but no more than 5 connections to it? Is this possible?
Since it's rare to have a vertex in a Delaunay triangulation have much more than 6 edges, you can use brute force: there are only 20+15+6 ways to select 3, 4, or 5 edges out of 6 (respectively), so try all of them. For each of the 41 (up to 336 for degree 9) small trees (the root and a few edges) thus created, run either Kruskal's algorithm or Prim's algorithm starting with that tree already "found" to be part of the MST. (Ignore the root's other edges so as not to increase its degree further.) Then just pick the best one (including the cost of the seed tree).
As for the general neighbor information problem, it seems you just need to build a standard graph representation first. For example, you can make an adjacency list by scanning over all your Edge objects and storing each endpoint in a list associated with the other (in a map<Vector2<T>,vector<Vector2<T>>> or an equivalent based on whatever identifiers for your vertices).
I've taken a workaround approach...
After step 3 of my algorithm, I simply remove all edges which connect to the "central node", keeping track of which edges form the "ring" (aka "edge loop") around it, and run the MST on all remaining edges.
For the MST, I went with the boost graph library.
That made it easy to loop through the triangles I had, adding each of its three edges to an adjacency_list. Then a simple call to whichever boost-provided MST algorithm took care of the rest.
Finally, I readd the edges that were previously taken out. The shortest path is whatever it was in the previous step, plus the length of whichever readded edge that connects to another edge on the "ring" is shortest.
I can then add (or remove) an arbitrary number of previous edges to ensure there are between 3 to 5 edges connecting from the edge loop to the "central node".
Doing things in this order also allows me to know as soon as step 3 if we'll even have a valid number of edges, so we don't waste cycles running a MST.
I was reading through the BOOST library and noticed that they dint have an algorithm to find bridges in a graph, they do have one to find articulation points. Is there anyway this could be done efficiently?
I have an idea:
1. Use the BOOST to find articulation points
2. Using out_edges,find all edges attached the each articulation point
3. remove them and calculate the number on connected components,( I assume my graph is originally fully connected), if its more than 1,i add this edge to the bridges.
QUESTION: Is it necessary for bridges to be attached to articulation points? I just assumed they are,couldn't find anything no the net.
I would also like an idea how to approach this.
My other approach would be more naive and take O(v*(V+E)), which is very bad.
Sounds a bit slow with the whole graph rewriting. You'd have to check if Boost counts a single-connected vertex as an articulation point. (If not, this slightly complicates things).
Now it is fairly obvious that a bridge must be an edge between two articulation points, but not all edges between articulation points are necessarily bridges. Consider a chain of 4 articulation points connected by 3 edges: A-b-c-D. Now add a node e connected to both b and c. The outer two bridges remain bridges, and so all 4 original nodes remain articulation points, but the middle node is no longer a bridge.
This means we have a necessary but insufficient extra condition: both nodes of the edge must be articulation points. Here's where the slight complication steps in; if Boost doesn't count single-connected nodes as articulation points, you have to treat them specially. But that's still simple; that one edge is necessarily a bridge.
This extra condition is quite efficient in dense graphs, as most nodes will not be articulation points. As a result, you cull most candidate edges before trying to alter the graph. Secondly, you don't need to test the component count of the resulting altered graph. You just need to check if the two articulation points are still connected after you cut the edge linking them directly.
There is a much easier way when you realize if a biconnected component only contains one edge this edge is a bridge. It is very easy to implement using boost (http://www.boost.org/doc/libs/1_58_0/libs/graph/example/biconnected_components.cpp):
Calculate the biconnected components
Create a edge counter for each component. Iteratate over all edge and increase the coresponding edge counter of the respective component
Iterate again over all edges and check if the edge counter of the corresponding component is 1, if so this edge is a bridge
I have a homework problem and i don't know how to solve it. If you could give me an idea i would be very grateful.
This is the problem:
"You are given a connected undirected graph which has N vertices and N edges. Each vertex has a cost. You have to find a subset of vertices so that the total cost of the vertices in the subset is minimum, and each edge is incident with at least one vertex from the subset."
Thank you in advance!
P.S: I have tought about a solution for a long time, and the only ideas i came up with are backtracking or an minimum cost matching in bipartite graph but both ideas are too slow for N=100000.
This may be solved in linear time using dynamic programming.
A connected graph with N vertices and N edges contains exactly one cycle. Start with detecting this cycle (with the help of depth-first search).
Then remove any edge on this cycle. Two vertices incident to this edge are u and v. After this edge removal, we have a tree. Interpret it as a rooted tree with the root u.
Dynamic programming recurrence for this tree may be defined this way:
w0[k] = 0 (for leaf nodes)
w1[k] = vertex_cost (for leaf nodes)
w0[k] = w1[k+1] (for nodes with one descendant)
w1[k] = vertex_cost + min(w0[k+1], w1[k+1]) (for nodes with one descendant)
w0[k] = sum(w1[k+1], x1[k+1], ...) (for branch nodes)
w1[k] = vertex_cost + sum(min(w0[k+1], w1[k+1]), min(x0[k+1], x1[k+1]), ...)
Here k is the node depth (distance from root), w0 is cost of the sub-tree starting from node w when w is not in the "subset", w1 is cost of the sub-tree starting from node w when w is in the "subset".
For each node only two values should be calculated: w0 and w1. But for nodes that were on the cycle we need 4 values: wi,j, where i=0 if node v is not in the "subset", i=1 if node v is in the "subset", j=0 if current node is not in the "subset", j=1 if current node is in the "subset".
Optimal cost of the "subset" is determined as min(u0,1, u1,0, u1,1). To get the "subset" itself, store back-pointers along with each sub-tree cost, and use them to reconstruct the subset.
Due to the number of edges are strict to the same number of vertices, so it's not the common Vertex cover problem which is NP-Complete. I think there's a polynomial solution here:
An N vertices and (N-1) edges graph is a tree. Your graph has N vertices and N edges. Firstly find the awful edge causing a loop and make the graph to a tree. You could use DFS to find the loop (O(N)). Removing any one of the edges in the loop would make a possible tree. In extreme condition you would get N possible trees (the raw graph is a circle).
Apply a simple dynamic planning algorithm (O(N)) to each possible tree (O(N^2)), then find the one with the least cost.
As my question speaks I want to know why do we use Priority queue in Prim's Algorithm?
How does it saves us from using the naive way (yes I've heard of it but don't know why).
I'd be very happy if anyone could explain step by step for adjacency list . I am using Cormen's book.
The pseudocode :
Prim(G,w,r) //what is w (weight?) and r?
For each u in V[G]
do key[u] ← ∞ // what is key?
π[u] ← NIL
key[r] ← 0
Q ← V[G]
While Q ≠ Ø
do u ← EXTRACT-MIN(Q)
for each v in Adj[u]
if v is in Q and w(u,v) < key[v]
then π[v] ← u
key[v] ← w(u,v)
I am thinking to use std::vector then std::make_heap(); as priority queue for storing edges.
In prim's algorithm, there is a step where you have to get the 'nearest' vertex. This step would cost O(N) if using normal array, but it'd take only O(logN) if you use priority queue (heap for example)
Hence, the reason for using priority queue is to reduce the algorithm's time complexity (which mean it make your program run faster)
**
Update:
**
Here is Prim's algorithm's description from Wikipedia. The bold part is the part for finding nearest vertex I talked about:
Input: A non-empty connected weighted graph with vertices V and edges E (the weights can be negative).
Initialize: Vnew = {x}, where x is an arbitrary node (starting point) from V, Enew = {}
Repeat until Vnew = V:
Choose an edge (u, v) with minimal weight such that u is in Vnew and v is not (if there are multiple edges with the same weight, any of them may be picked)
Add v to Vnew, and (u, v) to Enew
Output: Vnew and Enew describe a minimal spanning tree
You don't "need" it. In fact, a naive implementation of Prim's algorithm would simply do a linear search of the array of distances to find the next nearest vertex. Dijkstra's algorithm works the exact same way.
The reason why people use it is because it significantly speeds up the runtime of the algorithm. It turns from O(V^2 + E) to O(E*log(V)).
The key to this is the EXTRACT-MIN(Q) function. If you do it naively, this operation would take O(V) time. With a heap, it only takes O(logV) time.
Doing this roughly from memory, so it may be slightly inconsistent, but it gets the point across:
class Graph
Set<node> nodes; // The set of nodes in the graph
MultiMap<Node, Edge> edges; // Map from Node, to a list of weighted edges connected to the node. If it weren't weighted, any spanning tree by definition would be a minimum spanning tree.
Graph Prim(Graph input):
Graph MST = new Graph();
PriorityQueue<Edge> candidateEdges;
Node anyNode = input.pickAnyNodeAtRandom()
candidateEdges.putAll(input.edges.get(anyNode));
while MST.nodes.size() < input.nodes.size():
edge = candidateEdges.takeLowest() // THIS IS THE IMPORTANT PART
if edge.v1 in MST.nodes and edge.v2 not in MST.nodes:
MST.nodes.add(edge.v2)
MST.edges.add(edge)
candidateEdges.add(edge.v2.edges)
Basically, at each step in the algorithm, you're looking for the minimum edge with one vertex in the partial minimum spanning tree, and one vertex not in the tree, and you're going to add said edge to the tree. How do you do that efficiently? If you have a way to efficiently order all of the edges connected to a vertex in your partial spanning tree, you can simply iterate through them until you find an edge with an acceptable vertex.
Without such an ordered data structure, you'd have to iterate through all candidate edges each time to find the minimum, rather than being able to efficiently grab the minimum directly.
Prim's algorithm uses two Sets - lets say U and V/U.
You are starting from the root, (root is the only element in U).
You place all the vertexes adjacent to it in the queue, with weight[v] = dist[root,v] where v is adjacent to root.
So when you are popping from the queue, you are taking the vertex (lets say u) that has one end in U and end in V/U and is the smallest with that property.
You set its weight, its parent to be root and etc... and put all its ajdacent nodes in the queue. So now the queue has all the nodes ajdacent to root and all the nodes the ajdacent to root and all the nodes ajdacent to u with their respective weights. So when you pop from it, you will once more get a node from V/U which is 'closest' to U.
In the implementation, they are initially adding every vertex to the queue with INFINITY priority, but they are gradually updating the weights, as you can see. This reflects in the priority queue as well, guaranteeng the text above.
Hope it helps.
I have an undirected graph network made of streets and crossings, and I would like to know if there is any algorithm to help me finding closed loops, ie places where I can put buildings.
Any help appreciated, thanks !
Based on comments to my earlier answer:
It seems the graphs are all undirected and planar, i.e. can be embedded in a 2D plane without crossing edges, and one such embedding is given. This embedding will partition the plane. E.g. a figure 8 partitions the plane in three: two "inner" areas and an infinite outer area. An alternative view is that all edges of a node are cyclically ordered. (This is the essential part that allows us to apply graph theory)
A partition is necessarily enclosed by a cycle, but not all cycles may partition a single area. In the trivial case of a figure 8, though, all three areas are directly associated with a distinct cycle.
The input graph can generally be simplified. Some nodes may have only a single edge; they can't contribute to the partitioning and can be removed along with the edge. Other nodes have two edges connecting distinct nodes. Here, the node and the two edges can be replaced by a direct edge connecting the neighbors. I.e. a figure 8 graph can be simplified to two nodes and three edges between them. (This is not a necessary step but helps computation).
Now, each vertex will have two areas to either side (since they're undirected, "left and right" aren't obvious distinctions). So, for |V| vertices, we need to consider 2 * |V| sides. They're in general not distinct. Two adjacent edges (connected to the same node) may border the same area, if they're also adjacent in the cyclic order of edges of that node. Obviously, for nodes with only two edges, the two edges share both areas (which is why we'd eliminated them in the previous step). For nodes with three edges, any two edges share at least one area.
So, here's how to enumerate those areas: Assign a sequential number to all edges and vertices. Assign a direction to each edge so it runs from the lower-numbered edge to the higher. Start with vertex 1, right side, and number this area 1. Trace the boundary edges of this area, assigning the same number 1 to the appropriate sides of its boundary edges. You do this by taking at each node the next adjacent edge in counter-cyclical order. When you get back to your starting point, you know all edges bounding area 1.
You then check the left edge of the first vertex. If it's not part of area 1, then it's area 2, and you apply the same algorithm. Next, check vertex 2, right side and left side, etc. Each time you find an edge and a side that's unnumbered yet, assign the next area number and trace the edges of the newly founded area.
There's a slight problem with determining which area number corresponds to infinity. To see this, take a simple () graph: two edges, two nodes, and two areas (inside and outside). Due to the random numbering of edges and vertices, outside may end up as either 1 or 2. That's unavoidable; in graph theory there's no distinction between inside and outside.
It's a standard function in the Boost Graph library. See this previous answer for details.