Given an undirected graph in which each node has a Cartesian coordinate in space that has the general shape of a tree, is there an algorithm to convert the graph into a tree, and find the appropriate root node?
Note that our definition of a "tree" requires that branches do not diverge from parent nodes at acute angles.
See the example graphs below. How do we find the red node?
here is a suggestion on how to solve your problem.
prerequisites
notation:
g graph, g.v graph vertices
v,w,z: individual vertices
e: individual edge
n: number of vertices
any combination of an undirected tree g and a given node g.v uniquely determines a directed tree with root g.v (provable by induction)
idea
complement the edges of g by orientations in the directed tree implied by g and the yet-to-be-found root node by local computations at the nodes of g.
these orientations will represent child-parent-relationsships between nodes (v -> w: v child, w parent).
the completely marked tree will contain a sole node with outdegree 0, which is the desired root node. you might end up with 0 or more than one root node.
algorithm
assumes standard representation of the graph/tree structure (eg adjacency list)
all vertices in g.v are marked initially as not visited, not finished.
visit all vertices in arbitrary sequence. skip nodes marked as 'finished'.
let v be the currently visited vertex.
2.1 sweep through all edges linking v clockwise starting with a randomly chosen e_0 in the order of the edges' angle with e_0.
2.2. orient adjacent edges e_1=(v,w_1), e_2(v,w_2), that enclose an acute angle.
adjacent: wrt being ordered according to the angle they enclose with e_0.
[ note: the existence of such a pair is not guaranteed, see 2nd comment and last remark. if no angle is acute, proceed at 2. with next node. ]
2.2.1 the orientations of edges e_1, e_2 are known:
w_1 -> v -> w_2: impossible, as a grandparent-child-segment would enclose an acute angle
w_1 <- v <- w_2: impossible, same reason
w_1 <- v -> w_2: impossible, there are no nodes with outdegree >1 in a tree
w_1 -> v <- w_2:
only possible pair of orientations. e_1, e_2 might have been oriented before. if the previous orientation violates the current assignment, the problem instance has no solution.
2.2.2 this assignment implies a tree structure on the subgraphs induced by all vertices reachable from w_1 (w_2) on a path not comprising e_1 (e_2`). mark all vertices in both induced subtrees as finished
[ note: the subtree structure might violate the angle constraints. in this case the problem has no solution. ]
2.3 mark v visited. after completing steps 2.2 at vertex v, check the number nc of edges connecting that have not yet been assigned an orientation.
nc = 0: this is the root you've been searching for - but you must check whether the solution is compatible with your constraints.
nc = 1: let this edge be (v,z).
the orientation of this edge is v->z as you are in a tree. mark v as finished.
2.3.1 check z whether it is marked finished.
if it is not, check the number nc2 of unoriented edges connecting z.
nc2 = 1: repeat step 2.3 by taking z for v.
if you have not yet found a root node, your problem instance is ambiguous:
orient the remaining unoriented edges at will.
remarks
termination:
each node is visited at max 4 times:
once per step 2
at max twice per step 2.2.2
at max once per step 2.3
correctness:
all edges enclosing an acute angle are oriented per step 2.2.1
complexity (time):
visiting every node: O(n);
the clockwise sweep through all edges connecting a given vertex requires these edges to be sorted.
thus you need O( sum_i=1..m ( k_i * lg k_i ) ) at m <= n vertices under the constraint sum_i=1..m k_i = n.
in total this requires O ( n * lg n), as sum_i=1..m ( k_i * lg k_i ) <= n * lg n given sum_i=1..m k_i = n for any m <= n (provable by applying lagrange optimization).
[ note: if your trees have a degree bounded by a constant, you theoretically sort in constant time at each node affected; grand total in this case: O(n) ]
subtree marking:
each node in the graph is visited at max 2 times by this procedure if implemented as a dfs. thus a grand total of O(n) for the invocation of this subroutine.
in total: O(n * lg n)
complexity (space):
O(n) for sorting (with vertex-degree not constant-bound).
problem is probably ill-defined:
multiple solutions: e.g. steiner tree
no solution: e.g. graph shaped like a double-tipped arrow (<->)
A simple solution would be to define a 2d rectangle around the red node or the center of your node and compute each node with a moore curve. A moore curve is a space-filling curve, more over a special version of a hilbert curve where the start and end vertex is the same and the coordinate is in the middle of the 2d rectangle. In generell your problem looks like a discrete addressing space problem.
Related
Say that I have a big network with 10^4 nodes. And then I want to analyse the neighbourhood associated with a random node, say node 10. I can see which are the nodes connected to that node by looking at the 10th row entries of the adjacency matrix, and then I can repeat this if I want to look at the neighbours of those neighbours (second shell) and so on and so forth.
Is there an efficient way to do this - or even an inefficient but better than writing the whole thing from the scratch-? The actual network that I have is a Random Regular Graph and I am interested on the tree-like local structure for large networks.
If I understand your use case, there is a good way of doing this: the egonet function. You give it a graph, a starting vertex, and number of hops, and it will return an induced subgraph of the graph starting at the vertex and going out that number of hops. Here's the docstring:
egonet(g, v, d, distmx=weights(g))
Return the subgraph of g induced by the neighbors of v up to distance d, using weights (optionally) provided by distmx. This is equivalent to
induced_subgraph(g, neighborhood(g, v, d, dir=dir))[1].
Optional Arguments
––––––––––––––––––––
• dir=:out: if g is directed, this argument specifies the edge direction
with respect to v (i.e. :in or :out).
Edited to add: if all you need are the vertex indices, then neighborhood() is what you want:
neighborhood(g, v, d, distmx=weights(g))
Return a vector of each vertex in g at a geodesic distance less than or equal to d, where distances may be specified by distmx.
Optional Arguments
––––––––––––––––––––
• dir=:out: If g is directed, this argument specifies the edge direction
with respect to v of the edges to be considered. Possible values: :in or :out.
Okay, I know that a directed acyclic graph (DAG) has E=V-1 edges. E = number of edges. V = number of vertices.
So the question is, "In a directed graph G, the number of edges is always less than the number of vertices." True or false?
Thanks for the help.
Assume N vertices/nodes, and let's explore building up a DAG with maximum edges. Consider any given node, say N1. The maximum # of nodes it can point to, or edges, at this early stage is N-1. Let's choose a second node N2: it can point to all nodes except itself and N1 - that's N-2 additional edges. Continue for remaining nodes, each can point to one less edge than the node before. The last node can point to 0 other nodes.
Sum of all edges: (N-1) + (N-2) + .. + 1 + 0 == (N-1)(N)/2
Let's say we have a fully connected digraph G with N vertices and M edges.
How many edges does the graph have? Is it M = N^2?
If we take one vertex and start visiting its neighbors in a 'depth-first search' manner and avoiding loops, how many non-cyclic simple paths will we get?
For example, if we start from vertex 1 in a graph of 4 vertices, here are the paths:
- 1
- 1,2
- 1,3
- 1,4
- 1,2,3
- 1,2,4
- 1,3,2
- 1,3,4
- 1,4,2
- 1,4,3
Is it N! or more for a graph with N vertices? I could not find a way to generalize this and to derive a usable formula.
If your graph is full, there are n! simple paths for each vertex, so total of n*n! simple paths in the graph.
let a starting vertex be v_1.
There are |V| possibilities what to do next: move to one of each V\{v_1}, or stop.
next you have |V|-1 possibilities: move to one of each V\{v_1,v_2} [where v_2 is the node chosen as second] or stop.
... [do induction to formally prove it here]
after you have a path of n nodes, there is one only possibility: stop.
giving you total of n*(n-1)*...*1 = n! possible simple paths for each vertex, and n*n! total possible simple paths in the graph
A friend presented me with a conjecture that seems to be true but neither of us can come up with a proof. Here's the problem:
Given a connected, bipartite graph with disjoint non-empty vertex sets U and V, such that |U|<|V|, all vertices are in either U or V, and there are no edges connecting two vertices within the same set, then there exists at least one edge which connects vertices a∈U and b∈V such that degree(a)>degree(b)
It's trivial to prove that there is at least one vertex in U with degree higher than one in V, but to prove that a pair exists with an edge connecting them is stumping us.
For any edge e=(a,b) with a∈U and b∈V, let w(e)=1/deg(b)-1/deg(a). For any vertex x, the sum of 1/deg(x) over all edges incident with x equals 1, because there are deg(x) such edges. Hence, the sum of w(e) over all edges e equals |V|-|U|. Since |V|-|U|>0, w(e)>0 for som edge e=(a,b), which means that deg(a)>deg(b).
Prove it by contradiction, i.e. suppose that deg(a) ≤ deg(b) ∀(a,b)∈E, where E is the edgeset of the graph (with the convention that the first element is in U and the second in V).
For F⊆E, designate by V(F) the subset of V which is reachable through edgeset F, that is:
V(F) = { b | (a,b)∈F }
Now build an edgeset F as follows:
F = empty set
For a ∈ U:
add any edge (a,b)∈E to F
Keep adding arbitrary edges (a,b)∈E to F until |V(F)| = |U|
The set V(F) obtained is connected to all nodes in U, hence by our assumption we must have
∑a∈U deg(a) ≤ ∑b∈V(F) deg(b)
However, since |U|=|V(F)| and |U|<|V| we know that there must be at least one "unreached" node v∈V\V(F), and since the graph is connected, deg(v)>0, so we obtain
∑a∈U deg(a) < ∑b∈V deg(b)
which is impossible; this should be an equality for a bipartite graph.
here is the question. I am wondering if there is a clear and efficient proof:
Vertex Cover: input undirected G, integer k > 0. Is there a subset of
vertices S, |S|<=k, that covers all edges?
Dominating Set: input undirected G, integer k > 0. Is there a subset of
vertices S, |S|<= k, that dominates all vertices?
A vertex covers it's incident edges and dominates it's neighbors and itself.
Assuming that VC is NPC, prove that DS is NPC.
There is a quite nice and well known reduction:
Given an instance (G,k) of Vertex Cover build an instance of Dominating Set (H,k), where for H you take G, remove all isolated vertices, and for every edge (u,v) add an additional vertex x connected to u and v.
First realize that a Vertex Cover of G is a Dominating Set of H: it's a DS of G (after removing isolated vertices), and the new vertices are also dominated. So if G has a VC smaller k, then H has a DS smaller k.
For the converse, consider D, a Dominating Set of H.
Notice that if one of the new vertices is in D, we can replace it with one of it's two neighbors and still get an Dominating Set: it's only neighbors are are the two original vertices and they are also connected - everything x can possible dominate is also dominated by u or v.
So we can assume that D contains only vertices from G. Now for every edge (u,v) in G the new vertex x is dominated by D, so either u or v is in D. But this means D is a Vertex Cover of G.
And there we have it: G has a Vertex Cover smaller k if and only if H has a Dominating Set smaller k.
Taken from :
CMSC 651 Advanced Algorithms , Lecturer Samir Khuller
I think that second problem is not NP.
Let's try the following algorithm.
1. Get the original Graph
2. Run any algorithm which checks if a graph is connected or not.
3. mark all used edges of step 2
4. if the graph is connected then return the set of marked edges otherwise there is no such a set.
If I understood correctly your problem then it is not NP Complete.