How to print a description string near a node? - binary-tree

I have recently started to use the DOT language to describe the structure of a binary tree. The following example allows to draw a binary tree having numbers as labels inside each node.
graph tree {
0 [shape=ellipse]
1 [shape=ellipse]
2 [shape=ellipse]
3 [shape=ellipse]
4 [shape=ellipse]
0 -- 1
0 -- 2
2 -- 3
2 -- 4
}
Now, I would like to print some additional information near each node, but not inside the ellipse containing the label of the node. In other words, how can I print a description string near a node? How should I modify the above code in order to achieve this?

this script, with the added lines,
graph tree {
0 [shape=ellipse]
1 [shape=ellipse]
2 [shape=ellipse]
3 [shape=ellipse]
4 [shape=ellipse]
0 -- 1
0 -- 2
2 -- 3
2 -- 4
node [shape=none]
edge [style="invis"]
rank="same"
subgraph { 0 -- "desc of 0" }
subgraph { 1 -- "desc of 1" }
subgraph { 2 -- "desc of 2" }
subgraph { 3 -- "desc of 3" }
subgraph { 4 -- "desc of 4" }
}
generates a plausible image for your description

Related

Graphviz: Flat horizontal graph with arching edges?

I have this code
graph G {
node [shape=circle]
rankdir=LR;
1 -- 10;
2 -- 9;
3 -- 8;
4 -- 7;
5 -- 6;
}
but I want to have the vertices 1 ... 10 in a flat, horizontal row, then with the connecting edges as arcs (alternating above, below) connecting 1 to 10, 2 to 9, etc. My code only produces a stack of vertices and their edges.
You need to tell graphviz first that you want to have the nodes in a row. Only then you can introduce a second set of edges the way you like. There is very limited control as to how graphviz places the edges; Trial and error brought me to the solution below which is the best I could find.
See comments in the code:
graph so
{
node [shape=circle]
rankdir=LR;
// We put all nodes in one row
// We need the weight to keep them straight
// Edge style is invisible, so that they are not in the way of your edges
1 -- 2 -- 3 -- 4 -- 5 -- 6 -- 7 -- 8 -- 9 -- 10[ weight = 10, style = invis ];
1:ne -- 10:nw; // added ports to force node above
2 -- 9; // the rest is graphviz' decision
3 -- 8;
4 -- 7;
5 -- 6;
}
gives you
Try this. Invisible edges are to enforce order within rank. Double 5 -- 6 edge is to enforce arc, otherwise the edge would be straight. I tried it on viz-js.com. The alternation of above and below arcs heavily depends on order of edges. Since it's very sensitive, undocumented and probably prone to minor version change, I don't recommend it as production solution, the DOT engine is IMHO not suitable for such tasks. For one-shot documentation purposes it's sufficient and fulfills your specification.
graph G {
splines=splines;
node [shape=circle];
edge [constraint=false];
rankdir=LR;
1 -- 10;
3 -- 8;
2 -- 9;
1 -- 2 [style=invis, constraint=true];
2 -- 3 [style=invis, constraint=true];
3 -- 4 [style=invis, constraint=true];
4 -- 5 [style=invis, constraint=true];
5 -- 6 [style=invis];
4 -- 7;
5 -- 6 [constraint=true];
6 -- 7 [style=invis, constraint=true];
7 -- 8 [style=invis, constraint=true];
8 -- 9 [style=invis, constraint=true];
9 -- 10 [style=invis, constraint=true];
}

backtracking for graph with adj list

Consider a graph with adjacency list as given below and with 4 vertices and 4 edges.
1 2 3 4
1 0 1 0 1
2 1 0 1 0
3 0 1 0 1
4 1 0 1 0
It is a simple rectangular graph.
In m-colorability graph problem we have to colour the graph with no adjacent nodes of the same color.I am reading a book which says that if the degree of the graph is 'd' then graph can be colored in d+1 ways.But the above graph can be colored in 2 ways which is the degree of the graph.How?
If graph is fully connected then the graph is colorable with d+1 color. In this case it is not fully connected so colors can be less than d+1 which is 3 here and as seen it is 2 in this case.
Note: fully connected means all vertices are connected to each other directly by edge.

Construct a graph from given node degrees

