Newbie graphviz edge direction issue - graph

I have an undirected graph with the following schema:
graph G {
A -- B;
B -- C;
C -- D;
D -- A;
}
The graph is top to bottom as you see yourself. But I wanted to be in the form of a rectangle where A is top-left and D is bottom-right and I don't really have a clue how to do it.

graph G {
A [
label = A
pos = "0,0!"
]
B [
label = B
pos = "5,0!"
]
C [
label = C
pos = "5,5!"
]
D [
label = D
pos = "0,5!"
]
A -- B;
B -- C;
C -- D;
D -- A;
}
and use neato to generate the image file. (it did not work with dot for me)

I have got another solution without neato I guess that renders with dot properly.
graph G{
{rank=same A B}
{rank=same C D}
A -- B;
B -- C;
D -- A;
D -- C;
}

Related

How can I define which node goes next to another one in grViz

I am trying to plot a regular graph with grViz in R like the below:
using the following code:
grViz("
graph {
# a graph statement
graph [layout = circo]
# a node statement
node [shape = circle,
style = filled,
color = grey,
fillcolor = orange];
nodesep=4
A; B; C; D; E; F; G; H;
# an edge statement
edge [color = grey]
A -- B
B -- C
C -- D
D -- E
E -- F
F -- G
G -- H
H -- A
A -- D
H -- E
B -- G
C -- F
}")
However, I cannot place the nodes in sequential order despite trying the different options for rankdir:

graphviz/dot graph: Order nodes within a cluster/a subgraph

Help sort nodes within subgraphs or clusters such as subgraph A and B below.
graph {
splines=line;
subgraph cluster_0 {
label="Subgraph A";
a; b; c
}
subgraph cluster_1 {
label="Subgraph B";
d; e;
}
a -- e;
a -- d;
b -- d;
b -- e;
c -- d;
c -- e;
}
This graph is not desirable. Help us sort "a", "b", "c" and "d", and "e" from left-to-right, please.
https://graphs.grevian.org/resources/static/images/example6a.png
I found this difficult to do, and don't guarantee that it works with a more complex graph. In addition to getting the nodes in the desired sequence, it is quite difficult to position clusters where you want. That said, this:
graph {
splines=line;
rankdir=LR
subgraph cluster_0 {
label="Subgraph A";
rank=same
a -- b -- c [style=invis]
}
subgraph cluster_1 {
label="Subgraph B";
rank=same
d -- e [style=invis]
}
edge[constraint=false]
a -- e;
a -- d;
b -- d;
b -- e;
c -- d;
c -- e;
}
produces this:

How to put a node in the center of the dot-generated graph

With the following dot code
digraph DG {
G -> V;
G -> E;
G -> P;
G -> C;
}
I generate the following graph
How could I move the node G in the centre? That is I wish to get something like this:
p.s. My experiments with setting the rank of the edge didn't work out.
For the general case, the easiest thing to do is to use twopi or neato instead of dot as your layout engine.
Twopi:
Neato:
If you're truly confined to dot, this will give you close to what you want, though you'll have to customize each graph.
digraph g
{
P -> G [dir=back];
subgraph clusterGVE {
{rank=same V; G; E;}
G -> V [constraint=false];
G -> E;
color=invis;
};
G -> C;
}

how to print variables in gmlp

I have a linear programming model, for the problem of minimum path. This is the model:
/* Min path problem
file: minPath.mod */
set V;
set E within V cross V;
param cost{E};
param S symbolic;
param T symbolic;
var flow{E} integer, >= 0;
minimize min_path: sum{(a,b) in E} cost[a,b] * flow[a,b];
s.t. conservazione{v in V: v != S and v != T}:
sum{(a,b) in E: a == v} flow[a,b] ==
sum{(a,b) in E: b == v} flow[a,b];
s.t. sorgente: sum{(a,b) in E: a == S} flow[a,b] == 1;
s.t. destinazione: sum{(a,b) in E: b == T} flow[a,b] == 1;
display {(a,b) in E} flow[a,b];
data;
set V := A B C D E;
set E := (A,B) (A,C) (B,D) (B,E) (C,D) (D,E);
param S := A;
param T := D;
param cost := [A,B] 2 [A,C] 1 [B,D] 3 [B,E] 1 [C,D] 1 [D,E] 1;
end;
The objective value is 3 for my example, and the minimum path is:
A -> C -> D -> E
For this reason, the vector flow has to be 1 on the edges, that i written here above. By the way, when i display the vector flow with the statement:
display {(a,b) in E} flow[a,b];
the vector is 0 in all the position.
flow[A,B].val = 0
flow[A,C].val = 0
flow[B,D].val = 0
flow[B,E].val = 0
flow[C,D].val = 0
flow[D,E].val = 0
I tried to change the syntax, but i couldn't force glpsol to print the real value.
Am I missing something?
you have to put the statement:
solve;
before the display statement!

Is angle in between two angles

I have 3 angles a b c
a=315
b=20
c=45
ok so would like to know giving all three if b is in between a and c
i have the long way of doing this adding and subtracting that's seems to work. I would just like to get something smaller and maybe more efficient.
thanks
EDIT
Here is a picture what i am trying to say.
Ok I have angle L(currently 0) i add 45(or any angle) and subtract 45(or any angle) to get a and b (my view angle).
Now i need to know if the green dot is between a and b
(g> a || g > 0) && (g < b)
so in this picture only the top green dot will be true..
Sorry if I am not making my self clear my first language is not English
I had a similar problem. I got it. All the calculations are in degrees.
I needed to calculate id a gps location is inside a rectangle.
Or, I needed to see if an angle x is between angle check+r and angle check-r.
check-r<x<check+r.
If you need a<x<b, find the angle check in the middle of a and b and then the distance (r) of check from a or b.
The method normalize, changes the angles from -infinity...infinity to -180...180.
The method check, takes the arguments
x: the angle that we need to see if it is between the angles check-r and check+r.
check: the angle to check with.
r: the radius around angle check.
private static double normalize(double x) {
x = x % 360;
if (x>=180) {
return x-360;
}
if (x<-180) {
return x+360;
}
return x;
}
public static boolean check(double x, double check, double r) {
x = x - check;
x = normalize(x);
return x<r && x>-r;
}
1st off, every angle is between 2 other angles, what you're really asking is:
For given angles: a, b, and g, is g outside the reflex angle between a and b?
You can just go ahead and define a as the leftmost angle and b as the rightmost angle or you can solve for that, for example if either of these statements are true a is your leftmost angle:
a ≤ b ∧ b - a ≤ π
a > b ∧ a - b ≥ π
For simplicity let's say that your leftmost angle is l and your rightmost angle is r and you're trying to find if g is between them.
The problem here is the seem. There are essentially 3 positive cases that we're looking for:
l ≤ g ≤ r
l ≤ g ∧ r < l
g ≤ r ∧ r < l
If you're just defining a to be leftmost and b to be rightmost you're done here and your condition will look like:
a <= g && g <= b ||
a <= g && b < a ||
g <= b && b < a
If however you calculated the l and r you'll notice there is an optimization opportunity here in doing both processes at once. Your function will look like:
if(a <= b) {
if(b - a <= PI) {
return a <= g && g <= b;
} else {
return b <= g || g <= a;
}
} else {
if(a - b <= PI) {
return b <= g && g <= a;
} else {
return a <= g || g <= b;
}
}
Or if you need it you could expand into this nightmare condition:
a <= b ?
(b - a <= PI && a <= g && g <= b) || (b - a > PI && (b <= g || g <= a)) :
(a - b <= PI && b <= g && g <= a) || (a - b > PI && (a <= g || g <= b))
Note that all this math presumes that your input is in radians and in the range [0 : 2π].
Live Example
I personally had the same problem recently and found counterexamples for all the answers posted yet, so I will share my own approach.
Let a be the start angle and b the end angle and we are checking whether c is between them clockwise, that means when you go from a to b you must pass c. The approach of checking whether c is in the range from a to b gives you false positives when b is greater than a numerically. For example:
a=80°, b=320° and c=150°: a <= c <= b which would mean that c is between a and b.
But it isn't.
The approach that's working is to subtract 360 from b if it is greater than a and also subtract 360 from c if c is greater than a. Then check whether a <= c <= b.
In Java:
public static boolean isBetween(double c, double a, double b) {
if (b > a) b -= 360;
if (c > a) c -= 360;
return a <= c && c <= b;
}
This assumes that a, b and c are in range 0 to 360.
Some example:
isBetween(150, 80, 320) => false
isBetween(30, 80, 320) => true
isBetween(340, 80, 320) => true
isBetween(140, 0, 160) => true
isBetween(180, 0, 160) => false
There is an issue with the suggested solutions when handling negative angles (e.g. from=30 to=-29)
The suggested (kotlin) fix should be:
fun isBetween(from:Float,to:Float,check:Float,inclusive:Boolean = true):Boolean{
var a1 = to - from
a1 = (a1 + 180f).mod(360f) - 180f
if(a1<0f) a1+=360f
var a2 = check - from
a2 = (a2 + 180f).mod(360f) - 180f
if(a2<0f) a2+=360f
val between = if(inclusive) a2<=a1 else a2<a1 && a2>0f
println("$from->$to, $check, $between ($a1,$a2)")
return between }
Assuming a > c, you would actually use:
( b < a ) && ( b > c )
This is the same as checking if a value is between a lower and upper bound. Them being angles makes no difference, unless you want to take into account the fact that as you go round a circle, an angle of 405 is the same as an angle of 45. In which case you can just use a % 360 to get the angle betweeen 0 and 360.

Resources