I want to create a graphviz graph which contains two subgraphs containing nodes which are linked to other nodes in the other graph.
Some nodes need to be aligned horizontally to each other.
I've found out about the newrank=true command and I'm using it to achieve my described goal.
For some reason I've found that really weird behaviour:
If I create two nodes in one cluster and an arrow from one to the other and then another arrow pointing towards a third node in another cluster, graphviz will display two arrows.
digraph g{
newrank=true;
subgraph cluster_d{
A -> B
}
subgraph cluster_v{
C
}
{rank=same; A, B, C }
B -> C
}
I know, that I could simply use rankdir=LR and remove the rank=same, but in a larger graph with more nodes and subgraphs I seem to run into this problem sooner or later anyway.
I just created the artificial example above, to narrow the problem down.
Here is the code in use:
https://hackmd.io/s/B1NXAiTk7#
Why does Graphviz create two arrows between the subgraphs and how can I prevent this?
Related to: Why is graphviz drawing two arrows, and using a weird order?
But there was no satisfying answer and I think I narrowed the problem down.
How do I add an edge to a graphviz neato/fdp graph, that has no influence of the layout. I tried especially weight=0 and w=0 as stated in the documentation, and many other combination with the len attribute and different weights .
I'm aming for a map of nodes with "fixed" position/neighborhood and an overlay of additional relations.
This should be achievable by a two-step approach where you first run graphviz with the nodes and subset of edges you want it to use to compute positions and have it output the node positions (for example, use the -Tdot output). Then add the additional edges and rerun graphviz again.
You may need to pin the nodes, see this question: graphviz - fixed node positions
I know how to detect a cycle in a graph using the three colors (Black, White and Gray) mechanism. For those who do not know this, please follow this :
http://www.geeksforgeeks.org/detect-cycle-direct-graph-using-colors/
Briefly, White nodes are nodes which are undiscovered, Gray is for the nodes which are under processing and Black nodes are the ones which are discovered.
A couple of days back, one senior guy asked me why one needs exactly three colors for this purpose. Why can't we do it only with Black and White? Why are Gray nodes really needed? My bad that I could answer this question to him. Can anyone of you tell if he was asking me a valid question or just testing me?
No, he wasn't testing you. You can detect cycles in a graph using just two colors, but the graph must be undirected in that case.
Elaboration
What I want to emphasize is that graphs are of two kinds on the basis of the way edges are directed, when we have a graph when we have al the edges going forward as well as backward between two vertices, the type of graph is called undirected graph.
And the following picture is of a directed graph.
The way these two differ on paper is that we don't draw direction of edge in undirected graph, whenever we say there exists an edge between node A and B in context of an undirected graph, it automatically follows that the reverse edge also exists.Why we even talk of reverse edge, the reason being in computer programs the way edges are represented in different representations, we indicate directed edges only, for example in an adjacency list Node B will be in adjacency list of A only if there is an edge from A to B, and so in this representation, if we need to show that there exists an edge from B to A as well then we also need to add Node A in the adjacency list of B.
Similarly in case of adjacency matrix based representaion the matrix is symmetric about it's leading diagonal(the diagonal which starts from left top), to show that for every edge that exists from A to B , there also exists an edge from B to A.
So to realize any undirected graph we do following
So after you replace all the edges of an undirected graph by this, you see the actual picture of the graph in computer's representation.
Now assume that you have been given a graph. You must ask, which one ?
An undirected Graph
I will talk in reference to First Picture posted here. And assume that the adjacency list representation has been used to represent the graph.
How will that look like? Here you see:
A : B -> D -> E -> NULL
B : A -> D -> E -> NULL
C : D -> NULL
D : A -> B -> C -> NULL
E : A -> B -> NULL
The objective is to devise some strategy to check if a cycle exists or not.
Now suppose that these nodes represents some shops in a city and the edges are roads, so if you see a road from node A to B then automatically there exists a road from B to A, as the graph is undirected. The same is evident from the adjacency list as well.
To detect a cycle in undirected graph, we will follow the following procedure in a way, a typical program will follow. And then you will see how the statement I gave is valid. So let's start.
We start from Node A, in mood to traverse the whole graph, traversal here means you want to visit all the shops. Now to really keep track of which all shops you have visited you color them, as you leave them, so you are standing at node A and now you have got many roads emerging from node A, which you can take to go somewhere else. All these options are present in the adjacency list for A.
Let's say you choose a road to Node B, and you follow it , leaving A , and before leaving A you color it. Now standing at B you first see , is that node colored ? you see no !! and then you know that you have not visited this node before. Again want to do same thing, so you see for the adjacency list of B to choose next road, you see a road to A, you again follow that path and reach A, Color B as you leave. But as soon as you reach node A you see it's being colored, it means you have visited this shop before, but then you realize that because the graph is undirected therefore reaching at A from B is not an issue, as the edges are bidirectional, and so you backtrack.
To avoid this again you use a parent array, where par[i] = j, if you discovered i from j. Now you have eliminated the pitfall of visiting parent again. now you choose next road from B, which is to E, you go there, color B, and this time set par[E] = B, when you reach E, you want to do same thing again. But this time you see a road to A, first you check is A your parent ? because you don't want to visit your parent again as you came from there itself.
Which is NO here. so you go to A, but as soon as you reach A, you notice that the node is colored. And if this is true then it means you have already visited A, and that means there exists a path from A which ends at A again, hence a cycle.
So tell me how many colors we used? Only two, one is initial color and the other one after visiting the node.
You may say I have showed it on this specific example and so procedure may not work always, but try realizing the situation i described with the feel of traversal, and try convincing yourself that if you start from a node and following a set of roads if you reach somewhere and see that the node is colored, it means you have already visited that node, and because you are avoiding visiting the node's parent therefore the only way you can see a node colored is because of some cycle.
I am leaving it to you to realize that why this thing do not works in a directed graph, and where is the mechanics of bidirectional edge is coming here.
Here is all you the explanation you need
https://cs.stackexchange.com/questions/9676/the-purpose-of-grey-node-in-graph-depth-first-search
Basically, white nodes turn grey after you visit them for the first time but grey nodes become black only after all their neighbours turned black, or they don't have any unvisited neighbours.
In a directed graph, a cycle is present if and only if a node is seen again before all its descendants have been visited. In other words, if a node has a neighbor which is grey, then there is a cycle (and not when the neighbor is black). A grey node means we are currently exploring its descendants - and if one such descendant has an edge to this grey node, then there is a cycle. So, for cycle detection in directed graphs, you need to have 3 colors.
Now it should be pretty clear that two colors won't suffice.
For an undirected graph, 2 colours will suffice. But for the directed graph we'll need 3 colours. The reason, why we need 3 colours for the directed graph is clear from this example: when we have visited node D and all its neighbours then it becomes black. When we reach this node again from some previous node A using another path, we realise this node is already been visited, also since its colour is black it means at that node we have explored all the neighbours and there was no path to node A from D and we have backtracked. So we conclude there that there is no cycle between A and D.
Consider another case in directed graph, if we have used only two colours when we reach D from A second time using another path, we get node D as a grey colour which means it has been visited in the first round so we conclude that the cycle exists which is actually not the case.
That's the importance of 3rd colour.
#include<bits/stdc++.h>
using namespace std;
list<int>adj[10000];
int flag =0;
void dfs(int s , bool visited[] , char color[]){
visited[s] = true;
color[s] = 'g';
std::list<int>::iterator ii;
for(ii=adj[s].begin() ; ii!=adj[s].end(); ii++){
if(visited[*ii]==false){
visited[*ii]=true;
color[*ii]='g';
dfs(*ii , visited , color);
}
else if(visited[*ii]==true && color[*ii]=='g'){
flag=1;
}
}
color[s] = 'b';
}
int main(){
int n,m,x,y,i;
cin>>n>>m;
for(i=0; i<m; i++){
cin>>x>>y;
adj[x].push_back(y);
}
bool visited[n+1];
char color[n+1];
for(i=0; i<n; i++){
visited[i] = false;
color[i] = 'w';
}
dfs(0 , visited , color);
if(flag==1)
{
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
Two colors for directed graph are also enough. Assuming the convention for white grey and black to be what we have been reading, the only reason to have black color is an optimization. If we eliminate grey, we will end up revisiting a node that is still not processed fully and fail to detect a cycle, but if we do not maintain a black node list, it will only cause the algorithm to traverse nodes and the neighbors more than once or maybe even many times, but it will still work fine as long as white and grey nodes are used the same way
Is it possible to draw an edge from a Node to the center of an existing Edge in graphviz? I would like to duplicate this type of reaction diagram, common in chemical or biological networks.
Thanks!
--Peter
Yes, you can use invisible nodes, like in this example for instance.
Then play with creating subgraphs for A and B where
rank=same
and then an edge where
constraint=false
for the connection from C to the invisible node. This will put the first two above C.
I have a directed graph that concentrates overlapping edges on to one edge. A sample .dot file is given below:
strict digraph Test {
concentrate=true
A -> B;
A -> B;
A -> B;
}
I would like to display the number of overlapping edges as the edge label. This sounds pretty trivial, but I haven't been able to figure out how to do this. Is this possible? If possible how do I do it?
Thank you.
Only way is to do some post-processing yourself on the .gv file before feeding it to dot. You'd have to modify the output to explicitly include the text you want, such as:
strict digraph Test
{
concentrate=true
A -> B [label="3 connections between A and B"];
}