graphviz - fixed node positions - graphviz

I have a graph that is processed by neato and I'm adding new edges to it. However, I don't want that the old nodes to be moved. I want that neato computes the new positions of the new nodes and the old nodes stay in the same place.
strict graph {
node0 [pos="1,2"];
node1 [pos="2,3"];
}
and I add new edges:
strict graph {
node0 [pos="1,2"];
node1 [pos="2,3"];
node1 -- node2 [len="3"];
...
}
I want to get the same positions on the old nodes. For example:
strict graph {
node0 [pos="1,2"];
node1 [pos="2,3"];
node2 [pos="3,4"];
...
}
How can I do that?

You can pin a node's position by setting the node attribute pin=true.
Or put a '!' at the end of the pos attribute: pos="34,12!"

Running it with -n option should do the trick.

Related

Assign edge direction based on edge parameter

Is it possible to assign edge direction based on a edge attribute in R igraph?
Suppose I have a following edge table. I can either created a directed graph or an undirected graph using graph_from_data_frame(). But as seen here some are directed edges while others are undirected. Is it possible to create it?
Node1 Node2 Directional
Node2 Node3 Undirected
Node1 Node3 Directional
Node1 Node4 Undirected
Node4 Node2 Directional
One method could be to separate the directed and undirected edges, create a graph separately and then merge them. Any other efficient method?
When using igraph, I don't think you can enclose both directed and undirected edges on the same plot. However, we can use bidirectional edges as an alternative of undirected edges, and create a directed graph in turn.
Below is a possible option
g <- graph_from_data_frame(
rbind(
df,
transform(
subset(
df,
V3 == "Undirected"
),
V1 = V2,
V2 = V1
)
)
)
and plot(g) gives
data
> dput(df)
structure(list(V1 = c("Node1", "Node2", "Node1", "Node1", "Node4"
), V2 = c("Node2", "Node3", "Node3", "Node4", "Node2"), V3 = c("Directional",
"Undirected", "Directional", "Undirected", "Directional")), class = "data.frame", row.names = c(NA,
-5L))
> df
V1 V2 V3
1 Node1 Node2 Directional
2 Node2 Node3 Undirected
3 Node1 Node3 Directional
4 Node1 Node4 Undirected
5 Node4 Node2 Directional

Create a k-ary tree from a list of coordinates and list of edges connecting them.

