Graphviz: Items not in alphabetic order - graphviz

Good morning, can anyone tell why the items on the graph are displayed in the order 1,3,2 rather than 1,2,3 please? I guess this is a bug, how to workaround it? Thanks in advance!
Open
http://viz-js.com/
Paste this and focus on 3rd level (the bottom)
digraph G {
"NA";
"I";
"II";
"III";
"1";
"2";
"3";
{rank = same 1; 2 ; 3}
{rank = same I; II ; III}
"NA"->"I" ;
"NA"->"II" ;
"NA"->"III" ;
"I"->"1" ;
"I"->"2" ;
"I"->"3" ;
"II"->"1" ;
"II"->"2" ;
"II"->"3" ;
"III"->"1" ;
"III"->"2" ;
"III"->"3" ;
"NA"->"1" ;
"NA"->"2" ;
"NA"->"3" ;
}

A common issue, we want a graph to look "just so" - whatever our personal aesthetic is. But the dot algorithms are programmed to a different set of goals - sometimes producing very confusing results.
Luckily your problem is easily (and explicitly) resolved with the ordering attribute.
digraph G {
"NA";
"I" [ordering=out]; // explicit ordering of out edges
"II";
"III";
"1";
"2";
"3";
{rank = same 1; 2 ; 3}
{rank = same I; II ; III}
"NA"->"I" ;
"NA"->"II" ;
"NA"->"III" ;
"I"->"1" ;
"I"->"2" ;
"I"->"3" ;
"II"->"1" ;
"II"->"2" ;
"II"->"3" ;
"III"->"1" ;
"III"->"2" ;
"III"->"3" ;
"NA"->"1" ;
"NA"->"2" ;
"NA"->"3" ;
}
Sometimes these ordering-type problems can be hard to get "right", but not this time. The only trick was to find the "right" attribute and a way to use it.

Related

Prolog, return only smallest result

For example my output is like this
?- sroute(india,england,X).
X = 2481 ;
X = 3438 ;
X = 1931 ;
X = 3762 ;
X = 3840 ;
X = 1922 ;
X = 2668 ;
X = 2677 ;
X = 4184 ;
X = 3227 ;
X = 2000 ;
false.
I'm assuming I found all routes and their distances(recursively) in my code and they are all true, but i want to see only "X = 1922 ." when i ask sroute(india,england,X). How i can do this, thanks for helping.
You can call setof/3 to get a sorted set and take only the first element of the resulting set:
setof(X, sroute(india,england,X), [Min|_]).

For loop being ignored

I've written this script, but everytime i click run, All I get is a blank image in the output. And when I try to print lists or variable within the for loops, nothing prints. if i remove the last line, I get nothing.
It seems like my For loops aren't running. Can anyone see what I have done wrong?
people = 100;
c = 3; (* number of connections to add to graph per person added*)
d = 1; (* Number of people assigned randomly*)
ct =3; (* number of traits person must have in common *)
region = 11; (* Position of region percentage break down list *)
m={{0.48,0.52},{0.19,0.25,0.40,0.16},{0.36,30,34},
{0.26,0.39,0.35},{0.18,32,32,18},{0.05,0.95},
{0.13,0.87},{0.34,0.49,0.17},{0.27,0.23,0.01,0.24,0.03,0.07,0.15},
{0.7,0.12,0.04,0.03,0.11},
{0.19,0.23,0.37,0.21}}; (* List of list of % breakdowns of traits*)
randomchoice[matr_]:=Table[RandomChoice[matr[[i]]
-> Range[Length[matr[[i]]]]],{i,Length[matr]}];
PickTraits := RandomChoice[Range[Length[m]-1],ct];
listoflistoftraits = Table[randomchoice[m],people];
adjmat = {};
For[j,j<Range[Length[people]],1,
commontraits = Table[listoflistoftraits[[j]],
{i,PickTraits}];
ccount = 0;
possibleconnections = {};
possibleregionconnections = {};
emptyc = {};
For[k,k<people,1,
If[Count[listoflistoftraits[[k]],commontraits] = ct,
Append[possibleconnections,k]
,Unevaluated[Sequence[]]
];
If[listoflistoftraits[[k,Length[listoflistoftraits,region]]] =
listoflistoftraits[[j,region]],
Append[possibleregionconnections,k]
,Unevaluated[Sequence[]]
]
];
selected = RandomChoice[possibleconnections,c-d];
randomselect = RandomChoice[possibleregionconnections,d];
connectionindices = Join[selected,randomselect];
emptyc = Table[If[MemberQ[connectionindices,i],1,0],
{i,people}];
Append[adjmat,emptyc]
]
AdjacencyGraph[adjmat]
#murksiuke is right. people is an Integer so Range[Length[people]] == {}. j is not initialized to any value and it is not incremented anywhere, so the For loop will never terminate. Same for the loop over k. You probably want something like
For[j = 1, j <= people, j++, ...]
The second argument to Count is a pattern, commontraits is a list of Integer, so it will never match a list. Maybe you intended
Count[{listoflistoftraits[[k]]}, commontraits]
Length only takes one argument, two are being passed
Length[listoflistoftraits, region]
Not sure what you intended.

