GraphViz DOT rectangular layout with uneven distribution of nodes along parallel sides - layout

I'm trying to expand upon this rectangular layout example. The goal is to generate a similar layout but with a dynamic distribution of nodes (within reason, say no more than 20 per row) along both the top and bottom. (For now, the sides will always be 3 nodes.)
My current simplified base example uses this code:
digraph {
rankdir="LR";
node [group=top];
aa -> ab -> ac -> ad -> ae -> af -> ba;
{ rank="same"; ba -> bb -> ca; }
node [group=bot];
da -> cc -> cb -> ca [ dir="back" ];
{ rank="same"; aa -> db -> da [ dir="back"]; }
}
Output:
All the SO solutions I've come across suggest using invisible nodes, but that doesn't seem practical as I'll have math out the least common multiple, space the nodes accordingly, and create an invisible edge to lock them in place. I'd like to leave that as a last resort if there aren't better options out there.
Have tried several other approaches like calculating and setting minlen separately for each edge, playing with settings like clusterrank, nodesep, ranksep, constraint.
Any other ideas on how to equally space the nodes along the top and bottom sides of the layout?
(I'm not tied to GraphViz. Alternative software libraries are welcome. Preferably free and with a Python API.)

dot will always try to figure out the "right" hierarchical position of a node, so "equally spacing" is meaningless within one graph. In order to get a node to a specific position, you will always have to tell dot about that position. Empty nodes give a large amount of flexibility, but can be cumbersome.
In your case, you could calculate the nodes that should be vertically aligned, and simply use another rank = same instruction. Admittedly, this is not the real answer to your question (as I think such answer does not exist) but maybe an improvement over the empty node approach:
digraph {
rankdir="LR";
node [group=top];
aa -> ab -> ac -> ad -> ae -> af -> ba;
{ rank="same"; ba -> bb -> ca; }
node [group=bot];
da -> cc -> cb -> ca [ dir="back" ];
{ rank="same"; aa -> db -> da [ dir="back"]; }
// this leads to a manually fixed "equal spacing":
{ rank = same; ac cc }
{ rank = same; ae cb }
}
which gives you

Related

Representing a chessboard in Haskell

I'm trying to implement a function in Haskell that returns a list containing all possible moves for the player who's up. The function's only argument is a String composed of an actual state of the board (in Forsyth-Edwards Notation ) followed by the moving player(b/w).
Notation example : rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w (starting board state)
A move is transmitted as a string of the form [origin]-[destination]. The destination is always a position of the form [column][row], where the lower left square is called a1 and the upper right square is called h8. A move would be for example the move "b3-c4". (no castling/En-passant).
In Java I would use a 2d Array for the Board, but in Haskell I can't find a similar solution (I'm new to functional programming).
What would be a good way/data structure to represent the chess board in?
There are two primary options for storing a board state. The first is a 2D list of Maybe, where a piece would be represented as, e.g. Just $ Piece Black King and a blank square would be represented as Nothing. This optimizes determining if a square is occupied over listing where pieces are (which might be important if you plan to add rendering later):
type Board = Vector (Vector (Maybe Piece))
data Piece = Piece { color :: Color
, type :: PieceType }
The second option is to store a list of pieces and their locations. This implementation is faster to enumerate the locations of all pieces, but slower to check if there is a piece on a particular square:
type Pieces = [Placement]
type Placement = { position :: Position
, piece :: Piece }
data Position =
Pos { rank :: Int
, file :: Int }
deriving (Show, Eq)
data Piece =
Piece { color :: Color
, ptype :: PieceType }
deriving Show
EDIT: It's worth noting that with an 8x8 grid and a maximum of 32 pieces on the board, the performance hit either way is going to be minimal unless you're doing a lot of calculations.
Data.Vector, has constant time lookup by index.
A chessboard can be represented as a Vector (Vector (Maybe Piece)). To define Piece, see ADTs

How to restrict a cross point bin based on the sum of crossed coverpoints? and what's the meaning of binsof?

I got two 3-bit signals a and b with legal values 0-4.
I'm trying to make a cross point where I only consider the coverage if the sum also is in the range 0-4. What is the preferred way to do that? I have a solution that seems to work, but I have guessed in some places ...
covergroup CG_operands #(posedge clk);
coveproint a { illegal_bins hi = {[5:$]}; }
coveproint b { illegal_bins hi = {[5:$]}; }
cross a, b { illegal_bins hi = binsof(a) with (a + b > 4) }
endgroup
What does the binsof(a) part do? If I change it to binsof(a) && binsof(b) nothing seems to change in the coverage report. Is it possible to skip the binsof part completely?
Also can I make the coverpoint conditions look more like the with-condition of the cross using > 4?
The binsof operator is used to select a subset of bins from a coverpoint. But since you are selecting the entire coverpoint a, there's no difference between using binsof(b) or binsof(a) && binsof(b). You could write
ab: cross a, b { ignore_bins hi = ab with (a + b > 4); }

Comparing predicates