I have a list of Nodes/Vertices, and a list of lines/edges connecting these nodes.The lists are not sorted or ordered in any way, but contain all the edges and nodes for a particular data set.
The edges are line segments defined by Cartesian coordinates, (x1,y1) and (x2,y2), and each node position is also represented by coordinates in the form (x,y).
The image attached depicts a typical test case, clearly showing two trees, with roots R1 and R2, each Node, including leaf nodes (labelled Lx, and highlighted orange text and blue circles) is shown with corresponding coordinates.
class Node
{
Point coordinates; // x,y coordinates of node <int,int>
Node parentNode; // parent node of current node. ( may not be necessary as parentID may suffice to keep reference to parent node)
List<Node> children; // List of all child nodes of this node
List<Edge> edges; // list of all edges connected to this node
string Data; // relevant data of each node
long nodeID; // current nodes ID
long parentID; // ID of current node's parent node
}
And each edge is represented as:
class Edge
{
Point p1; // first end coordinates of line segment
Point p2; // coordinates of the other end of the segment
}
From the image attached, it is clear that Edge N1-N2 will be represented as either p1= (0,0), p2=(20,20) or p1 =(20,20), p2 = (0,0). the order is random.
Assumption 1: Nodes R1 and R2 can be clearly recognized as root nodes, because of the type of node on them. (Concentric circles with Red outer circle).
Assumption 2: A list of all edges directly connected to a node are also available, e.g, node N8 will have segments :N8-L7,N8-R2,N8-N9, N8-N7.
My question is how do I write a function in C# that has two inputs,a List of edges and a List of nodes, and returns a root node, or root nodes of trees with reference to the child nodes, which would also be identical/true to the what is depicted in the drawing attached.
List<Node> getRootNodes(List<Node> nodes, List<Edge> edges)
{
// implementation here
List<Node> roots = new List<Node>();
//more logic
//
//
return roots; //returned list may have more than one root node!
}
I have been able to list each nodes edges, but can't figure out a way to construct the tree.
I have read about Kruskal's Algorithm, but I'm not sure if i can adapt it to this problem. I'm not sure if it will preserve the order shown in the diagram.
All code is in C#, but any C style language solution will do.
NB:The answers I have seen on this website assume that the ordering of the tree nodes in terms of parent nodes and children is already known. I can tell that two nodes are connected by an edge, but cannot determine which node is the parent and which is the child node.
Thank you,
Greg M
You said that there are two assumptions:
Nodes R1 and R2 can be clearly recognized as root nodes, because of the type of node on them. (Concentric circles with Red outer circle).
A list of all edges directly connected to a node are also available, e.g, node N8 will have segments N8-L7, N8-R2, N8-N9, N8-N7.
I'm going to assume that there are also segments L7-N8, R2-N8, N9-N8, N7-N8. If not, you can build them easily enough from the existing segments that you mentioned.
You also said, in response to my questions, that roots have no parents, and each node has only one parent. That makes this a lot easier.
First, create a dictionary that has node names as keys, and the value is the list of nodes to which it connects. This would be a Dictionary<string, List<string>>. In the example above, you'd have:
key value
N8 L7, R2, N9, N7
L7 N8
R2 N8
N9 N8
N7 N8
In the above list, only N8 is fully populated. Your dictionary would contain all the connections for all the nodes.
To build this:
var segmentDict = new Dictionary<string, List<string>>();
foreach (var segment in SegmentList)
{
List<string> nodeConnections;
if (!segmentDict.TryGetValue(segment.From, out nodeConnections))
{
// This node is not in dictionary. Create it.
nodeConnections = new List<string>();
segmentDict.Add(segment.From, nodeConnections);
}
nodeConnections.Add(segment.To);
}
Now, we'll build a new Dictionary<string, List<string>> that is initially empty. This will be the final tree, that has only the children for each node.
Because you know that root nodes have no parents, and that a node has no more than a single parent, you can start at the roots and start making connections. Scan the dictionary and for each root node, add it to a queue, and create an entry in the finalTree with an empty child list:
var finalTree = new Dictionary<string, List<string>>();
var nodeQueue = new Queue<string>();
foreach (var nodeName in segmentDict.Keys)
{
if (nodeName.StartsWith("R")) // if it's a root node
{
finalTree.Add(nodeName, new List<string>()); // add tree node
nodeQueue.Enqueue(nodeName); // and add node to queue
}
}
Now, start processing the queue. For each node name you pull from the queue:
Create an entry in the finalTree for that node.
Get the list of connections for that node from the segmentDict.
For each of the node connections, if there is no entry for that node in the finalTree, add the node to the queue, and add it to the list of connections for this node in finalTree.
Repeat that until the queue is empty.
The code looks something like this:
while (nodeQueue.Count > 0)
{
var fromNode = nodeQueue.Dequeue();
var nodeChildren = finalTree[fromNode];
foreach (var toNode in segmentDict[fromNode])
{
if (finalTree.ContainsKey(toNode))
{
// This node has already been seen as a child node.
// So this connection is from child to parent. Ignore it.
break;
}
nodeChildren.Add(toNode); // update children for this node
finalTree.Add(toNode, new List<string>()); // create tree entry for child node
nodeQueue.Enqueue(toNode); // add child to queue
}
}
What I've done here is followed the tree from the roots to the leaves, so the first time I encounter a node, I know that it's a parent-child link rather than a child-parent link. So all child-parent links get removed.
You can get your tree, then, by going through finalTree and doing a depth-first traversal on each root node:
foreach (var kvp in finalTree)
{
if (kvp.Key.StartsWith("R"))
{
PrintTree(kvp.Key, kvp.Value);
}
}
void PrintTree(string nodeName, List<string> children)
{
Console.WriteLine("node {1} has children {2}.", nodeName, string.Join(",", children);
foreach (var child in children)
{
PrintTree(child, finalTree[child]);
}
}
You'll want to pretty up the output, of course, but that shows how to traverse the trees from the roots.

Computing depth of each node in a "maximally packed" DAG

(Note: I thought about asking this on https://cstheory.stackexchange.com/, but decided my question is not theoretical enough -- it's about an algorithm. If there is a better Stack Exchange community for this post, I'm happy to listen!)
I'm using the terminology "starting node" to mean a node with no links into it, and "terminal node" to mean a node with no links out of it. So the following graph has starting nodes A and B and terminal nodes F and G:
I want to draw it with the following rules:
at least one starting node has a depth of 0.
links always point from top to bottom
nodes are packed vertically as closely as possible
Using those rules, depth of for each node is shown for the graph above. Can someone suggest an algorithm to compute the depth of each node that runs in less than O(n^2) time?
update:
I tweaked the graph to show that the DAG may contain starting and terminal nodes at different depths. (This was a case that I didn't consider in my original buggy answer.) I also switched terminology from "x coordinate" to "depth" in order to emphasize that this is about "graphing" and not "graphics".
Your x coordinate of a node corresponds to the longest way from any node without incomming edges to this node in question. For a DAG it can be calculated in O(N):
given DAG G:
calculate incomming_degree[v] for every v in G
initialize queue q={v with incomming_degree[v]==0}, x[v]=0 for every v in q
while(q not empty):
v=q.pop() #retreive and delete first element
for(w in neighbors of v):
incomming_degree[w]--
if(incomming_degree[w]==0): #no further way to w exists, evaluate
q.offer(w)
x[w]=x[v]+1
x stores the desired information.
Here's one solution which is essentially a two-pass depth-first tree walk. The first pass (traverseA) traces the DAG from the starting nodes (A and B in the O.P.'s example) until encountering terminal nodes (F and G in the example). It them marks them with the maximum depth as traced through the graph.
The second pass (traverseB) starts at the terminal nodes and traces back towards the starting nodes, marking each node along the way with the node's current value OR the previous node's value minus one, whichever is smaller if the node hasn't been visited yet:
function labelDAG() {
nodes.forEach(function(node) { node.depth = -1; }); // initialize
// find and mark terminal nodes
startingNodes().forEach(function(node) { traverseA(node, 0); });
// walk backwards from the terminal nodes
terminalNodes().forEach(function(node) { traverseB(node); });
dumpGraph();
};
function traverseA(node, depth) {
var targets = targetsOf(node);
if (targets.length === 0) {
// we're at a leaf (terminal) node -- set depth
node.depth = Math.max(node.depth, depth);
} else {
// traverse each subtree with depth = depth+1
targets.forEach(function(target) {
traverseA(target, depth+1);
});
};
};
// walk backwards from a terminal node, setting each source node's depth value
// along the way.
function traverseB(node) {
sourcesOf(node).forEach(function(source) {
if ((source.depth === -1) || (source.depth > node.x - 1)) {
// source has not yet been visited, or we found a longer path
// between terminal node and source node.
source.depth = node.depth - 1;
}
traverseB(source);
});
};

Modeling a completely connected graph in Alloy

I'm trying to get my feet wet with Alloy (also relatively new-ish to formal logic as well), and I'm trying to start with a completely connected graph of nodes.
sig Node {
adj : set Node
}
fact {
adj = ~adj -- symmetrical
no iden & adj -- no loops
all n : Node | Node in n.*adj -- connected
}
pred ex { }
run ex for exactly 3 Node
As you can see from the image, Nodes 0 and 1 aren't connected. I thought that my fact was enough to make it completely connected...but perhaps I missed something.
How about
adj = Node -> Node - iden
This basically says that adj contains all possible pairs of nodes, except identities (self-loops).
The reason why it is ok that Node1 and Node2 are not connected for your model is the last clause of your fact which constrains that for each node, all nodes are transitively reachable, but it seems to me that you want them to be immediately reachable. Alternatively to using my solution above, you can change
all n: Node | Node in n.*adj to all n: Node | (Node - n) in n.adj
to get the same effect.

Placing clusters on the same rank in Graphviz

I would like these two nodes to appear on the same level:
digraph G {
subgraph cluster1 {
label="Local Datacenter";
router1;
host1;
}
subgraph cluster2 {
label="Remote Datacenter";
router2;
host2;
}
router1 -> router2;
router2 -> host2;
router1 -> host1;
}
I have tried using rank=same and rank=min, but they aren't giving me what I need.
Interestingly, if I set rankdir=LR and comment out the two router-to-host edges, it gives me exactly the look I want - but I would like to leave the edges intact.
You may use the newrank graph attribute (added in GraphViz 2.30) to activate the new ranking algorithm which allows defining rank=same for nodes which belong to clusters.
Add the following line at the top:
newrank=true;
Add the following line after the cluster definitions:
{ rank=same; router1; router2; }
Here's the resulting graph:
You may simply modify the edge between the routers:
router1 -> router2[constraint=false];
constraint indicates whether the edge should be used in the ranking of the nodes.

Resources