There is an un-directed cyclic graph with n nodes and there is a root node. Each node in the graph has a weight. Given a integer k, select k nodes from the graph with the two below conditions :
• Sum of weights on the selected nodes should be minimum
• All the selected nodes should have a path to root node
The weights are on the nodes.
First split the graph into its connected components. Thereafter only consider the component containing the root node. Select the top k vertices under a non-decreasing ordering by weight. Note that neither existence nor uniqueness of a solution is guaranteed.
Caveat
Something may be missing from the problem description, as the cyclicity of the graph does not figure in the solution.
Possibly the sum of weights of all vertices of the tree composed of the paths from the solution nodes to the root are to be minimized ? The question heading suggests this but the body says otherwise.
In case this surmise is true, the task to solve is the node-weighted Steiner Tree problem restricted to instances with k being the size of terminals.
Related
I have got a graph network and the edges of the graph are weighted. Is there a way to distribute the edge weights to nodes?
I'd like to know if there is a way to derive node weight or edge weight from each other.
I noticed a similar post here, which is the inverse of my problem. I am not sure if there is a similar approach that can be used for my problem.
EDIT:
For instance, for a graph like this (created from the commands given here) and each edge has a weight associated with it.
Example: Nodes i and j are linked by edge $e_{ij}$ that has weight $w_{ij}$
If the node weights are denoted by $nw_i$ (i = 1 to Number of nodes), the weight of any two nodes should sum up to the weight of the edge that links those nodes. i.e. $nw_i$ + $nw_j$ should be equal to $w_{ij}$,
$nw_j$ + $nw_k$ should be equal to $w_{jk}$ and so on.
My graph is as follows:
I need to find a maximum weight subgraph.
The problem is as follows:
There are n Vectex clusters, and in every Vextex cluster, there are some vertexes. For two vertexes in different Vertex cluster, there is a weighted edge, and in the same Vextex cluster, there is no edge among vertexes. Now I
want to find a maximum weight subgraph by finding only one vertex in each
Vertex cluster. And the total weight is computed by adding all weights of the edges between the selected vertex. I add a picture to explain the problem. Now I know how to model this problem by ILP method. However, I do not know how to solve it by an approximation algorithm and how to get its approximation ratio.
Could you give some solutions and suggestions?
Thank you very much. If any unclear points in this description,
please feel free to ask.
I do not think you can find an alpha-approx for this problem, for any alpha. That is because if such an approximation exists, then it would also prove that the unique games conjecture(UGC) is false. And disproving (or proving) the UGC is a rather big feat :-)
(and I'm actually among the UGC believers, so I'd say it's impossible :p)
The reduction is quite straightforward, since any UGC instance can be described as your problem, with weights of 0 or 1 on edges.
What I can see as polynomial approximation is a 1/k-approx (k the number of clusters), using a maximum weight perfect matching (PM) algorithm (we suppose the number of clusters is even, if it's odd just add a 'useless' one with 1 vertex, 0 weights everywhere).
First, you need to build a new graph. One vertex per cluster. The weight of the edge u, v has the weight max w(e) for e edge from cluster u to cluster v. Run a max weight PM on this graph.
You then can select one vertex per cluster, the one that corresponds to the edge selected in the PM.
The total weight of the solution extracted from the PM is at least as big as the weight of the PM (since it contains the edges of the PM + other edges).
And then you can conclude that this is a 1/k approx, because if there exists a solution to the problem that is more than k times bigger than the PM weight, then the PM was not maximal.
The explanation is quite short (lapidaire I'd say), tell me if there is one part you don't catch/disagree with.
Edit: Equivalence with UGC: unique label cover explained.
Think of a UGC instance. Then, every node in the UGC instance will be represented by a cluster, with as many nodes in the cluster as there are colors in the UGC instance. Then, create edge with weight 0 if they do not correspond to an edge in the UGC, or if it correspond to a 'bad color match'. If they correspond to a good color match, then give it the weight 1.
Then, if you find the optimal solution to an instance of your problem, it means it corresponds to an optimal solution to the corresponding UGC instance.
So, if UGC holds, it means it is NP-hard to approximate your problem.
Introduce a new graph G'=(V',E') as follows and then solve (or approximate) the maximum stable set problem on G'.
Corresponding to each edge a-b in E(G), introduce a vertex v_ab in V'(G') where its weight is equal to the weight of the edge a-b.
Connect all of vertices of V'(G') to each other except for the following ones.
The vertex v_ab is not connected to the vertex v_ac, where vertices b and c are in different clusters in G. In this manner, we can select both of these vertices in an stable set of G' (Hence, we can select both of the corresponding edges in G)
The vertex v_ab is not connected to the vertex v_cd, where vertices a, b, c and d are in different clusters in G. In this manner, we can select both of these vertices in an stable set of G' (Hence, we can select both of the corresponding edges in G)
Finally, I think you can find an alpha-approximation for this problem. In other words, in my opinion the Unique Games Conjecture is wrong due to the 1.999999-approximation algorithm which I proposed for the vertex cover problem.
I want to write an algorithm that finds an optimal vertex cover of a tree in linear time O(n), where n is the number of the vertices of the tree.
A vertex cover of a graph G=(V,E) is a subset W of V such that for every edge (a,b) in E, a is in W or b is in W.
In a vertex cover we need to have at least one vertex for each edge.
If we pick a non-leaf, it can cover more than one edge.
That's why I thought we can do it as follows:
We visit the root of the tree, then we visit one of its children, a child of the latter that we visited and so on.
Then if we have reached at a leaf, we check if we already have taken its father for the optimal vertex cover, and if not we pick it. Then, if the vertex that we picked for the optimal vertex cover has also other children, we pick the first of them and visit the leftmost children recursively and if we reach at the leaf and its father hasn't been chosen for the desired vertex cover, we choose it and so on.
I have written the following algorithm:
DFS(node x){
discovered[x]=1;
for each (v in Adj(x)){
if discovered[v]==0{
DFS(v);
if (v->taken==0){
x<-taken=1;
}
}
}
}
I thought that its time complexity is
(|V_i|, |E_i| are the number of vertices and edges respectively of the subtrees at the root of which we call DFS )
Is the time complexity I found right? Or have I calculated it wrong?
EDIT: Is the complexity of the algorithm described by the recurrence relation:
T(|V|)=E*T(|V|-1)+O(1)
? Or am I wrong?
Consider a graph that has weights on each of its nodes instead of between two nodes. Therefore the cost of traveling to a node would be the weight of that node.
1- How can we represent this graph?
2- Is there a minimum spanning path algorithm for this type of graph (or could we modify an existing algorithm)?
For example, consider a matrix. What path, when traveling from a certain number to another, would produce a minimum sum? (Keep in mind the graph must be directed)
if one don't want to adjust existing algorithms and use edge oriented approaches, one could transform node weights to edge weights. For every incoming edge of node v, one would save the weight of v to the edge. Thats the representation.
well, with the approach of 1. this is now easy to do with well known algorithms like MST.
You could also represent the graph as wished and hold the weight at the node. The algorithm simply didn't use Weight w = edge.weight(); it would use Weight w = edge.target().weight()
simply done. no big adjustments are necessary.
if you have to use adjacency matrix, you need a second array with node weights and in adjacency matrix are just 0 - for no edge or 1 - for an edge.
hope that helped
I have a graph with Edge E and Vertex V, I can find the spanning tree using Kruskal algorithm (or any other traverse-backtrack-traverse-again kind of algorithms), now I want to find all the cycle bases that are created by utilitizing that spanning tree and the edges that are not on the tree, any algorithm that allows me to do that, besides brute force search?
I can, of course, starts from one vertex of the non-spanning tree edge, gets all the edges, explore all of them, retracts if I find dead end, until I come back to the other vertex of the edge. But this is a bit, err... brutal. Any other ideas?
After constructing spanning tree, iterate on every edge(A,B) which is not in tree and find Lowest Common Ancestor(LCA) for nodes of this edge, your cycle would be path from
A -> LCA -> B -> A
you can use this link:
http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor
for efficient Lowest Common Ancestor algorithm implementation.
A simple algorithm we use for finding cycles in graphs:
Create a depth-first spanning tree
where each node has a parent.
In traversing the tree create a record of used nodes.
When an edge points to a previously used node, store it as a
cyclic edge.
When the spanning tree is complete, the count of the cyclic
edges gives the count of cycles.
For each cyclic edge recurse through the ancestors of the two nodes
until a common ancestor is found. That
will give exactly the cycles.
It may be useful to have an index (hashtable) of all the ancestors of a cyclic edge node so that is quick to find the common ancestor.
I doubt this is the best algorithm but it is fairly quick.
EDIT in repsonse to comment
Each node in the spanning tree has a parent. When a node in a cyclic edge is reached it calculates its list of ancestors (List<Node>This list could be indexed for speed (i.e. contains() is < O(n)). When a cyclic edge with two nodes (n1, n2) is found then iterate through the ancestors of n1, n1.ancestorList (rapidly since the list has already been created) and test whether the ancestor is in n2.ancestorList. If it (commonAncestor) is, then exactly those ancestors traversed correspond to cycles. Then iterate through n2 until you reach commonAncestor (rapid). The time should depend on the number of cyclic edges, combined with the lookup in lists (probably O(logN) but cheap). There is no need to re-explore the graph and there is no backtracking.