A poster asked how to compare functions in Alloy. While testing a small example (comparing predicates instead of functions) to answer the question with, I've noticed the following behavior, which puzzles me.
The analyzer finds no counterexamples whenever the boundary of the check command is higher than 3 and the fact 'f1' is active. Inactivating the fact, the analyzer works as expected. Why does the redundant fact 'f1' modify the analyzer's operation so and why just in the case the boundary is higher than 3?
open util/ordering [V]
sig V {}
fact f1 {
# V > 0
}
pred p1 [x: V] {
x = last
}
pred p2 [x: V] {
x = first
}
assert a1 {
all x: V | p1[x] <=> p2[x]
}
check a1 for 3
It appears that whenever the check boundary is 4 or higher and 'f1' is active the analyzer reports '0 vars. 0 primary vars. 0 clauses.'
I am unable at the moment to look into the details, but it seems likely that you're seeing overflow behavior, based in part on the fact that Alloy's integers are very narrow (4 bits by default, I believe?) twos-complement integers, so overflow happens regularly.
Several changes might be instructive, separately or together, to see if they affect the behavior.
replace fact f1 with some V
turn on the "Forbid Overflow" option
provide an explicit bit width for Int using the scope command (for other signatures, the scope number specifies a maximum number of instances; for Int it specifies a bit width)
As Loïc Gammaitoni has put it in another question here "You should always be careful when playing with numbers in Alloy".

Solving equations as CSP

I have a set of equations. I also have a set of values and the results for the equation.
Something like:
a + b + c = x
and some allocation might be:
1 + 1 + 1 = 3
2 + 3 + 4 = 9
However, the actual equations are much longer and may contain some functions, for example logarithms.
I now need to alter the result of a given set in a way that (1) the equation becomes equal to a specific value xx and (2) the parameters change as little as possible.
I thought I could solve this as a CSP by altering the eqation to
(a + ax) + (b + bx) + (c + cx) = xx
where a, b and c correspond to the old values and ax, bx and cx are the differences which need to be applied to the corresponding old values. And xx will be the result I want the equation to have. Note that a, b, c, xa, xb, cx etc. are all integer values and xx will always be within a certain distance to x, i.e. xx - d < x < xx + d.
In a CSP a, b, c and xx would be treated as Problem facts, ax, bx, cx would be treated as Planning variable and the equation (a + ax) + (b + bx) + (c + cx) = xx would be a hard constraint.
Minimizing all of ax, ab, ac would be a soft constraint.
I don't really see a Planning entity here.
global HardSoftScoreHolder scoreHolder;
rule "changeIsBad"
when
DeltaVariable($delta : delta)
then
scoreHolder.addSoftConstraintMatch(kcontext, -Math.abs(delta));
end
rule "equationMustBeEqual"
// No idea?
end
But I can't figure out how to go on from here. Is Optaplanner feasible for this kind of problem? It seems all PlanningVariables have to come from a List and have to be instances, whereas I only have integer values. Is my model correct?
You can wrap each integer variable in an entity class, like this:
#PlanningEntity
public class MyEntity {
private Integer myVariable;
#PlanningVariable(...)
public Integer getMyVariable() {...}
...
}
Additionally, use a planning entity range to define the range of each variable (because it differs per entity), see official docs section "4.3.5.2.2. ValueRangeProvider on a planning entity" (and don't use SwapMove's, only ChangeMove's I guess).
But overall, I am not 100% sure if this is the right tool for the job. I would be interested to know what your experience with this use case results into.
PS: Starting from 6.1.0.Beta1 (not yet released, but nightlies are available), we have IntValueRange as documented in nightly docs in section "4.3.5.2.4. ValueRangeFactory", which is more efficient for these kinds of use cases.

Control the layout of nodes in graphviz (dot2tex)?

I am new to graphviz and am just wondering how to determine the relative node positioning in a graph. For example, if I want to draw a simple triangle 'abc', with node 'a' being at the top and nodes 'b' and 'c' on the same level at the bottom, how should I tell graphviz to lay out the nodes as desired?
I tried the following:
graph G
{
node [shape="circle"];
edge [lblstyle="auto"];
{rank=min; "a"}
a -- b [label = "-"];
a -- c [label = "-"];
{rank=same; "b" "c"}
b -- c [label = "+"];
}
but the output positions nodes 'a' and 'b' on the same level at the top, with node 'c' at the bottom.
In addition, is it possible to draw two such triangles side-by-side (with a nice appropriate space in between) in the same graph? if so, how is it implemented?
Thanks a lot.
but the output positions nodes 'a' and 'b' on the same level at the
top, with node 'c' at the bottom.
I actually get a on top, centered above b and c (see image).
Your markup, slightly simplified (what's lblstyle ?), seems to achieve what you want when rendered with dot:
graph G
{
node[shape=circle];
a -- b [label = "-"];
a -- c [label = "-"];
{rank=same; b -- c [label="+"];}
}
What version of graphviz do you use?
And to have two triangles side by side:
graph G
{
node[shape=circle];
edge[label="-"];
a -- b;
a -- c;
{rank=same; b -- c [label="+"];}
d -- e;
d -- f;
{rank=same; e -- f [label="+"];}
}
However, if things get more complex, it may be difficult to have graphviz layout everything exactly as one would like. That's actually the strength of graphviz - applying layout algorithms in order to not have a user intervene.

Resources