Overlapping edges in graphviz - graphviz

I've two overlapping edges and don't know why:
digraph G {
graph [rankdir=LR, overlap=false];
subgraph cluster1 {
d1;
n1;
}
subgraph cluster2 {
n2;
d2;
}
n1 -> n2;
n2 -> n1;
d0 -> d1;
d0 -> d2;
}
Is there any way to display both edges n1 -> n2 and n2 -> n1 separately? Removing the clusters is not an option but would help ...

A solution making use of the portPos modifier:
digraph G {
graph [rankdir=LR, overlap=false];
subgraph cluster1 {
d1;
n1;
}
subgraph cluster2 {
n2;
d2;
}
n1:sw -> n2:nw;
n2:ne -> n1:se;
d0 -> d1;
d0 -> d2;
}
Another solution is to make use of the dir and color modifiers:
digraph G {
graph [rankdir=LR, overlap=false];
subgraph cluster1 {
d1;
n1;
}
subgraph cluster2 {
n2;
d2;
}
n2 -> n1[dir=both color="red:blue"];
d0 -> d1;
d0 -> d2;
}
You can even use color="black:black" if you want to maintain the black and white coloring scheme.

Trial-and-error solution (don't ask me why this works...):
digraph G {
graph [rankdir=LR, overlap=false];
subgraph cluster1 {
d1;
n1;
}
subgraph cluster2 {
n2;
d2;
}
n1 -> n2;
n1 -> n2[constraint=false, dir=back];
n2 -> n1[style=invis];
d0 -> d1;
d0 -> d2;
}

Related

Find all cycles of directed graph in boost

Can someone tell me how to find all cycles of a directed graph using the boost graph library?
Google turns up the - otherwise undocumented - tiernan_all_cycles. There is an example though.
The example presupposes less-than-optimal graph models. According to issue #182 you should really be able to satisfy the missing concept requirement for adjacency-list (provided that it has a correct vertex index):
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::/*un*/directedS>;
// see https://github.com/boostorg/graph/issues/182
namespace boost { void renumber_vertex_indices(Graph const&) {} }
Here's a modernized example:
Live On Compiler Explorer
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/tiernan_all_cycles.hpp>
#include <iostream>
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::/*un*/directedS>;
// see https://github.com/boostorg/graph/issues/182
namespace boost { void renumber_vertex_indices(Graph const&) {} }
struct Vis {
void cycle(auto const& path, Graph const& g) const {
auto indices = get(boost::vertex_index, g);
for (auto v : path)
std::cout << "ABCDEFGHIJKL"[get(indices, v)] << " ";
std::cout << "\n";
};
};
int main()
{
enum { A, B, C, D, E, F, G, H, I, J, K, L, NUM };
Graph g(NUM);
// Graph from https://commons.wikimedia.org/wiki/File:Graph_with_Chordless_and_Chorded_Cycles.svg
for (auto [s, t] : { std::pair //
{A, B}, {B, C}, {C, D}, {D, E}, {E, F}, {F, A},
{G, H}, {H, I}, {I, J}, {J, K}, {K, L}, {L, G},
{C, L}, {D, K}, {B, G}, {C, G}, {I, K}
}) //
add_edge(s, t, g);
tiernan_all_cycles(g, Vis{});
}
Prints
A B C D E F
G H I J K L
G H I K L

Accelerate matrix speed in neon arm

I tried to run the below code for 1k x 1k the time taken is 1.4s.
Is there any possible way to increase the speed and the code is tested on raspberry pi-4.
The numpy based multiply for same size taking 0.14s to execute the code.
The A and B matrix are of same size 1000 x 1000.
The code is auto-vectorized while compiling.
void matrix_multiply_neon(float32_t *A, float32_t *B, float32_t *C, uint32_t n, uint32_t m, uint32_t k) {
int A_idx;
int B_idx;
int C_idx;
float32x4_t A0;
float32x4_t A1;
float32x4_t A2;
float32x4_t A3;
float32x4_t B0;
float32x4_t B1;
float32x4_t B2;
float32x4_t B3;
float32x4_t C0;
float32x4_t C1;
float32x4_t C2;
float32x4_t C3;
for (int i_idx=0; i_idx<n; i_idx+=4) {
for (int j_idx=0; j_idx<m; j_idx+=4) {
// Zero accumulators before matrix op
C0 = vmovq_n_f32(0);
C1 = vmovq_n_f32(0);
C2 = vmovq_n_f32(0);
C3 = vmovq_n_f32(0);
for (int k_idx=0; k_idx<k; k_idx+=4) {
A_idx = i_idx + n*k_idx;
B_idx = k*j_idx + k_idx;
A0 = vld1q_f32(A+A_idx);
A1 = vld1q_f32(A+A_idx+n);
A2 = vld1q_f32(A+A_idx+2*n);
A3 = vld1q_f32(A+A_idx+3*n);
B0 = vld1q_f32(B+B_idx);
C0 = vfmaq_laneq_f32(C0, A0, B0, 0);
C0 = vfmaq_laneq_f32(C0, A1, B0, 1);
C0 = vfmaq_laneq_f32(C0, A2, B0, 2);
C0 = vfmaq_laneq_f32(C0, A3, B0, 3);
B1 = vld1q_f32(B+B_idx+k);
C1 = vfmaq_laneq_f32(C1, A0, B1, 0);
C1 = vfmaq_laneq_f32(C1, A1, B1, 1);
C1 = vfmaq_laneq_f32(C1, A2, B1, 2);
C1 = vfmaq_laneq_f32(C1, A3, B1, 3);
B2 = vld1q_f32(B+B_idx+2*k);
C2 = vfmaq_laneq_f32(C2, A0, B2, 0);
C2 = vfmaq_laneq_f32(C2, A1, B2, 1);
C2 = vfmaq_laneq_f32(C2, A2, B2, 2);
C2 = vfmaq_laneq_f32(C2, A3, B2, 3);
B3 = vld1q_f32(B+B_idx+3*k);
C3 = vfmaq_laneq_f32(C3, A0, B3, 0);
C3 = vfmaq_laneq_f32(C3, A1, B3, 1);
C3 = vfmaq_laneq_f32(C3, A2, B3, 2);
C3 = vfmaq_laneq_f32(C3, A3, B3, 3);
}
// Compute base index for stores
C_idx = n*j_idx + i_idx;
vst1q_f32(C+C_idx, C0);
vst1q_f32(C+C_idx+n, C1);
vst1q_f32(C+C_idx+2*n, C2);
vst1q_f32(C+C_idx+3*n, C3);
}
}
}

Swap positions of two nodes in a GraphViz diagram (DOT)

I use the DOT language to create a diagram in R. As I get a strange result, I am interested how to swap positions of two nodes: node 8 and node c4?
The code:
digraph DAG {
# Initialization of node attributes
node [shape = box, color = blue]; 2; 3; 4;
# Revision to node attributes
{ node [shape = box,style = filled,fillcolor = yellow]; 8}
# Revision to node attributes
{ node [shape = diamond, color = "red"]; c1; c2; c3; c4}
{ rank=same; c1; c2; c3}
{ rank=same; 8; c4}
# Initialization of edge attributes
edge [color = green, rel = yields]
# Edge statements
2->c1 [headport = w];
c1->c2->c3
c2->c1 [tailport = n, headport = n];
8->c3 [tailport = n, headport = s];
c3->3 [tailport = e, headport = n];
c3->c2 [tailport = n, headport = n];
3->c4 [tailport = s, headport = n];
c4->4 [tailport = s, headport = n];
c4->8 [tailport = w, headport = e];
}
The (incorrect) result is:
for "wrong way" edges you may
swap nodes and use attribute dir = back to invert its 'force'
use attribute constraint = none to disable its 'force'
in your case you substitute
8->c4 [tailport = e, headport = w, dir = back];
by either
c4->8 [tailport = w, headport = e, constraint = none];
or by
8->c4 [tailport = e, headport = w, dir = back];

Graphviz: arranging nodes

Is it possible to tell GraphViz (Dot) to try arranging nodes of the graph without stretching either of the dimensions?
For example, if I create a graph with 25 nodes and no edges, GraphViz visualizes it with all nodes in a single row. What I want is to get a 5 x 5 "field" of nodes.
rank=same in conjunction with invisible edges are your friend:
digraph Test
{
nodesep = 0.5; // even node distribution
node [ shape = circle, width = 0.7 ];
edge [ style = invis ];
{ rank = same; A; B; C; D; E }
{ rank = same; F; G; H; I; J }
{ rank = same; K; L; M; N; O }
{ rank = same; P; Q; R; S; T }
{ rank = same; U; V; W; X; Y }
C -> { F G H I J }
H -> { K L M N O }
M -> { P Q R S T }
R -> { U V W X Y }
}
Instead of the last four lines, you could simply use
A -> F -> K -> P -> U;
This would lead to the same result with the given nodes but may be less stable when node sizes are varying.
You can force the position of nodes in Graphviz although it won't work with the dot engine.
That means you will have to come up with an algorithm to specify the position of your node.
Look at this question: How to force node position (x and y) in graphviz
Alternatively you can use invisible edges:
nodeA -> nodeB [style=invis]
And create a mesh between your nodes, that would likely cause the engine to arrange the nodes in a orderly fashion.
In both cases you will have to specify how you want to arrange the nodes by either specifying their position or connecting them together.

Meeting Conflict algorithms

I had a interview today and was asked to check whether two meeting conflicts with each other or not. Each meeting has start time and end time.
I tried to answer the question but not that specific..can somebody throw some idea?
bool IsConflict(Datetime s1, Datetime e1, Datetime s2, Datetime e2)
should return true if Conflict is there and false if no conflict.
E.g
True if:
(s1, e1)= 8,10
(s2, e2) = 9, 11
(s1, e1)= 7,10
(s2, e2) = 8, 9
(s1, e1)= 8,11
(s2, e2) = 9, 11
and so on
This is basic interval algebra, see my answer here for more details, but the code would look like this:
bool IsConflict(Datetime s1, Datetime e1, Datetime s2, Datetime e2)
{
return (s1 < e2) && (e1 > s2);
}
I am assuming that two meetings where one start where the other ends are not in conflict.
In the simple case of two intervals I think this will work (untested pseudocode ahead):
bool IsConflict(Datatime s1, Datatime e1, Datatime s2, Datatime e2) {
if( s1 < s2 ) {
// meeting 1 starts first
if( e1 > s2 ) return true; // overlap
}
else {
// meeting 2 starts first
if( e2 > s1 ) return true; // overlap
}
return false;
}
The meetings overlap if and only if max(s1, s2) < min(e1, e2). This intersection based approach assumes that intervals (s, e) are open, and implies (rightly or wrongly) that an empty meeting s = e cannot have an overlap with another meeting.
Complexity of following algorithm is O (nlogn)
public boolean isConflicts(float startTime[], float endTime[])
{
TreeMap<Float, Integer> map = new TreeMap<Float, Integer>();
for (int i = 0; i < startTime.length; i++)
{
map.put(startTime[i], -1);
map.put(endTime[i], 1);
}
Iterator<Integer>iter = map.values().iterator();
while (iter.hasNext())
{
if ((iter.next() + iter.next()) != 0)
{
System.out.println ("Conflicts...");
return true;
}
}
return false;
}
The plan
There are three cases to check for with this problem.
Case 1: Does s1 lie within the interval [s2,e2]
(s1 >= s2) && (s1 <= e2)
Case 2: Does e1 lie within the interval [s2, e2]
(e1 >= s2) && (e2 <= e2))
Case 3: Does the point (s2, e2) lie within [s1, e1]
(s1 <= s2) && (e1 >= e2)
So here is the answer. I apologize; It's not the most readable lines of code.
The code (pseudo):
bool isConflict(Datetime s1, Datetime e1, Datetime s2, Datetime e2){
return ((s1 >= s2) && (s1 <= e2)) || ((e1 >= s2) && (e2 <= e2)) || (s1 <= s2) && (e1 >= e2));
}

Resources