Group Graphviz nodes as a table - graphviz

I've got the following Graphviz cluster with > 100 nodes rendered as a list, which looks pretty sloppy.
I want to make this cluster to look like a table with n columns and k rows.
Here is an example of how diagram should look like:
Does anybody have an idea how to achieve the desired result? Here's code I wrote trying to reproduce diagram above:
main = GraphViz.new(:G, rankdir: "TB")
rows = gets.to_i
columns = gets.to_i
1.upto(rows) do |row|
row_graph = GraphViz.new("#{row}_row", rankdir: "LR")
1.upto(columns) do |column|
node_num = column + columns * (row - 1)
row_graph.add_node("node_#{row}#{column}", label: "Node #{node_num}", shape: "box")
end
end
main.output(png: "table_graph.png")

Found a solution:
digraph {
node [shape=box width=1]
{rank=same Node1 Node2 Node3 Node4}
{rank=same Node5 Node6 Node7 Node8}
{rank=same Node9 Node10 Node11 Node12}
Node1 -> Node5 -> Node9 [style=invis]
}
corresponding ruby code can be generated by dot2ruby tool

Related

Code for finding redundant edges in a undirected tree partially working

I am solving the question 684. Redundant Connection from from Leetcode with partial success (I am failing one of the testcases). The question is asked as following:
In this problem, a tree is an undirected graph that is connected and
has no cycles.
You are given a graph that started as a tree with n nodes labeled from
1 to n, with one additional edge added. The added edge has two
different vertices chosen from 1 to n, and was not an edge that
already existed. The graph is represented as an array edges of length
n where edges[i] = [ai, bi] indicates that there is an edge between
nodes ai and bi in the graph.
Return an edge that can be removed so that the resulting graph is a
tree of n nodes. If there are multiple answers, return the answer that
occurs last in the input.
I solved this using BFS which gives a time complexity of O(n^2), however I read that using union-find will give a time complexity of O(n). My try with using union-find+path compression is only partially working, and I am stuck figuring out why.
For these following data, my code is working correctly (Meaning my code returns correct edge):
However, for this testcase below, my code don't succeed in finding the correct edge (My union-find runs through all the edges and return false, meaning there was no redundant edges):
Input data: [[7,8],[2,6],[2,8],[1,4],[9,10],[1,7],[3,9],[6,9],[3,5],[3,10]]
From logs i can see that my union-find constructs the graph as following (with no detected redundant edges):
Here is my code:
class Solution {
fun findRedundantConnection(edges: Array<IntArray>): IntArray {
val parents = IntArray(edges.size + 1) // 1 to N, we dont use 0
for(i in 1..parents.size - 1)
parents[i] = i //each node is its own parent, since this is a undirected graph
val rank = IntArray(edges.size + 1){ 1 } //all nodes have rank 1 since they are their own parent
val res = IntArray(2)
for(edge in edges){
val (node1, node2) = edge
if(union(node1,node2, parents, rank, res) == false)
return intArrayOf(node1, node2)
}
return res
}
private fun find(
node: Int,
parents: IntArray
): Int{
var parent = parents[node]
while(parents[node] != parent){
parents[parent] = parents[parents[parent]] //path compression
parent = parents[parent]
}
return parent
}
//modified union which return false on redundant connection
private fun union(
node1: Int,
node2: Int,
parents: IntArray,
rank: IntArray,
res: IntArray
): Boolean{
val parent1 = find(node1, parents)
val parent2 = find(node2, parents)
if(parent1 == parent2){ //redundant connection
res[0] = node1
res[1] = node2
return false
}
if(rank[parent1] > rank[parent2]){
parents[parent2] = parent1
rank[parent1] += rank[parent2]
}else{ // rank[parent1] <= rank[parent2]
parents[parent1] = parent2
rank[parent2] += rank[parent1]
}
return true
}
}
Any suggestions on what the problem might be? I have not been able to figure it out.
var parent = parents[node]
while(parents[node] != parent){
You're never going to get into the while loop.

How to generate parent child relation data from networkx to work with d3.js?

I want to generate the parent child relation data from python networkx. I am using a multidigraph. I want to use the below javascript to generate my graph in html format:
https://bl.ocks.org/mbostock/4339184.
The data needs to be in some format as like in the flare.csv file mentioned in the link above.
So, my question is how can I generate the data from networkx as like above parent.child relation data?
First, Let's create a graph (technically, a tree) based on your description:
G=nx.DiGraph()
nodes = ['n0', 'n1', 'n1_1', 'n1_2', 'n2', 'n2_1', 'n2_2', 'n2_1_1']
edges = [('n0', 'n1'), ('n0', 'n2'),
('n1', 'n1_1'), ('n1', 'n1_2'),
('n2', 'n2_1'), ('n2', 'n2_2'),
('n2_1', 'n2_1_1')]
G.add_edges_from(edges)
G.add_nodes_from(nodes)
You should first get the root of the graph, and then traverse from root to every single node.
Root is the only node with in_degree zero, so:
root = [k for k, v in G.in_degree().items() if v == 0]
# ['n0']
Next, calculate shortest path from root to every leaf. We need to have a list of node which excludes the root.
all_but_root = [i for i in nodes if i not in root]
res =[]
for i in all_but_root:
res.append(nx.shortest_path(G, root[0], i))
Additionally, if you want a painless way to get the output with correct format, you can use following code:
for i in res:
txt = ""
for j in i:
if j != i[-1]:
txt += j + "."
else:
txt += j + ","
print (txt)

Get Main Line From Graph

I am Facing a problem that requires some sort of an algorithm which allows me to get main line from a graph. A main line is basically a feeder network. On a graph it would be the main nodes that feeds sub nodes. Picture below explains.
so the main line in the diagram above would be 1, 2, 3, 4, 5. Each node contains a property which is the list of connected nodes; So number 3 would contain 2, 4, and 10. I started thinking that first I should get rid of the nodes that has one connected to them, but that will leave me with some unwanted nodes as well, hence if I were to remove 6, 7, 8 ,9, 11, 13, 12 I'd still have an unwanted node of 10.
For those of you that do not understand what a feeder network is, it is basically a bunch of structures, manholes, handholes, cabinets, that carry the signal from the root structure 1 distributing it to areas through 2, 3, 4, and 5, till it reaches the customers. 6, 7, 8, 11, 13, 12, 9. as for 10, it is a sub manhole structure that simply is not part of the main network because it distributes within the branch. now I know what those are, but in the code. those are all nothing but a bunch of objects that contain what they are connected to. no types no nothing.
Following from the partial answer that you'd given, I think adding another property will give you the solution.
So far, you have 1,2,3,4,5 and 10.
The problem is 10, as we know, should not be part of the feeder network (since it's a branch).
If you look back, you can see that, for all nodes except 10, there's one path from node to source and one path from node to destination (the last node that you have have selected through your process from the queue) without any edge being visited twice.
Ex:
1.) 3->2->1 (source) & 3->4->5 (destination)
2.) 4->3->2->1 (source) & 4->5 (destination)
But in case of 10, one edge is going to be visited twice.
As in,
10->3->2->1 & 10->3->4->5
Here, as you can see, the edge 10-3 is visited twice which does not happen in case of other nodes.
Through this process, any node, which is not part of the feeder network, will be discarded.
From the information provided, this will give the right solution.
I would suggest you recursively search from your starting node. Descend through your nodes keeping track of the number of nodes you have passed though.
keep 2 arrays (or linked lists) one for your current path and one for your longest path. Add nodes to your current array as you descend and remove them as you return. do the same for the longest path array but only add to it as you exceed your current longest path. when you have searched the entire graph remove the last node in your array (since that will not be part of the main path).
There is probably a more efficient way to do this, which I'll have to give some thought to.
This code return the mainline for you:
static void Main()
{
Node node1 = new Node(1, null);
Node node6 = new Node(6, node1);
Node node2 = new Node(2, node1);
Node node7 = new Node(7, node2);
Node node8 = new Node(8, node2);
Node node3 = new Node(3, node2);
Node node10 = new Node(10, node3);
Node node8_ = new Node(8, node10);
Node node11 = new Node(11, node10);
Node node4 = new Node(4, node3);
Node node5 = new Node(5, node4);
Node node12 = new Node(12, node5);
Node node13 = new Node(13, node5);
List<List<Node>> MainLines = new List<List<Node>>();
foreach (var i in Node.HighestRankNodes)
{
List<Node> m = new List<Node>();
m.Add(i);
Node j = i.Parent;
while (j != null)
{
m.Insert(0, j);
j = j.Parent;
}
MainLines.Add(m);
}
foreach (var i in MainLines) Console.WriteLine("Mainline: " + string.Join(", ", i));
Console.ReadLine();
}
Node class:
public class Node
{
public int Number;
public Node Parent = null;
public int Rank = 0;
public static int currentMaxRank = 0;
public static List<Node> HighestRankNodes = new List<Node>();
public Node(int number, Node parent)
{
Number = number;
Parent = parent;
Rank = Parent != null ? Parent.Rank + 1 : 0;
if (currentMaxRank < Rank)
{
currentMaxRank = Rank;
HighestRankNodes.Clear();
}
if (currentMaxRank == Rank) HighestRankNodes.Add(this);
}
public override string ToString()
{
return Number.ToString();
}
}
Output:
Mainline: 1, 2, 3, 4, 5, 12
Mainline: 1, 2, 3, 4, 5, 13

