What is a Acyclic connected undirected graph? - data-structures

I was going through lecture of Minimum Spanning Tree, It says we are supposed to find connected acyclic subgraph graph in a Undirected graphs.
My question is that How can a connected undirected graph be a Acyclic, Since it is connected you can move to any vertex from any vertex.
Can anyone tell me what I am doing wrong?

It's really just a matter of definition. See http://en.wikipedia.org/wiki/Cycle_(graph_theory). What you seem to refer to as a cycle, is what is called a closed walk in the article: any path from a vertex to itself. As you have said yourself, using that definition, any connected undirected graph contains cycles. However, if you require that the subpath from the second to the last vertex be a simple path (hence simple cycle), i.e. one containing no repeating vertices, you end up with many connected undirected graphs which are in fact acyclic, such as trees for instance. Obviously, the path also has to contain at least 3 edges, else any (A,B,A) would be a cycle.
Consider the following graphs
A A
1) / \ 2) / \
B C B - C
only 2) contains simple cycles, so 1) is acyclic.

Related

Directed Graph walk - visit every node at least once

I’m familiar with the Hamilton path for a directed graph - visit every node exactly once.
I’m looking for an algorithm to walk the graph so that I visit every node at least once. I can’t find the standard name for this problem, if any.
This graph is walkable - root-a-d-b-c
This graph is not walkable - because in my walk, if I reach c, I have no directed edge to reach a & d and conversely, if I walk to a, d; there’s no directed edge that takes me to b & c
Hope that clarifies the question? Is there a standard name for this type of graph walk and an algorithm to solve it?
Hamiltonian path
Finding at most 2 leafs in the graph
I don't know if there's a name for a directed "walkable" graph, but it's not too hard to determine of a graph is walkable or not:
Find all the strongly connected components using Tarjan's algorithn, for example
Make a new directed graph of the connections between SCCs. This will be a DAG, and your original graph is walkable if and only if this DAG is walkable.
To determine whether or not a DAG is walkable, do a topological sort. Then check that each vertex has an edge to the next.
Each of these steps takes linear time, so you get O(|V|+|E|) complexity for the whole algorithm.
Theorem: a directed graph is walkable if and only if its strongly connected components are totally ordered by reachability.
Proof sketch: (walkable implies condition) The existence of a walk implies that, for each two strongly connected components, a vertex from one or the other appears first in the walk. That component can reach the other. (condition implies walkable) Since there is full connectivity inside a strongly connected component, each is walkable on its own. We just have to concatenate the walks according to the total order, adding the necessary transitions.
The proof is constructive, so we can extract an algorithm.
Algorithm
Compute the strongly connected components.
Concatenate the strongly connected components in topological order. Actually Tarjan's algorithm will list them in reverse topological order, so this doesn't need to be a separate step.
For each adjacent pair in the previous list, use breadth-first search to find a shortest path.
In general, this algorithm does not find the shortest walk (that's NP-hard by reduction from Hamiltonian path).

Cycles between two vertices in a directed graph

I know that in an undirected graph you have to have at least three vertices to form a cycle. My question is, in a directed graph, is it considered a cycle if two vertices have two edges pointing to each other?
Here is an example:
Is this a cyclic graph?
Related questions:
In an undirected graph, the simplest cycle must have 3 nodes?
Existence of cycle between any two vertices of graph
Cycles in an Undirected Graph
A graph has a cycle if there is a non-empty path that originates at some vertex and ends at the same vertex. In your graph above, you have a cycle on path A -> C -> A. Similarly, let's imagine a directed graph with 2 vertices A and B and 2 edges AB and BA (where the first letter is the source vertex). This means that there is a cycle A -> B -> A, thus you can have a cycle in a directed graph of 2 vertices.
I would say it (A-C-A) is a cycle. But I am from a different perspective: you may know that for a directed acyclic graph (dag), there is a topological sorting on it; otherwise, there isn't.
Topological sorting is indeed the linear extension of a partial order <=. Thus, dag is the graphical representation of a partial order <=. Be aware that according to the anti-symmetry property of a partial order <= (i.e., if a<=b and b<=a, then a=b), there is no possibility that two edges (a,b) and (b,a) simultaneously exist between two distinct vertices a and b.
In summary, no cycle => exists topological sorting, since no topological sorting on your digraph, thus there must be a cycle (A-C-A).
No,it is not considered a cycle if two vertices have two edges pointing to each other in directed graph. They are called Parallel Edges.
According to this definition 1:
A circuit is a closed trail with at least one edge
A-C is considered a circuit.
A-C also complies with this definition2:
A cycle is a circuit in which no vertex except the first (which is
also the last) appears more than once.
so it is also a cycle.
1 source: https://proofwiki.org/wiki/Definition:Circuit
2 source: https://proofwiki.org/wiki/Definition:Cycle_(Graph_Theory)

Determining whether or not a directed or undirected graph is a tree

I would like to know of a fast algorithm to determine if a directed or undirected graph is a tree.
This post seems to deal with it, but it is not very clear; according to this link, if the graph is acyclic, then it is a tree. But if you consider the directed and undirected graphs below: in my opinion, only graphs 1 and 4 are trees. I suppose 3 is neither cyclic, nor a tree.
What needs to be checked to see if a directed or undirected graph is a tree or not, in an efficient way? And taking it one step ahead: if a tree exists then is it a binary tree or not?
For a directed graph:
Find the vertex with no incoming edges (if there is more than one or no such vertex, fail).
Do a breadth-first or depth-first search from that vertex. If you encounter an already visited vertex, it's not a tree.
If you're done and there are unexplored vertices, it's not a tree - the graph is not connected.
Otherwise, it's a tree.
To check for a binary tree, additionally check if each vertex has at most 2 outgoing edges.
For an undirected graph:
Check for a cycle with a simple depth-first search (starting from any vertex) - "If an unexplored edge leads to a node visited before, then the graph contains a cycle." If there's a cycle, it's not a tree.
If the above process leaves some vertices unexplored, it's not a tree, because it's not connected.
Otherwise, it's a tree.
To check for a binary tree, if the graph has more than one vertex, additionally check that all vertices have 1-3 edges (1 to the parent and 2 to the children).
Checking for the root, i.e. whether one vertex contains 1-2 edges, is not necessary as there has to be vertices with 1-2 edges in an acyclic connected undirected graph.
Note that identifying the root is not generically possible (it may be possible in special cases) as, in many undirected graphs, more than one of the nodes can be made the root if we were to make it a binary tree.
If an undirected given graph is a tree:
the graph is connected
the number of edges equals the number of nodes - 1.
An undirected graph is a tree when the following two conditions are true:
The graph is a connected graph.
The graph does not have a cycle.
A directed graph is a tree when the following three conditions are true:
The graph is a connected graph.
The graph does not have a cycle.
Each node except root should have exactly one parent.

Minimize set of edges in a directed graph keeping connected components

Here is the full question:
Assume we have a directed graph G = (V,E), we want to find a graph G' = (V,E') that has the following properties:
G' has same connected components as G
G' has same component graph as G
E' is minimized. That is, E' is as small as possible.
Here is what I got:
First, run the strongly connected components algorithm. Now we have the strongly connected components. Now go to each strong connected component and within that SCC make a simple cycle; that is, a cycle where the only nodes that are repeated are the start/finish nodes. This will minimize the edges within each SCC.
Now, we need to minimize the edges between the SCCs. Alas, I can't think of a way of doing this.
My 2 questions are: (1) Does the algorithm prior to the part about minimizing edges between SCCs sound right? (2) How does one go about minimizing the edges between SCCs.
For (2), I know that this is equivalent to minimizing the number of edges in a DAG. (Think of the SCCs as the vertices). But this doesn't seem to help me.
The algorithm seems right, as long as you allow for closed walks (i.e. repeating vertices.) Proper cycles might not exist (e.g. in an "8" shaped component) and finding them is NP-hard.
It seems that it is sufficient to group the inter-component edges by ordered pairs of components they connect and leave only one edge in each group.
Regarding the step 2,minimize the edges between the SCCs, you could randomly select a vertex, and run DFS, only keeping the longest path for each pair of (root, end), while removing other paths. Store all the vertices searched in a list L.
Choose another vertex, if it exists in L, skip to the next vertex; if not, repeat the procedure above.