Force some connections to be horizontal

I'm using DOT to visualize a lisp AST, and the picture that is generated currently looks like this:
Currently, the vertical lines are specified normally like parent -> child;, and the skewed ones are specified using constraint like so: parent -> child [constraint=false];.
This kind of works, but what I'm really looking for is a way to make the vertical connections stay the same where each connection puts the child one row downwards, but make the horizontal connections be actually horizontal. This would create something that looks more like this:
Is this possible?
You may be making it too complicated - this simple basic code does the job:
digraph so
{
# nodes
A[ label = "list" ];
B[ label = "ident: +" ];
C[ label = "literal: 1" ];
D[ label = "list" ];
E[ label = "ident: *" ];
F[ label = "literal: 3" ];
G[ label = "literal: 2" ];
# layout
{ rank = same; B C D }
{ rank = same; E F G }
# edges
A -> B;
B -> C -> D;
D -> E;
E -> F -> G;
}
compiled with dot -T png -o so.png so.dot yields what you want:

Insertion sort using fold_left with bool function passing as argument

I want to write simple insertion sort function using fold_left but I also want to pass function that will specify order in my sort fun.
What I don't know, is how to pass it to fold_left..
let rec insert f l e =
match l with
| [] -> [e]
| h :: t -> if f e h then h :: insert f t e else e :: l;;
let insertion_sort f l = List.fold_left insert f [] l;;
let less x y = x < y;;
let result = insertion_sort less [2 ; 5 ; 1 ; 9 ; 7 ; -2 ; 0 ; 124];;
This what I am talking about but fold_left doesn't accept that solution.
When I make specialization of sort function then it works just fine.
let insertLess = insert less;;
let insertion_sortLess l = List.fold_left insertLess [] l;;
let result = insertion_sortLess [2 ; 5 ; 1 ; 9 ; 7 ; -2 ; 0 ; 124];;
# val result : int list = [124; 9; 7; 5; 2; 1; 0; -2]
List.fold_left insert f ... will apply insert and f as separate arguments to List.fold_left. What you want is List.fold (insert f) ..., which will apply f to insert, and then the result of that to List.fold_left.
Edit: In addition, you don't need to define less. You can pass > as a function directly by surrounding it in parentheses: insertion_sort (<) ...

How to print a Stack data structure in OCaml

Anyone can tell how to print a Stack data structure in OCaml?
The build-in Stack type definition is like :
type 'a t = { mutable c : 'a list }
exception Empty
let create () = { c = [] }
let clear s = s.c <- []
let push x s = s.c <- x :: s.c
let pop s = match s.c with hd::tl -> s.c <- tl; hd | [] -> raise Empty
let length s = List.length s.c
let iter f s = List.iter f s.c
Want to print and keep its elements in place, which means do not use pop and push.
Better to use the pattern matching to complete the problem.
Code should be like:
let print_stack stack =???
This looks like it could be homework. You should show something you've tried that didn't work, and explain why you think it didn't work. This is a lot more valuable that just having somebody give you the answer.
If it's not homework: if you think about it, you can find a good implementation at another place in the standard library. The implementation of Stack.iter tells you where to look.
It seems like the function Stack.iter does exactly what you want:
let print_stack print_elem stack = Stack.iter print_elem
Where. print_elem prints one element of the stack.
e.g. let print_elem_int n = (print_int n; print_newline ())
Finally get the answer:
let rec print_s {c=l}=
match l with
| [] -> raise Empty
| [x] -> print_int x; print_string " "
| h :: ts -> print_int h; print_string " "; print_s {c=ts}
;;
Improved version:
let print_s2 {c=l}=
let rec print_l list =
match list with
| [] -> raise Empty
| [x] -> print_int x; print_string " "
| h :: ts -> print_int h; print_string " "; print_l ts
in
print_l l
;;

Resources