Venn Diagram in Dot - dot

I have been trying to implement a Venn Diagram in Dot. Whilst Venn Diagrams probably aren't that useful in Dot, it's mostly so I can use it as a very basic building block.
I have provided some ways that I have tried to do this:
graph G {
subgraph cluster0 {
color=white;
subgraph cluster0 {
label="1";
color=black;
a;
b;
}
subgraph cluster1 {
label="2";
color=black;
b;
c;
}
}
subgraph cluster1 {
color=white;
subgraph cluster2 {
label="1";
color=black;
d;
}
subgraph cluster3 {
label="1+2";
color=black;
e;
}
subgraph cluster4 {
label="2";
color=black;
f;
}
}
subgraph cluster2 {
color=white;
subgraph cluster5 {
label="1";
color=black;
g;
subgraph cluster6 {
label="2";
color=black;
h;
}
}
subgraph cluster6 {
label="2";
color=black;
i;
}
}
a -- d -- g [penwidth=0];
b -- e -- h [penwidth=0];
c -- f -- i [penwidth=0];
}
Producing:
These all have problems:
The first says b is in 1, but not 2. When it should be in both.
The second looks like it's separate from 1 and 2. And can be hard to show it's both.
The third is almost perfect IMO, it just requires the two 2 sub-graphs to join together.
To prevent an XY problem, I have:
two servers,
a docker swarm between the two servers, and
three applications. Located at:
One is on the first server, not in the docker swarm.
One is on the first server in the docker swarm.
One is on the second server in the docker swarm.
Leading to:
graph G {
subgraph cluster0 {
color=white;
subgraph cluster0 {
label="Server1";
color=black;
a;
subgraph cluster0 {
label="Docker";
b;
}
}
subgraph cluster1 {
label="Server2";
color=black;
subgraph cluster0 {
label="Docker";
c;
}
}
}
subgraph cluster1 {
color=white;
subgraph cluster0 {
label="Server1";
color=black;
d;
}
subgraph cluster1 {
label="Docker";
color=black;
subgraph cluster0 {
label="Server1";
e;
}
subgraph cluster1 {
label="Server2";
f;
}
}
}
a -- d [penwidth=0];
b -- e [penwidth=0];
c -- f [penwidth=0];
}

Related

mother vertex using disjoint dataset in directed graph

I had the solution of classical Mother vertex problem using DSU (disjoint data set). I have used path compression.
i wanted to know if it is correct or not.I think time complexity O(E log(V)).
the solution proceeds as
initialise each vertex's parent as it self
as soon as a edge comes, try to join them. note that 1->2 can't be merged if 2 already has some other parent! like if graph is 1->2 , 3->4 , 2->4
here edges 1->2 merge as par[1] = par[2]= 1 and 3->4 merge as par[3]= par[4] =3.
when it comes to merge 2->4, we can't since par[4]!=4, aka, it has some other incoming edge, out of this group.
atlast, all the parent vertices are checked, if they are all equal then, mother vertexos present.
code is :
class dsu
{
public:
int cap;
vector<int> par;
dsu(int n)
{
cap = n;
par.resize(cap);
for(int i=0; i<cap; i++)
par[i] = i;
}
int get(int a)
{
while(a!= par[a])
{
par[a] = par[par[a]];
a = par[a];
}
return a;
}
void join(int a, int b)
{
a= get(a);
int pb= get(b);
if(pb!=b)
return ;
par[pb] = a;
}
};
int findMother(int n, vector<int> g[])
{
// Your code here
// do disjoint data set, if everyone;s parent is same woohla! i have found the mother vertex
dsu arr(n);
for(int i=0; i< n; i++)
{
for(auto a: g[i])
{
arr.join(i,a);}
}
int mother = arr.get(0);
for(int i=1; i<n; i++)
{
if(mother != arr.get(i))
return -1;
}
return mother;
}
after some research I have fount out that, it is correct. It can be used to find the mother vertex .

DiagrammeR general flow direction