Extract chain components from mixed graphs

Given a mixed acyclic graph consists of directed and undirected edges, I want to decompose this graph into a directed graph of chain components (each node within a chain component will be connected to each other only with undirected edges) and their orderings.
I am confused whether I should first topologically sort all directed edges, and then hunt undirected edges as chain components, or first should I go over all undirected edges and give them group id's and then find some directed edges to connect those components.
Since the graph is acyclic, I think it's possible to order them from low-numbered components to high-numbered ones, but couldn't come up with a solid answer.
I think both of your methods would work fine.
To my mind the second method seems more natural.
If I was doing this in networkx I would implement your second method by:
Create a new graph H containing all vertices but only the undirected edges.
Call connected_components on H to extract the chain components and assign each component a different group id.
Create a new graph F with 1 node for each group id. Connect groups in F with directed edges based on the directed edges in the original graph.
Call topological_sort on F to compute the ordering of the group ids.
The equivalence relation that defines a chain component is the following by Drton 2009:
Define two vertices v_0 and v_k in a chain graph G to be equivalent if there exists a path (v_0,..., v_k) such that v_i − v_{i+1} in G for all 0 ≤ i ≤ k − 1.
The equivalence classes under this equivalence relation are the chain components of G. Rougly speaking this means all connected components of the graph made from undirected edges of the chain graph, plus all the nodes that are incident with only directed edges, plus all the nodes that have no neighbors at all, which amounts to Peter's answer
Here is the function that correctly decomposes the chain graph CH-Asia given in Cowell 2005,Probabilistic Networks and ..., p. 110 Fig. 6.1.
It is part of a graphical models library I have been developing as hobby project.
Though it uses custom data structures, it should not be too hard to adapt to other code bases involving graphical models.
def get_chain_components(self) -> Set[Set[Node]]:
"""!
"""
# filter out undirected edges
edges = set()
for e in self.edges():
if e.type() == EdgeType.UNDIRECTED:
edges.add(e)
# make a graph from undirected edges
undi = UndiGraph.from_graph(Graph.from_edge_node_set(edges, self.nodes()))
return undi.get_components_as_node_set()
A mixed graph such you describe is again a directed graph. Simply replace each undirected edge with two directed ones pointing in opposite directions.
Also you can't have an acyclic graph that has undirected edges. At least a cycle of length 2 will always exist, so I am not sure what do you mean by this.
It seems you are looking for the strongly connected components in this graph so I advice you to use Tarjan's algorith for finding them.

Resources