I'm looking for a good graph database for finding set intersections -- taking any two nodes and looking at whether their edge endpoints "overlap." Social network analogy would be two look at two people and see whether they are are connected to the same people.
I've tried to get FlockDB (from the folks at Twitter) working, because intersection functions are built in, but found there wasn't much in terms of user community/support. So any recommendations of other graph databases, especially where the kind of intersection functionality I'm looking for already exists...?
Isn't that just the shortest paths between the two nodes with length == 2 ?
In Neo4j you can use the shortestPath() Finder from the GraphAlgoFactory for that.
This would tell you if there is a connection:
Node from_node = index.get("guid", "user_a").getSingle();
Node to_node = index.get("guid", "user_b").getSingle();
if(from_node != null && to_node != null) {
RelationshipExpander expander = Traversal.expanderForAllTypes(Direction.BOTH);
PathFinder<Path> finder = GraphAlgoFactory.shortestPath(expander, 2);
if(finder.findSinglePath(from_node, to_node) != null) {
//Connected by at least 1 common friend
} else {
//Too far apart or not connected at all
}
}
This would tell you who are the common friends are:
Node from_node = index.get("guid", "user_a").getSingle();
Node to_node = index.get("guid", "user_b").getSingle();
if(from_node != null && to_node != null) {
RelationshipExpander expander = Traversal.expanderForAllTypes(Direction.BOTH);
PathFinder<Path> finder = GraphAlgoFactory.shortestPath(expander, 2);
Iterable<Path> paths = finder.findAllPaths(from_node, to_node);
if(paths != null) {
for(Path path : paths) {
Relationship relationship = path.relationships().iterator().next();
Node friend_of_friend = relationship.getEndNode();
}
} else {
//Too far apart or not connected at all
}
}
This code is a little rough and is much easier to express in Cypher (taken from the Cheet Sheet in the Neo4J Server console (great way to play with Neo4J after you populate a database):
START a = (user, name, "user_a")
MATCH (a)-[:FRIEND]->(friend)-[:FRIEND]->(friend_of_friend)
RETURN friend_of_friend
This will give you a list of the nodes shared between to otherwise disconnected nodes. You can pass this query to an embedded server thought the CypherParser class.
Related
The function (code below) simply moves a character node (contact.nodeA) back after it has penetrated a collision node (contact.nodeB) that it's not allowed to pass through.
In a scenario where a user is trying to move the character node (contact.nodeA) while it's stuck in a corner, etc. the scene/character repeatedly shakes/glitches while its position is repeatedly being moved back away from contact.nodeB at 60hz.
Is it possible with SCNPhysicsContact in SceneKit to prevent contact.nodeA from moving forward into contact.nodeB in the first place? (ie., why does "contact.penetrationDistance" occur at all? Why can't we just be alerted when a physics contact has begun w/o contact.nodeA actually moving forward into contact.nodeB? We are, after all, catching the contact on "didBegin" yet there's already penetration that we have to readjust.)
(When a user is trying to move the character node while it's "stuck" in a corner, or between two rocks, etc.)
Or, is there another solution to prevent the repeated shaking of contact.nodeA as its position is repeatedly being readjusted to compensate for its penetration into contact.nodeB? Transform instead of position change?
I've already tried setting momentum to 0.0 and removing all animations, etc. However, since contact is still occurring with contact.nodeB, contact.nodeA cannot be moved away since its momentum is still being stopped during contact with nodeB.
Any help would be greatly appreciated.
private func characterNode(_ characterNode: SCNNode, hitWall wall: SCNNode, withContact contact: SCNPhysicsContact) {
if characterNode.name != "collider" { return }
if maxPenetrationDistance > contact.penetrationDistance { return }
var characterPosition = float3(characterNode.parent!.position)
var positionOffset = float3(contact.contactNormal) * Float(contact.penetrationDistance)
maxPenetrationDistance = contact.penetrationDistance
characterPosition.y += positionOffset.y
replacementPositions[characterNode.parent!] = SCNVector3(characterPosition)
}
extension GameViewController : SCNPhysicsContactDelegate {
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
if gameState != .playing { return }
contact.match(BitmaskWall) {
(matching, other) in
if other.name == "collider" {
self.characterNode(other, hitWall: matching, withContact: contact)
}
}
}
I wrote the below Rascal code that is supposed to build a tree out of a map from node names to nodes, starting at the node mapped from "top". It should repeatedly replace the children of all nodes that have strings as children in result by the nodes nodeMap maps them to, until nothing changes anymore (fixpoint).
getNode returns the node a map[str,node] maps it to, or the key itself if it is not present as a key in the map. This works fine, as proves the fact that other code at the bottom of this question does work. However, the code directly below seems to run infintely even on very small inputs.
node nodeMapToNode(map[str, node] nodeMap) {
node result = nodeMap["top"];
return outermost visit(result) {
case node n: {
if ([*str children] := getChildren(n)) {
insert makeNode(getName(n), [getNode(child, nodeMap) | child <- children]);
}
}
}
}
The following code does work and returns in an instant on small inputs as I expected. This is, however, exactly what I understood outermost-visiting should do from what I understood from the Rascal tutor.
Can anyone explain to me what the difference between these code snippets is (besides the way they are written) and what I thus misunderstood about the effect of outermost visit? Also, I'd like to know if a shorter and/or nicer way to write this code - using something like outermost-visiting instead of writing the fixpoint by hand - does exist.
node nodeMapToNode(map[str, node] nodeMap) {
node result = nodeMap["top"];
node lastResult;
do {
lastResult = result;
result = visit(lastResult) {
case node n: {
if ([*str children] := getChildren(n)) {
insert makeNode(getName(n),
[getNode(child, nodeMap) | child <- children]);
}
}
}
} while (result != lastResult);
return result;
}
What is outermost?
The rascal tutor is very compact in it's explanation but let's start from there.
repeat a top-down traversal as long as the traversal changes the resulting value (compute a fixed-point).
which in rascal terms means that this:
r = outermost visit(x) {
case str s => s + "."
when size(s) < 3
};
is syntactic sugar for:
r = x;
solve(r) {
r = top-down visit(r) {
case str s => s + "."
when size(s) < 3
};
}
I think there are two common cases were outermost/innermost makes sense:
your replacement should be repeated multiple times on the same node
your replacement generate new nodes that match other patterns
Your specific example
Regarding the example in your question. The other manually rewritten outermost is actually an innermost. The default visit strategy is bottom-up.
In general, an bottom-up visit of the tree is a quicker than a top-down. Especially when you are rewriting it, since Rascal is immutable, building a new tree bottom-up is quicker.
So, perhaps replace your code with an innermost visit instead of an outermost?
I am trying to store triplets inside of OrientDB as Vertex-Edge-Vertex relationships inside of a Java application that I am working on. My understanding of using OrientDB is that I can use the Tinkerpop API and instantiate a graph like this:
OrientGraph graph = new OrientGraph("local:/tmp/orient/test_db");
That is really all I do to instantiate the graph, then I try to connect vertices with edges in a loop like this: (Note that a Statement is a triplet consisting of subject-relationship-object.)
for (Statement s : statements) {
Vertex a = graph.addVertex(null);
Vertex b = graph.addVertex(null);
a.setProperty("Subject", s.getSubject().toBELShortForm());
RelationshipType r = s.getRelationshipType();
if (s.getObject() != null) {
b.setProperty("Object", s.getObject().toBELShortForm());
Edge e = graph.addEdge(null, a, b, r.toString());
}
else {
b.setProperty("Object", "null");
Edge e = graph.addEdge(null, a, b, "no-relationship");
}
}
I then loop through the vertices of the graph and print them out like this:
for (Vertex v : graph.getVertices()) {
out.println("Vertex: " +v.toString());
}
It does print a lot of vertices, but when I log into the server via the command line, using server.sh, all I see are the 3 records for ORole and 4 records for OUser. What am I missing here? Because it seems like although my java program runs and completes, the data is not being put into the database.
The answer, at least for now, seems to be not to use the Tinkerpop API but rather the Orient API directly. This is the same thing I was doing with Tinkerpop, but using the OrientDB API. This actually does store my data into the database:
for (Statement s : statements) {
ODocument sNode = db.createVertex();
sNode.field("Subject", s.getSubject().toBELShortForm());
sNode.save();
ODocument oNode = db.createVertex();
if (s.getObject() != null) {
oNode.field("Object", s.getObject().toBELShortForm());
oNode.save();
}
else {
oNode.field("Object", "null");
oNode.save();
}
RelationshipType r = s.getRelationshipType();
ODocument edge = db.createEdge(sNode, oNode);
if (r != null) {
edge.field(r.toString());
edge.save();
}
else {
edge.field("no relationship");
edge.save();
}
}
Create the Graph under the Server's databases directory. Below an example assuming OrientDB has been installed under "/usr/local/orient":
OrientGraph graph = new OrientGraph("local:/usr/local/orient/databases/test_db");
When you start the server.sh you should find this database correctly populated.
Lvc#
I'm working with the new face tracking SDK of Kinect (Microsoft Official), and I noticed that there's difference in detection between c++ and c#-wpf example: the first one is way faster in recognition than the second (the one I want to use, actually). In the c++ version the face tracking is almost on the fly, while in the wpf one it starts ONLY when I put my entire body (so the entire skeleton) in the FOV of Kinect.
Did anyone found out why? I noticed that the skeletonframe provided shows the property "Trackingmode = default", even though I set the kinect skeleton stream on seated.
colorImageFrame.CopyPixelDataTo(this.colorImage);
depthImageFrame.CopyPixelDataTo(this.depthImage);
skeletonFrame.CopySkeletonDataTo(this.skeletonData);
// Update the list of trackers and the trackers with the current frame information
foreach (Skeleton skeleton in this.skeletonData)
{
if (skeleton.TrackingState == SkeletonTrackingState.Tracked
|| skeleton.TrackingState == SkeletonTrackingState.PositionOnly)
{
// We want keep a record of any skeleton, tracked or untracked.
if (!this.trackedSkeletons.ContainsKey(skeleton.TrackingId))
{
this.trackedSkeletons.Add(skeleton.TrackingId, new SkeletonFaceTracker());
}
// Give each tracker the upated frame.
SkeletonFaceTracker skeletonFaceTracker;
if (this.trackedSkeletons.TryGetValue(skeleton.TrackingId,
out skeletonFaceTracker))
{
skeletonFaceTracker.OnFrameReady(this.Kinect,
colorImageFormat,
colorImage,
depthImageFormat,
depthImage,
skeleton);
skeletonFaceTracker.LastTrackedFrame = skeletonFrame.FrameNumber;
}
}
}
The code is the one provide my microsoft with the 1.5 SDK.
I had some information in other forums, specifically here (Thanks to this guy (blog)):
MSDN forum link
Basically, in the c++ example all the methods to track the face are used, both color+depth and color+depth+skeleton, while in the c# only the latter is used. So it only starts when you stand up.
I did some tests, but the other method is still not working for me, I did some modification to the code but with no luck. Here is my modification:
internal void OnFrameReady(KinectSensor kinectSensor, ColorImageFormat colorImageFormat, byte[] colorImage, DepthImageFormat depthImageFormat, short[] depthImage)
{
if (this.faceTracker == null)
{
try
{
this.faceTracker = new Microsoft.Kinect.Toolkit.FaceTracking.FaceTracker(kinectSensor);
}
catch (InvalidOperationException)
{
// During some shutdown scenarios the FaceTracker
// is unable to be instantiated. Catch that exception
// and don't track a face.
//Debug.WriteLine("AllFramesReady - creating a new FaceTracker threw an InvalidOperationException");
this.faceTracker = null;
}
}
if (this.faceTracker != null)
{
FaceTrackFrame frame = this.faceTracker.Track(
colorImageFormat,
colorImage,
depthImageFormat,
depthImage,
Microsoft.Kinect.Toolkit.FaceTracking.Rect.Empty);
//new Microsoft.Kinect.Toolkit.FaceTracking.Rect(100,100,500,400));
this.lastFaceTrackSucceeded = frame.TrackSuccessful;
if (this.lastFaceTrackSucceeded)
{
if (faceTriangles == null)
{
// only need to get this once. It doesn't change.
faceTriangles = frame.GetTriangles();
}
this.facePointsProjected = frame.GetProjected3DShape();
this.rotationVector = frame.Rotation;
this.translationVector = frame.Translation;
this.faceRect = frame.FaceRect;
this.facepoints3D = frame.Get3DShape();
}
}
}
frame.TrackSuccessful is always false. Any idea?
I finally figured it out and made a post on MSDN forums regarding what else needs to be done to get this working.
It's here.
Hope that helps!
I am using mahout to cluster text documents indexed using solr.
I have used the "text" field in the document to form vectors. Then I used the k-means driver in mahout for clustering and then the clusterdumper utility to dump the results.
I am having difficulty in understanding the output results from the dumper. I could see the clusters formed with term vectors in those clusters.
But how do I extract the documents from these clusters. I want the result to be the input documents appearing in different clusters.
I also had this problem. The idea is that cluster dumper dumps all your cluster data with points and so on. You have two choices:
modify ClusterDumper.printClusters() method so it will not print all the terms and weights. I have some code like:
String clusterInfo = String.format("Cluster %d (%d) with %d points.\n", value.getId(), clusterCount, value.getNumPoints());
writer.write(clusterInfo);
writer.write('\n');
// list all top terms
if (dictionary != null) {
String topTerms = getTopFeatures(value.getCenter(), dictionary, numTopFeatures);
writer.write("\tTop Terms: ");
writer.write(topTerms);
writer.write('\n');
}
// list all the points in the cluster
List points = clusterIdToPoints.get(value.getId());
if (points != null) {
writer.write("\tCluster points:\n\t");
for (Iterator iterator = points.iterator(); iterator.hasNext();) {
WeightedVectorWritable point = iterator.next();
writer.write(String.valueOf(point.getWeight()));
writer.write(": ");
if (point.getVector() instanceof NamedVector) {
writer.write(((NamedVector) point.getVector()).getName() + " ");
}
}
writer.write('\n');
}
do some grep magic if possible and eliminate all the info about terms and weights.