Nested clusters (or add_subgraph) on pygraphviz - graphviz

With pygraphviz, I can add subgraphs with add_subgraph(list_of_nodes, label='cluster_somename'). This will create it inside a subgraph block when layout is called.
Is there a way to nest the subgraphs?
I'm using the dot layout, I know it can handle and display subclusters if they are nested. But I can't get pygraphviz to output nested clusters.

You can call the subgraph's add_subgraph() to create a nested subgraph.
import pygraphviz as pgv
g = pgv.AGraph(name='root')
g.add_node('A')
g.add_subgraph(name='cluster_1')
c1 = g.subgraphs()[-1]
c1.add_node('B')
c1.add_subgraph(name='cluster_2')
c2 = c1.subgraphs()[-1]
c2.add_node('C')
print(g)
strict graph root {
subgraph cluster_1 {
subgraph cluster_2 {
C;
}
B;
}
A;
}

Related

ArangoDB: Syntax error Unexpected For declaration

in the following query I want to traverse a graph and get a list of fraud nodes and then I want to get all the traversals between those fraud nodes in the graph.
Fraud nodes I want to store in the variable lstofnodes.
How to solve this error?
let lstofnodes=(for doc in Account
filter doc.fraud == true
for v in 1..3 outbound doc graph "G1"
return distinct v._id)
return lstofnodes
for vertex in 1..3 outbound lstofndes graph "G1"
return distinct vertex._id
Can you try (the first return seems wrong, but cannot verify without data)
let lstofnodes=(for doc in Account
filter doc.fraud == true
for v in 1..3 outbound doc graph "G1"
return distinct v._id)
FOR startnode IN lstofnodes
for vertex in 1..3 outbound startnode graph "G1"
return distinct vertex._id

Objects arranged as a graph

I want to arrange many objects of a certain class as a graph in Matlab. The goal is, that when I create a new object it automatically is added to the graph. However, as far as I can see graphs only accept numbers when I add a new node. How is typically dealt with it? Should I have a GroupClass that holds all the objects and a graph with the relations? What I would like to have is something like
G = graph()
O1 = createObject(G)
O2 = createObject(G)
and in createObject something like
...
G.addnode(O1)
G.addedge(O1,O2)
...
Afterwards I want to be able to plot the relations, print out groups or all nodes, etc.
You can do this by adding nodes as a "node properties" table. Here's a very simple example:
G = graph();
for idx = 1:10
% make a single-row table containing the name and data
% associated with this node
nodeProps = table({['Idx ', num2str(idx)]}, ...
MException('msg:id', sprintf('Message %d', idx)), ...
'VariableNames', {'Name', 'Data'});
G = addnode(G, nodeProps);
end
for idx = 2:10
% add edges based on the node names
G = addedge(G, 'Idx 1', sprintf('Idx %d', idx));
end
plot(G)

How to flatten recursive hierarchy using Hive/Pig/MapReduce

I have unbalanced tree data stored in tabular format like:
parent,child
a,b
b,c
c,d
c,f
f,g
The depth of tree is unknow.
how to flatten this hierarchy where each row contains entire path from leaf node to root node in a row as:
leaf node, root node, intermediate nodes
d,a,d:c:b
f,a,e:b
Any suggestions to solve above problem using hive, pig or mapreduce? Thanks in advance.
I tried to solve it using pig, here are the sample code:
Join function:
-- Join parent and child
Define join_hierarchy ( leftA, source, result) returns output {
joined= join $leftA by parent left, $source by child;
tmp_filtered= filter joined by source::parent is null;
part= foreach tmp_filtered leftA::child as child, leftA::path as path;
$result= union part, $result;
part_remaining= filter joined by source::parent is not null;
$output= foreach part_remaining generate $leftA::child as child, source::parent as parent, concat(concat(source::parent,':'),$leftA::path)
}
Load dataset:
--My dataset field delimiter is ','.
source= load '*****' using pigStorage(',') as (parent:chararray, child:chararray);
--create additional column for path
leftA= foreach source generate child, parent, concat(parent,':');
--initially result table will be blank.
result= limit leftA 1;
result= foreach result generate '' as child , '' as parent;
--Flatten hierarchy to 4 levels. Add below lines equivalent to hierarchy depth.
leftA= join_hierarchy(leftA, source, result);
leftA= join_hierarchy(leftA, source, result);
leftA= join_hierarchy(leftA, source, result);
leftA= join_hierarchy(leftA, source, result);