I have to find which of the following values can be the degrees of an undirected graph with 6 vertices:
a) 3 2 2 2 3 3
b) 4 2 2 2 3 2
c) 5 2 2 2 0 3
d) 5 2 2 2 1 2
I only method I found is to try to draw the graph on a sheet of paper and then check if it is possible.
I just need a hint to start this problem, if possible, in other way than drawing each graph.
The following algorithm decides if a simple graph can be constructed with given node degrees:
sort the degrees in descending order
if the first degree is 0 (i.e.all degrees are 0) then obviously such a graph can be formed (no edges) and you are done.
if the first degree has value d (> 0) then the following d degrees must be greater 0. If not you are done: no such graph can be formed.
take away the first degree (value d) and reduce the following d degrees by one (i.e. draw the requested number of edges from the node with highest degree to the nodes with highest degrees among the remaining ones - see proof below for correctness of this assumption), then continue with step 1 (with now one node less)
example a) (can be rejected because of the odd sum of weights, but also the above algorithms works)
3 2 2 2 3 3
3 3 3 2 2 2
2 2 1 2 2
2 2 2 2 1
1 1 2 1
2 1 1 1
0 0 1
1 0 0
-1 not possible
example c)
5 2 2 2 0 3
5 3 2 2 2 0
2 1 1 1 -1 not possible
example d)
5 2 2 2 1 2
5 2 2 2 2 1
1 1 1 1 0
0 1 1 0
1 1 0 0
0 0 0 ok
What is missing is a proof that if a graph can be drawn with given node degrees, then one of the matching graphs has this property of step 4, i.e. that the node with highest degree is connected with the nodes with next highest degrees.
Let us therefore assume that A is the node with highest degree and that it is connected with a node B whose degree is less then the degree of node C not being connected to A. Since degree(C) > degree(B), there is node D connected to C and not connected to B. Thus, there are edges AB and CD, and there are no edges AC nor BD. So we can replace AB and CD by the edges AC and BD without changing the nodes' degrees.
By repeating this procedure enough times we can make all nodes with the next highest degrees being connected to node with the highest degree.
The handshaking lemma or degree sum formula is necessary and sufficient condition in this case, since we only care that it forms an undirected graph (orientation of the edge doesn't matter, but nothing is said about loop or parallel edges). Therefore, option c and option d are valid 6-vertex undirected graph.
If the question asks for simple undirected graph (loop and parallel edges disallowed), then we need to bring in the algorithm by Havel/Hakimi, which is as described by #coproc.

GraphViz enforce columns

I have the following dot:
digraph G
{
rank="same";
subgraph sys
{
1 [shape=record, label="| | Système"];
}
subgraph obj
{
2 [shape=box, label="Sites"];
3 [shape=box, label="Sociétés de\nmaintenance"];
1 -> 2 [arrowhead=none] [label="a"];
1 -> 3 [arrowhead=none] [label="b"];
}
subgraph constraints
{
4 [style=dotted, label="Surveiller"];
5 [style=dotted, label="Effectuer des\ninterventions"];
4 -> 2 [style=dotted];
4 -> 3 [style=dotted];
5 -> 2 [style=dotted];
5 -> 3 [style=dotted];
}
}
Which gives me this image:
But I want to have a subgraph by column (1 on the first column, 2-3 on the second and 4-5 on the last).
Is there a way to do that?
For your help,
Thanks by advance.
digraph G
{
rank=same
rankdir=LR
subgraph sys
{
1 [shape=record, label="| | Système"]
}
subgraph obj
{
node [shape=box]
2 [label="Sites"]
3 [label="Sociétés de\nmaintenance"]
}
subgraph constraints
{
node [style=dotted]
4 [label="Surveiller"]
5 [label="Effectuer des\ninterventions"]
}
edge [style=invis, weight=2]
2->4
3->5
edge [style=dotted]
4 -> 2
4 -> 3
5 -> 2
5 -> 3
edge [style="" arrowhead=none]
1 -> 2 [label="a"]
1 -> 3 [label="b"]
}
This solution is the same as suggested by #alexandr_anturis (+1), but I have removed some irrelevant 'syntax noise', because I feel that such a complex and powerful specification as dot language benefits of any simplification available.
Use rankdir and hidden edges with appropriate weight.
Picture of the result:
digraph G
{
rank="same";
layout="dot";
rankdir=LR;
subgraph sys
{
style=filled;
1 [rank=1, shape=record, label="| | Système"];
}
subgraph obj
{
2 [rank=2,shape=box, label="Sites"];
3 [rank=3,shape=box, label="Sociétés de\nmaintenance"];
}
subgraph constraints
{
4 [rank=4,style=dotted, label="Surveiller"];
5 [rank=5,style=dotted, label="Effectuer des\ninterventions"];
}
2->3->4->5 [color=white, weight=100];
rankdir=LR;
4 ->2 [style=dotted, w=0];
4 -> 3 [style=dotted, w=0];
5 -> 2 [style=dotted, w=0];
5 -> 3 [style=dotted, w=0];
1 -> 2 [arrowhead=none] [label="a"];
1 -> 3 [arrowhead=none] [label="b"];
}
You can use something like this. The way to make what you want is to use rankdir and add invisible edges for correct ranking.

Using GraphViz to Diagram an Extensive-Form Game

I'm attempting to diagram an extensive form game in GraphViz. Compiling the code results in a graph that is correct in all ways except one. I want the "War" label to be placed to the left of the edge it labels, such that the edge is closest to "r" and not "W".
This is my "game" or graph so far:
digraph hierarchy_of_D {
graph [rankdir ="UD"]
node [color=black,shape=circle]
//splines="polyline"
I [label="R"]
subgraph infoset1
{
label="whatever"
rank="same"
1 [label="C"]
2 [label="C"]
}
I -> 1 [label="War"] //fix how this floats right of the line
I -> 2 [label="Peace"]
1 -> 2 [style=dashed, dir=none]
subgraph info21
{
rank="same"
3 [label="(2,2)", rank=sink, shape="plaintext"]
4 [label="(5,1)", rank=sink, shape="plaintext"]
5 [label="(1,5)", rank=sink, shape="plaintext"]
6 [label="(4,4)", rank=sink, shape="plaintext"]
}
1 -> 3 [label="War"]
1 -> 4 [label="Peace"]
2 -> 5 [label="War"]
2 -> 6 [label="Peace"]
}
Any ideas? I've already tried the following, which does not do what I want:
1 -> 3 [label="War/l"]
See also this question and that question, neither of which have an answer. C'mon now, this is worth triple points!
Triple points? Well then, the correct answer is that you cannot choose the placement of edge labels.
However, you may play with headlabel, labeldirection and labelangle:
digraph hierarchy_of_D {
node [color=black,shape=circle]
I [label="R"]
subgraph infoset1
{
label="whatever"
rank="same"
1 [label="C"]
2 [label="C"]
}
I -> 1 [headlabel="War", labeldistance=3, labelangle=40]
I -> 2 [headlabel="Peace", labeldistance=3, labelangle=-40]
1 -> 2 [style=dashed, dir=none]
subgraph info21
{
rank="same"
3 [label="(2,2)", rank=sink, shape="plaintext"]
4 [label="(5,1)", rank=sink, shape="plaintext"]
5 [label="(1,5)", rank=sink, shape="plaintext"]
6 [label="(4,4)", rank=sink, shape="plaintext"]
}
1 -> 3 [headlabel="War", labeldistance=3, labelangle=40]
1 -> 4 [headlabel="Peace", labeldistance=3, labelangle=-40]
2 -> 5 [headlabel="War", labeldistance=3, labelangle=40]
2 -> 6 [headlabel="Peace", labeldistance=3, labelangle=-40]
}
Output:
Just for fun, an other workaround I just found:
By forcing straight edges between nodes using splines=false and defining edges twice, the edges are drawn as if they were one single edge, but the labels of each edge get to are drawn (most of the time) on different sides of the edge.
Therefore by having one edge without a label, and the other one with a label, it is possible to influence the placement of the edge(s) label(s).
Your example:
digraph hierarchy_of_D {
splines=false;
node [color=black,shape=circle]
I [label="R"]
subgraph infoset1
{
rank="same"
1 [label="C"]
2 [label="C"]
}
I -> 1 [label="War "]
I -> 1 [label=" "]
I -> 2 [label=""]
I -> 2 [label="Peace"]
1 -> 2 [style=dashed, dir=none]
subgraph info21
{
rank="same"
3 [label="(2,2)", rank=sink, shape="plaintext"]
4 [label="(5,1)", rank=sink, shape="plaintext"]
5 [label="(1,5)", rank=sink, shape="plaintext"]
6 [label="(4,4)", rank=sink, shape="plaintext"]
}
1 -> 3 [label="War"]
1 -> 3 [label=""]
1 -> 4 [label=""]
1 -> 4 [label="Peace"]
2 -> 5 [label=""]
2 -> 5 [label="War "]
2 -> 6 [label=""]
2 -> 6 [label="Peace"]}
And the output:
It's not perfect, and your mileage may vary depending on the graph, but I thought it was worth mentioning it.

Resources