I have a graph modeled this way. A --calls('for', 'Item1')--> B --calls('for', 'Item1')--> C --calls('for', 'Item1')--> D.
A calls B for Item1(property of the edge). B calls C and C calls D. There can be other chains as well in the graph that would have some vertex call D for Item1. How can i determine all such chains? All the ways in which D can be called for Item1.
Apologies if the question is too basic. My knowledge on graph is very minimal and I am using cosmosDB to model this.
I suppose I would start at "D" and follow "Item1" paths from there using repeat(). Assuming "D" is the actual T.id (element identifier):
g.V("D").repeat(inE('calls').has('for','Item1').outV()).emit().path()
The above is the beginnings of such a query. You might need a terminating condition to that repeat() loop and methods to avoid cycles (i.e. simplePath()) if your graph contains such things so that you avoid infinite traversals along such paths.
Related
I have a large network table that I want to simplify by merging nodes that share the same interactions, so that it will have a better network once imaged (I am using Cytoscape). The interactions do not have direction. As a mini example, if I have a table such as below.
A E
B E
C G
C H
D G
H D
E F
R S
The two columns are nodes that interact with each other. In this case since nodes A, B and F all only have connections to node E, I want to merge them so it's A,B,F as one node that interacts with E. Similarly since both C and D only interact with G and H I would want to merge them together. The resulting table should look something like below.
A,B,F E
C,D G
C,D H
R S
I have created a list with all the nodes, but I am not sure how to see if they have matching interactions since they can be in either column. Is there a good way/program to handle this?
For most networks, there would not be single solution to this problem. Once you start collapsing you begin to exclude other equally valid solutions. For example, even in your simplified example, these are other valid solutions:
A,B,F E
G,H C
G,H D
R S
or even
A,B,F E
C,D G,H
R S
And it gets more complicated once you include interactions across your relatively clean example, e.g., A G. But if your data really is partitioned like this example (which should be immediately apparent when you load it into iGraph or Cytoscape and perform any basic layout to see a bunch of separate networks), then you might be able to get a solution by querying all interaction partners for each node, then collapsing based on identical partner sets.
I don't know of a function iGraph or Cytoscape that can do this for you.
And if you network is not a partitioned set of multiple networks, then I don't think this is feasible at all.
Do I understand it right, that your cytoscape graph contains all said elements and the 'interactions' stand for edges in cytoscape? Because if your network has said elements and edges, you could, for example (this will not be a fast solution I think), make an array with all id' of your elements with
cy.nodes();
and then call
Object.keys(cy.edges("[target = '" + nodeId + "']")).length;
on every node in the array and save the number of edges going out of said node in the array. This way you can find all nodes with at least x nodes attached and then you can do whatever you want. You could e.g make the selected nodes to parents, so that the connected nodes are now inside the parent nodes?
Please tell me if this helps you or not :)
So I have been trying to figure out the order for a Depth First Search in this graph
And I can't seem to understand what comes first, if A-D or A-B and then how would I proceed considering B is also a direct descendant from D? Also does cost matters in DFS?
I would like to create a bunch of "and" and "or" and "not" gates in a directed graph.
And then traverse from the inputs to see what they results are.
I assume there is a ready made traversal that would do that but I don't see it.
I don't know what the name of such a traversal would be.
Certainly breadth first will not do the job.
I need to get ALL the leaves, and go up toward the root.
In other words
A = (B & (C & Z))
I need to resolve C # Z first.
I need to put this type of thing in a graph and to traverse up.
You would probably create each of the operations as a node which has N incoming and one outgoing connection. You can of course also have more complex operations encapsuled as a node.
With Neo4j 2.0 I would use Labels for the 3 types of operations.
I assume your leaves would then be boolean values? Actually I think you have many roots and just a single leaf (the result expression)
(input1)-->(:AND {id:1})-->(:OR {id:2})-->(output)
(input2)-->(:AND {id:1})
(input3)------------------>(:OR {id:2})
Then you can use CASE when for decisions on the label type and use the collection predicates (ALL, ANY) for the computation
See: http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html
Predicates: http://docs.neo4j.org/chunked/milestone/query-function.html
Labels: http://docs.neo4j.org/chunked/milestone/query-match.html#match-get-all-nodes-with-a-label
Given an undirected cyclic graph, I want to find all possible traversals with Breadth-First search or Depth-First search. That is given a graph as an adjacency-list:
A-BC
B-A
C-ADE
D-C
E-C
So all BFS paths from root A would be:
{ABCDE,ABCED,ACBDE,ACBED}
and for DFS:
{ABCDE,ABCED,ACDEB,ACEDB}
How would I generate those traversals algorithmically in a meaningful way? I suppose one could generate all permutations of letters and check their validity, but that seems like last-resort to me.
Any help would be appreciated.
Apart from the obvious way where you actually perform all possible DFS and BFS traversals you could try this approach:
Step 1.
In a dfs traversal starting from the root A transform the adjacency list of the currently visited node like so: First remove the parent of the node from the list. Second generate all permutations of the remaining nodes in the adj list.
So if you are at node C having come from node A you will do:
C -> ADE transform into C -> DE transform into C -> [DE, ED]
Step 2.
After step 1 you have the following transformed adj list:
A -> [CB, BC]
B -> []
C -> [DE, ED]
D -> []
E -> []
Now you launch a processing starting from (A,0), where the first item in the pair is the traversal path and the second is an index. Lets assume we have two queues. A BFS queue and a DFS queue. We put this pair into both queues.
Now we repeat the following, first for one queue until it is empty and then for the other queue.
We pop the first pair off the queue. We get (A,0). The node A maps to [BC, CB]. So we generate two new paths (ACB,1) and (ABC,1). Put these new paths in the queue.
Take the first one of these off the queue to get (ACB,1). The index is 1 so we look at the second character in the path string. This is C. Node C maps to [DE, ED].
The BFS children of this path would be (ACBDE,2) and (ACBED,2) which we obtained by appending the child permutation.
The DFS children of this path would be (ACDEB,2) and (ACEDB,2) which we obtained by inserting the child permutation right after C into the path string.
We generate the new paths according to which queue we are working on, based on the above and put them in the queue. So if we are working on the BFS queue we put in (ACBDE,2) and (ACBED,2). The contents of our queue are now : (ABC,1) , (ACBDE,2), (ACBED,2).
We pop (ABC,1) off the queue. Generate (ABC,2) since B has no children. And get the queue :
(ACBDE,2), (ACBED,2), (ABC,2) and so on. At some point we will end up with a bunch of pairs where the index is not contained in the path. For example if we get (ACBED,5) we know this is a finished path.
BFS is should be quite simple: each node has a certain depth at which it will be found. In your example you find A at depth 0, B and C at depth 1 and E and D at depth 2. In each BFS path, you will have the element with depth 0 (A) as the first element, followed by any permutation of the elements at depth 1 (B and C), followed by any permutation of the elements at depth 2 (E and D), etc...
If you look at your example, your 4 BFS paths match that pattern. A is always the first element, followed by BC or CB, followed by DE or ED. You can generalize this for graphs with nodes at deeper depths.
To find that, all you need is 1 Dijkstra search which is quite cheap.
In DFS, you don't have the nice separation by depth which makes BFS straightforward. I don't immediately see an algorithm that is as efficient as the one above. You could set up a graph structure and build up your paths by traversing your graph and backtracking. There are some cases in which this would not be very efficient but it might be enough for your application.
a little out of my depth here and need to phone a friend. I've got a directed acyclical graph I need to traverse and I'm stumbling into to graph theory for the first time. I've been reading a lot about it lately but unfortunately I don't have time to figure this out academically. Can someone give me a kick with some help as to how to process this tree?
Here are the rules:
there are n root nodes (I call them "sources")
there are n end nodes
source nodes carry a numeric value
downstream nodes (I call them "worker" nodes) preform various operations on the incoming values like Add, Mult, etc.
As you can see from the graph below, nodes a, b, and c need to be processed before d, e, or f.
What's the proper order to walk this tree?
I would look into linearization of DAGs which should be achievable through Topological sorts.
Linearization, from what I remember, basically sorts in an order which holds to the invariant that for all nodes (Node_X) that have an outdegree to any other given node NodeA, NodeX appears before NodeA.
This would mean that, from your example, nodes a,b, and d would be processed first. Node c second. Nodes e and f, last.
http://en.wikipedia.org/wiki/Topological_sorting
You need to process the nodes via a Topological sort. The sort is not necessarily unique so there might be more than one available order (not that this should matter anyway).
The linked wikipedia page should have concrete algorithms to help you.