Is it possible to allow constrain one node to be not higher than other?
Regular edge constraints a node to be lower, rank=same forces the same rank, and I want to allow to node to be on the same level or lower than other node, but not higher. How can I do that?
try rank=min for your first rank, rank=max for your last rank, and all other ranks as rank=same, and it might order the nodes for you.
Related
Problem: given N nodes, each of them has a limit for it's own degree, for example degree of the node (1) can not be higher that 10 (but can be less, of course), degree of the node (2) can not be higher that 3, etc. On these nodes build graph with maximum possible edges.
Would be happy to see any hints/recommendations.
EIDT: Graph should be simple :)
If there's no other constraint on which vertices can be connected, a greedy algorithm should work here: Connect whichever two unconnected vertices have the highest remaining degree, until no such pair exists. This can be done efficiently with an array of vertices dynamically sorted by remaining degree.
If the graph doesn't have to be simple (the question doesn't specify) then just add duplicate self loops to exhaust all but at most one available endpoint at each node. Then, pair off nodes. You will be left with at most one unused endpoint; the number of edges is trivially the sum of endpoint allowances, divided by two, rounded down.
I have a cyclic directed graph and I was wondering if there is any algorithm (preferably an optimum one) to make a list of common descendants between any two nodes? Something almost opposite of what Lowest Common Ancestor (LCA) does.
As user1990169 suggests, you can compute the set of vertices reachable from each of the starting vertices using DFS and then return the intersection.
If you're planning to do this repeatedly on the same graph, then it might be worthwhile first to compute and contract the strong components to supervertices representing a set of vertices. As a side effect, you can get a topological order on supervertices. This allows a data-parallel algorithm to compute reachability from multiple starting vertices at the same time. Initialize all vertex labels to {}. For each start vertex v, set the label to {v}. Now, sweep all vertices w in topological order, updating the label of w's out-neighbors x by setting it to the union of x's label and w's label. Use bitsets for a compact, efficient representation of the sets. The downside is that we cannot prune as with single reachability computations.
I would recommend using a DFS (depth first search).
For each input node
Create a collection to store reachable nodes
Perform a DFS to find reachable nodes
When a node is reached
If it's already stored stop searching that path // Prevent cycles
Else store it and continue
Find the intersection between all collections of nodes
Note: You could easily use BFS (breadth first search) instead with the same logic if you wanted.
When you implement this keep in mind there will be a few special cases you can look for to further optimize your search such as:
If an input node doesn't have any vertices then there are no common nodes
If one input node (A) reaches another input node (B), then A can reach everything B can. This means the algorithm wouldn't have to be ran on B.
etc.
Why not just reverse the direction of the edge and use LCA?
So I am working on a problem where you have one graph, where all edges has a certain weight to it. Now the algorithm is supposed to select certain node(s) in the graph and the selected nodes must be able to traverse/span through all other nodes within a certain total weight. The output should be the minimum number of selected nodes and the position of the selected nodes (it doesn't matter which position it outputs as long as it is the minimum number of selected nodes)
I have thought of a couple simple solutions but neither of them seem too good so far.
Brute force by trying out every node. The algorithm will start with one selected node and then try every combination of selected nodes, which then loops through every other non-selected nodes and check if they are all within range. If not it increases one extra selected node and repeats the same process.
The algorithm makes a list of subgraph that can be traversed with 1 selected node at every node position. Then attempt to puzzle fit the subgraphs so that it re-creates the original graph and if it succeeds that would be the solution.
As an example, here's a picture of a grid as the graph.
The weights of every edge in this grid is 1, and each selected node can travel through a total weights of 2.
I'm not too familiar with graph problems so if there is a similar question out there or if anyone can provide any help with the solution that would be great!
First, you can get rid of the edge weights by simply making an edge between two nodes if they are within the distance limit. Then you need to find a subset of the nodes such that each node is either selected or neighbor of a selected node. This is known as the Dominating Set problem. Unfortunately, it is NP-hard, so typically it is solved heuristically or using Integer Linear Programming. It might be possible to take advantage of certain properties of the input, but it is hard to tell without knowing more about what they look like.
I have a large (100,000+ nodes) Directed Acyclic Graph (DAG) and would like to run a "visitor" type function on each node in order, where order is defined by the arrows in the graph. i.e. all parents of a node are guaranteed to be visited before the node itself.
If two nodes do not refer to each other directly or indirectly, then I don't care which order they are visited in.
What's the most efficient algorithm to do this?
You would have to perform a topological sort on the nodes, and visit the nodes in the resulting order.
The complexity of such algorithm is O(|V|+|E|) which is quite good. You want to traverse all nodes, so if you would want a faster algorithm than that, you would have to solve it without even looking at all edges, which would be dangerous, because one single edge could havoc the order completely.
There are some answers here:
Good graph traversal algorithm
and here:
http://en.wikipedia.org/wiki/Topological_sorting
In general, after visiting a node, you should visit its related nodes, but only the nodes that are not already visited. In order to keep track of the visited nodes, you need to keep the IDs of the nodes in a set (or map), or you can mark the node as visited (somehow).
If you care about the topological order, you must first get hold of a collection of all the un-traversed links ("remaining links") to a node, sorted by the id of the referenced node (typically: map(node-ID -> link-count)). If you haven't got that, you might need to build it using an approach similar to the one above. Then, start by visiting a node whose remaining incoming link count is zero. For each link from that node, reduce the remaining link count for each related node, adding the related node to the set of nodes-to-visit (or just visiting the node) if the count reaches zero.
As mentioned in the other answers, this problem can be solved by Topological Sorting.
A very simple algorithm for that (not the most efficient):
Keep an array (or map) indegree[] where indegree[node]=number of incoming edges of node
while there is at least one node n with indegree[n]=0:
for each node n in nodes where indegree[n]>0:
visit(n)
indegree[n]=-1 # mark n as visited
for each node x adjacent to n:
indegree[x]=indegree[x]-1 # its parent has been visited, so one less edge coming into it
You can traverse a DAG in O(N) (without any topsort) by just running your dfs from every node with zero indegree, because those will be the valid "starting point". This will work because graph has no cycles, those zero indegree nodes must exist, and must traverse the whole graph.
Does anyone know where I can find an implementation of an algorithm to convert an activity node graph (aka activity-on-node graph) to an event node graph (aka activiy-on-arrow graph)?
If you don't know what I am talking about, take a look here: http://www.brpreiss.com/books/opus7/html/page581.html
Please provide a working algo in your answer.
Thanks in advance.
The easiest thing to do is replace every node v in your original graph with two nodes, v_in and v_out, connected by a single edge with weight equal to the original vertex weight. Then replace all the original edges (u, v) with edges from u_out to v_in of zero weight.
That link states how you do it:
The activity-node graph is a
vertex-weighted graph. However, the
algorithms presented in the preceding
sections all require edge-weighted
graphs. Therefore, we must convert the
vertex-weighted graph into its
edge-weighted dual. In the dual graph
the edges represent the activities,
and the vertices represent the
commencement and termination of
activities. For this reason, the dual
graph is called an event-node graph.
Although I suppose it leaves out some important details. The way they suggest to convert from an activity node to event node graph is to convert every activity node into an event node edge and to add a dummy edge for activities that take multiple inputs.
Another way to construct the event node graph is to replace every activity node with an edge and two nodes, e.g., A->B->C becomes A->A'->B->B'->C-C'. Then, remove every node that has only one input and zero or one output and replace them with an edge of zero cost, as those event nodes don't actually do anything.
foreach node in graph
if count of incoming_arrows != 1
{
Create new node
Assign incoming arrows from old node to new node
Create arrow from new node to old node
Assign cost 0 to new node
}
endif
end foreach
foreach arrow in graph
Assign cost of destination node to cost of arrow
/* if you want ...preceded by "node name:" to get F:5 */
end foreach
Rename the nodes
The data structures needed are something like
struct node
node_name string
node_cost int
struct arrow
arrow_form_node node
arrow_to_node node
arrow_cost int