OCaml: parse JSON into cyclic type

This question is related to another question I asked before.
I am reading data from a JSON file and try to parse them into a datatype i made.
{
"rooms":
[
{
"id": "room1",
"description": "This is Room 1. There is an exit to the north.\nYou should drop the white hat here.",
"items": ["black hat"],
"points": 10,
"exits": [
{
"direction": "north",
"room": "room2"
}
],
"treasure": ["white hat"]
},
{
"id": "room2",
"description": "This is Room 2. There is an exit to the south.\nYou should drop the black hat here.",
"items": [],
"points": 10,
"exits": [
{
"direction": "south",
"room": "room1"
}
],
"treasure": ["black hat"]
}
]
}
My user-defined type for room is:
type room = {
room_id : int ;
room_description : string ;
room_items : item list ;
room_points : int ;
room_exits : exit list ;
room_treasure : item list ;
}
and exit = direction * room
However, room has a "exit" field, which itself is a "room" type. Then when I try to create record for room1, I first need to define room2, but in order to define room2, I need to know room1. This seems like a cyclic type.
Can anyone help me with this?
If you stick to the immutable and eager subset of OCaml, there's no real way to build up arbitrary cyclic structures. The problem is exactly as you state it.
It's possible to build specific examples of cyclic structures using let rec, but I don't believe this can be extended to building arbitrary structures while (for example) parsing JSON.
You can solve the problem by dropping the requirement for immutable data. If you make the links to other rooms into OCaml references (mutable fields), you can build cyclic structures pretty much as you'd do it in the imperative part of JavaScript.
One way to make this work might be to use an array for room_exits rather than a list. OCaml arrays are mutable.
Here's some code that creates the complete graph over 3 nodes (for a trivial node type that contains only the neighbor nodes):
# type node = { nabes: node array };;
type node = { nabes : node array; }
# type graph = node list;;
type graph = node list
# let z = { nabes = [||] };;
val z : node = {nabes = [||]}
# let temp = Array.init 3 (fun _ -> { nabes = Array.make 2 z});;
val temp : node array =
[|{nabes = [|{nabes = [||]}; {nabes = [||]}|]};
{nabes = [|{nabes = [||]}; {nabes = [||]}|]};
{nabes = [|{nabes = [||]}; {nabes = [||]}|]}|]
# temp.(0).nabes.(0) <- temp.(1);;
- : unit = ()
# temp.(0).nabes.(1) <- temp.(2);;
- : unit = ()
# temp.(1).nabes.(0) <- temp.(0);;
- : unit = ()
# temp.(1).nabes.(1) <- temp.(2);;
- : unit = ()
# temp.(2).nabes.(0) <- temp.(0);;
- : unit = ()
# temp.(2).nabes.(1) <- temp.(1);;
- : unit = ()
# let k3 : graph = Array.to_list temp;;
val k3 : graph =
[{nabes =
[|{nabes = [|<cycle>; {nabes = [|<cycle>; <cycle>|]}|]};
{nabes = [|<cycle>; {nabes = [|<cycle>; <cycle>|]}|]}|]};
{nabes =
[|{nabes = [|<cycle>; {nabes = [|<cycle>; <cycle>|]}|]};
{nabes = [|{nabes = [|<cycle>; <cycle>|]}; <cycle>|]}|]};
{nabes =
[|{nabes = [|{nabes = [|<cycle>; <cycle>|]}; <cycle>|]};
{nabes = [|{nabes = [|<cycle>; <cycle>|]}; <cycle>|]}|]}]
You can also solve the problem by linking through an intermediate structure. For example, you can have a dictionary that maps room names to rooms. Then your links to other rooms can just use the name (rather than a direct link to the OCaml value). I've used this method in the past, and it works pretty well. (This is, in fact, how your JSON is working implicitly.)
That's why in the previous answer I put function room_exits into the Game interface, not into the Room. The intuition behind this is that room exits, i.e., other rooms, are not part of the room. If you define some structure, as "the room is walls, treasure, and other rooms", then you defining something more than a room, that basically means, that you're defining the whole maze. So the room, is just a room, i.e., it's contents. The way how the rooms are connected is a Maze. (I've used Game for this in previous answer, but maybe Maze is a better name).
To summarize, in your particular case, you need just to remove references to other rooms from the room data representation, and store the maze information as an associative container inside the maze (or game) data structure:
type exits = (dir * room) list
type maze = {
...
entry : room;
rooms : exits Room.Map.t
}
or maybe even more precise, you can use Dir.Map as an associative container, instead of associative list:
type exits = room Dir.Map.t
The latter representation guarantees that there is no more than one room per direction.
Note: the above definitions assumes that Room implements Comparable interface, and that you're using Core library. (I think you're since I remember that there was a link to RWO from the course page). To implement a comparable interface you need to implement the compare function and Sexpable interface. It is easy using type generators, basically it looks like this:
module Room = struct
type t = {
name : string;
treasures : treasure list;
...
} with compare, sexp
include Comparable.Make(struct
type nonrec t = t with compare, sexp
end)
end
the with compare, sexp will automatically generate the compare function, and the pair of sexp_of_t, t_of_sexp functions, that are needed for a Comparable.Make functor to realize the Comparable interface.
Note: if it too much at this point of course, then you can just use String.Map.t data structure, and perform the lookup by a room name. This wouldn't be a bad idea.