I would like to produce a diagram with DiagramR.
This is my code
require(DiagrammeR)
grViz("
digraph boxes_and_circles {
node [shape = box,
fontname = Helvetica]
A; B; C; D
B->A C->A D->B
}
")
But I get this result
And I need like this one
How can I set flow direction to up?
You could to set the parameter rankdir and add the color to edge and node:
library(DiagrammeR)
grViz("
digraph boxes_and_circles {
rankdir = BT
node [shape = box,
fontname = Helvetica,
color = gray
]
A; B; C; D
edge [color = gray]
B->A C->A D->B
}
")

graphviz dot ignores 'rank' constraints

I constructed a simple graph:
digraph{
rankdir = LR;
{
rank="source";
Sa;
Sb;
Sc;
St;
}
St -> {t_1[label="t",shape=plaintext];}
Na;
{t_a[label="t",shape=plaintext];}->Na
Sa->Na;
Sb->Na;
Sc->Na;
subgraph cluster_b {
fillcolor = "#ddDDdd";
style=filled;
label="";
Nb1;
Nb;
Nb1->Nb;
}
{t_2[label="t",shape=plaintext];}->Nb1
Sa->Nb;
Nc;
{t_c[label="t",shape=plaintext];}->Nc
Nd;
{t_d[label="t",shape=plaintext];}->Nd
Na->Nd;
Nb->Nc;
Nd->O1;
Nc->Nd;
{
rank="sink";
O1;
}
}
view online here
It seems that dot is ignoring the rank="source".
According to the documentation
If rank="min", all nodes are placed on the minimum rank. If
rank="source", all nodes are placed on the minimum rank, and the only
nodes on the minimum rank belong to some subgraph whose rank attribute
is "source" or "min".
The Sx nodes should be the only ones on the lowest ranks.
(as if there would be an additional St->t_2[style=invis]; edge).
Is this a bug? do i misunderstand the documentation?
I vote "bug" (probably in software, maybe in documentation).
Here is a work-around, using the minlen attribute to "force" the Nb node (and the cluster) "down" the ranks.
digraph{
rankdir = LR;
{
rank="source";
Sa;
Sb;
Sc;
St;
}
St -> {t_1[label="t",shape=plaintext];}
Na;
{t_a[label="t",shape=plaintext];}->Na
Sa->Na;
Sb->Na;
Sc->Na;
subgraph cluster_b {
fillcolor = "#ddDDdd";
style=filled;
label="";
Nb1;
Nb;
Nb1->Nb;
}
{t_2[label="t",shape=plaintext];}->Nb1
Sa->Nb [minlen=3] // will this move the cluster??
Nc;
{t_c[label="t",shape=plaintext];}->Nc
Nd;
{t_d[label="t",shape=plaintext];}->Nd
Na->Nd;
Nb->Nc;
Nd->O1;
Nc->Nd;
{
rank="sink";
O1;
}
}
Giving:

SPARQL counting triples in multiple graphs

I want to count triples in multiple graphs which are of a certain class and sum it up. I manage to count the triples of this class in each graph but I don't manage to calculate the total.
Initial query:
PREFIX locah: <http://data.archiveshub.ac.uk/def/>
PREFIX bs: <http://localhost:3030/alod/bs>
PREFIX ne: <http://localhost:3030/alod/ne>
SELECT (count(?sBS) as ?BScount) (count(?sNE) AS ?NEcount) WHERE {
{
GRAPH bs: {
?sBS a locah:ArchivalResource
}
} UNION {
GRAPH ne: {
?sNE a locah:ArchivalResource
}
}
}
My idea was to simply use the SUM() function as well so the SELECT would be like this:
SELECT (count(?sBS) as ?BScount) (count(?sNE) AS ?NEcount) (SUM(?NEcount ?BScount) AS ?total )WHERE {
But that doesn't seem to work.
And a related question: Why do I need the UNION? If I execute it without UNION it seems to come up with a very high triple count which doesn't make much sense and the count is twice the same.
You can try it on my SPARQL endpoint: http://data.alod.ch/sparql/
When you use an aggregate in the projection, you have to partition, or group, the solutions by distinct values of some of the variables. If you don't specify a group by clause, then the grouping is implicit. In this case, you have (at least) two options. One would be to use two subqueries, as in:
select ?acount ?bcount (?acount + ?bcount as ?totalCount) where {
{ select (count(*) as ?acount) where {
graph :a { ... } }
{ select (count(*) as ?bcount) where {
graph :b { ... } }
}
I think that's probably the simplest and most self-explanatory option. The other option, as you've noted, is to use a union:
select (count(?a) as ?acount)
(count(?b) as ?bcount)
(?acount + ?bcount as ?totalCount)
where {
{ graph :a { ?a ... } }
union
{ graph :b { ?b ... } }
}
The reason that something like
select (count(?a) as ?acount)
(count(?b) as ?bcount)
(?acount + ?bcount as ?totalCount)
where {
graph :a { ?a ... }
graph :b { ?b ... }
}
doesn't work is that you end up with the Cartesian product of ?a and ?b values. That is, suppose that there are two values for ?a and three values for ?b. Then you end up with six rows in the table:
a1, b1
a1, b2
a1, b3
a2, b1
a2, b2
a2, b3
Each of these rows is unique, so if you use the implicit group by, you'll have six a's and six b's, which isn't really what you want. You could still do this however, using distinct:
select (count(distinct ?a) as ?acount)
(count(distinct ?b) as ?bcount)
(?acount + ?bcount as ?totalCount)
where {
#-- ...
}
Types of Queries
Type 1: Subqueries
SELECT ?BScount ?NEcount (?BScount + ?NEcount as ?totalCount)
WHERE {
{ select (count(*) as ?BScount) WHERE {
GRAPH bs: { ?sBS a locah:ArchivalResource }
} }
{ select (count(*) as ?NEcount) WHERE {
GRAPH ne: { ?sNE a locah:ArchivalResource }
} }
}
Type 2: Union
SELECT (count(?sBS) as ?BScount)
(count(?sNE) AS ?NEcount)
(?BScount + ?NEcount as ?totalCount)
WHERE {
{ GRAPH bs: { ?sBS a locah:ArchivalResource } }
UNION
{ GRAPH ne: { ?sNE a locah:ArchivalResource } }
}
Type 3: Cartesian Product and Distinct
SELECT (count(distinct ?sBS) as ?BScount)
(count(distinct ?sNE) AS ?NEcount)
(?BScount + ?NEcount as ?totalCount)
WHERE {
{ GRAPH bs: { ?sBS a locah:ArchivalResource } }
{ GRAPH ne: { ?sNE a locah:ArchivalResource } }
}

number of k-ary tree from pre-order and post-order traversals

Suppose pre-order and post-order traversals and k are given. How many k-ary trees are there with these traversals?
An k-ary tree is a rooted tree for which each vertex has at most k children.
It depends on the particular traversal pair. For instance
pre-order: a b c
post-order: b c a
describes only one possible tree (the fewest possible, unless you include inconsistent traversal pairs). On the other hand:
pre-order: a b c
post-order: c b a
describes 2^(3-1) = 4 trees (the most possible amongst all scenarios where the traversals have 3 nodes and k can be anything), namely the 4 3-node lines.
If you want to know the number of possible binary trees having Pre-order and Post-order traversals, you should first draw one possible tree. then count the number of nodes with only one child. The total number of possible trees would be : 2^(Number of single-child nodes)
as an example:
pre: adbefgchij
post: dgfebijhca
i draw one tree that has 3 single-child nodes. So , the number of possible trees is 8.
First determine the corresponding range of sub-tree by DFS, and get the amount of sub-tree, then solve it through combination of the sub-trees.
const int maxn = 30;
int C[maxn][maxn];
char pre[maxn],post[maxn];
int n,m;
void prepare()
{
memset(C,0,sizeof(C));
for(int i=0;i<maxn;i++)
{
C[i][0] = 1;
}
for(int i=1;i<maxn;i++)
{
for(int j=1;j<=i;j++)
{
C[i][j] = C[i-1][j-1] + C[i-1][j];
}
}
return;
}
int dfs(int rs,int rt,int os,int ot)
{
if(rs == rt) return 1;
int son = 0,res = 1;
int l = rs + 1,r = os;
while(l <= rt)
{
while(r < ot)
{
if(pre[l] == post[r])
{
son++;
break;
}
r++;
}
res *= dfs(l , l + r - os , os , r);
l += r - os + 1;
rs = l - 1;
os = ++r;
}
return res * C[m][son];
}
int main()
{
prepare();
while(scanf("%d",&m) && m)
{
scanf("%s %s",pre,post);
n = strlen(pre);
printf("%d\n",dfs(0,n-1,0,n-1));
}
return 0;
}

Resources