left rotation in bst with 4 fields

I have some problem with this and I tried a lot to solve it. I understand how rotation of bst work but I could not conform it to this structure.
Assume that the object Node of the binary search tree (BST) is described by 4 fields : key (integer), leftChild, rightChild and parent all are references to a Node of the BST.
Write the code of leftRotation (Node p).
this is my trying code:
Node temp
temp = parent.right// could I do like this ??
parent.rightChild = temp.leftChild
temp.leftChild= parent
i feel it is totally wrong because I just wanna work with only those four fields.
I just want a pseudo code.
thank you for help!
regards
Assuming you don't know is p left child or right child of it's parent
q = p.right
if p.parent <> nil then
if p.parent.right = p then
p.parent.right = q
else
p.parent.left = q
q.parent = p.parent
q.left.parent = p
p.right = q.left
q.left = p
p.parent = q

Obtain forest out of tree with even number of nodes

I'm stuck on a code challenge, and I want a hint.
PROBLEM: You are given a tree data structure (without cycles) and are asked to remove as many "edges" (connections) as possible, creating smaller trees with even numbers of nodes. This problem is always solvable as there are an even number of nodes and connections.
Your task is to count the removed edges.
Input:
The first line of input contains two integers N and M. N is the number of vertices and M is the number of edges. 2 <= N <= 100.
Next M lines contains two integers ui and vi which specifies an edge of the tree. (1-based index)
Output:
Print the number of edges removed.
Sample Input
10 9
2 1
3 1
4 3
5 2
6 1
7 2
8 6
9 8
10 8
Sample Output :
2
Explanation : On removing the edges (1, 3) and (1, 6), we can get the desired result.
I used BFS to travel through the nodes.
First, maintain an array separately to store the total number of child nodes + 1.
So, you can initially assign all the leaf nodes with value 1 in this array.
Now start from the last node and count the number of children for each node. This will work in bottom to top manner and the array that stores the number of child nodes will help in runtime to optimize the code.
Once you get the array after getting the number of children nodes for all the nodes, just counting the nodes with even number of nodes gives the answer. Note: I did not include root node in counting in final step.
This is my solution. I didn't use bfs tree, just allocated another array for holding eachnode's and their children nodes total number.
import java.util.Scanner;
import java.util.Arrays;
public class Solution {
public static void main(String[] args) {
int tree[];
int count[];
Scanner scan = new Scanner(System.in);
int N = scan.nextInt(); //points
int M = scan.nextInt();
tree = new int[N];
count = new int[N];
Arrays.fill(count, 1);
for(int i=0;i<M;i++)
{
int u1 = scan.nextInt();
int v1 = scan.nextInt();
tree[u1-1] = v1;
count[v1-1] += count[u1-1];
int root = tree[v1-1];
while(root!=0)
{
count[root-1] += count[u1-1];
root = tree[root-1];
}
}
System.out.println("");
int counter = -1;
for(int i=0;i<count.length;i++)
{
if(count[i]%2==0)
{
counter++;
}
}
System.out.println(counter);
}
}
If you observe the input, you can see that it is quite easy to count the number of nodes under each node. Consider (a b) as the edge input, in every case, a is the child and b is the immediate parent. The input always has edges represented bottom-up.
So its essentially the number of nodes which have an even count(Excluding the root node). I submitted the below code on Hackerrank and all the tests passed. I guess all the cases in the input satisfy the rule.
def find_edges(count):
root = max(count)
count_even = 0
for cnt in count:
if cnt % 2 == 0:
count_even += 1
if root % 2 == 0:
count_even -= 1
return count_even
def count_nodes(edge_list, n, m):
count = [1 for i in range(0, n)]
for i in range(m-1,-1,-1):
count[edge_list[i][1]-1] += count[edge_list[i][0]-1]
return find_edges(count)
I know that this has already been answered here lots and lots of time. I still want to know reviews on my solution here. I tried to construct the child count as the edges were coming through the input and it passed all the test cases.
namespace Hackerrank
{
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var tempArray = Console.ReadLine().Split(' ').Select(x => Convert.ToInt32(x)).ToList();
int verticeNumber = tempArray[0];
int edgeNumber = tempArray[1];
Dictionary<int, int> childCount = new Dictionary<int, int>();
Dictionary<int, int> parentDict = new Dictionary<int, int>();
for (int count = 0; count < edgeNumber; count++)
{
var nodes = Console.ReadLine().Split(' ').Select(x => Convert.ToInt32(x)).ToList();
var node1 = nodes[0];
var node2 = nodes[1];
if (childCount.ContainsKey(node2))
childCount[node2]++;
else childCount.Add(node2, 1);
var parent = node2;
while (parentDict.ContainsKey(parent))
{
var par = parentDict[parent];
childCount[par]++;
parent = par;
}
parentDict[node1] = node2;
}
Console.WriteLine(childCount.Count(x => x.Value % 2 == 1) - 1);
}
}
}
My first inclination is to work up from the leaf nodes because you cannot cut their edges as that would leave single-vertex subtrees.
Here's the approach that I used to successfully pass all the test cases.
Mark vertex 1 as the root
Starting at the current root vertex, consider each child. If the sum total of the child and all of its children are even, then you can cut that edge
Descend to the next vertex (child of root vertex) and let that be the new root vertex. Repeat step 2 until you have traversed all of the nodes (depth first search).
Here's the general outline of an alternative approach:
Find all of the articulation points in the graph.
Check each articulation point to see if edges can be removed there.
Remove legal edges and look for more articulation points.
Solution - Traverse all the edges, and count the number of even edges
If we remove an edge from the tree and it results in two tree with even number of vertices, let's call that edge - even edge
If we remove an edge from the tree and it results in two trees with odd
number of vertices, let's call that edge - odd edge
Here is my solution in Ruby
num_vertices, num_edges = gets.chomp.split(' ').map { |e| e.to_i }
graph = Graph.new
(1..num_vertices).to_a.each do |vertex|
graph.add_node_by_val(vertex)
end
num_edges.times do |edge|
first, second = gets.chomp.split(' ').map { |e| e.to_i }
graph.add_edge_by_val(first, second, 0, false)
end
even_edges = 0
graph.edges.each do |edge|
dup = graph.deep_dup
first_tree = nil
second_tree = nil
subject_edge = nil
dup.edges.each do |e|
if e.first.value == edge.first.value && e.second.value == edge.second.value
subject_edge = e
first_tree = e.first
second_tree = e.second
end
end
dup.remove_edge(subject_edge)
if first_tree.size.even? && second_tree.size.even?
even_edges += 1
end
end
puts even_edges
Note - Click Here to check out the code for Graph, Node and Edge classes

Resources