Titan cannot find suitable index while index exists

I try to create a simple Titan graph system on Berkeley, and Titan does not use the index I've created for its queries.
String INDEX_NAME = "search"
File dir=new File("C:/TEMP/titanTest1");
dir.mkdirs();
TitanFactory.Builder config = TitanFactory.build();
config.set("storage.backend", "berkeleyje");
config.set("storage.directory", dir.getAbsolutePath());
config.set("index."+INDEX_NAME+".backend","elasticsearch");
config.set("index." + INDEX_NAME + ".directory", new File(dir,"es").getAbsolutePath());
config.set("index."+INDEX_NAME+".elasticsearch.local-mode",true);
config.set("index."+INDEX_NAME+".elasticsearch.client-only",false);
config.set("query.force-index",true);
TitanGraph tg= config.open();
try {
if (tg.getPropertyKey("name")==null){
TitanManagement mgmt = tg.getManagementSystem();
VertexLabel metaclassLabel=mgmt.makeVertexLabel("metaclass").make();
final PropertyKey name = mgmt.makePropertyKey("name").dataType(String.class).make();
mgmt.buildIndex("metaClassesByName",Vertex.class).addKey(name).indexOnly(metaclassLabel).buildMixedIndex(INDEX_NAME);
mgmt.commit();
}
System.out.println("indexed:"+tg.getIndexedKeys(Vertex.class));
Vertex v=tg.addVertexWithLabel("metaclass");
v.setProperty("name", "test");
for (Object o:tg.query().has("name").has(ImplicitKey.LABEL.getName(), "metaclass").vertices()){
Vertex v2=(Vertex)o;
System.out.println(v2);
}
tg.commit()
} finally {
tg.shutdown();
}
this code prints:
indexed:[name]
Exception in thread "main" com.thinkaurelius.titan.core.TitanException: Could not find a suitable index to answer graph query and graph scans are disabled: [(name <> null AND label = metaclass)]:VERTEX
at com.thinkaurelius.titan.graphdb.transaction.StandardTitanTx$8.execute(StandardTitanTx.java:1198)
I don't understand why Titan can't use the index I've defined. I want to list all objects that have the metaclass label. The only thing that works is to defined a composite index and search a vertex with an exact name value. Is it in anyway possible?
Thanks!
You can use a direct index query:
for (Result<TitanVertex> res : g.indexQuery("metaClassesByName","v.name:*").vertices()) {
Vertex v2 = res.getElement();
System.out.println(v2);
}

Resources