package edu.albany.graph.neo4j; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Iterator; import org.neo4j.graphalgo.CommonEvaluators; import org.neo4j.graphalgo.CostEvaluator; import org.neo4j.graphalgo.GraphAlgoFactory; import org.neo4j.graphalgo.PathFinder; import org.neo4j.graphalgo.WeightedPath; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.RelationshipExpander; import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.ReturnableEvaluator; import org.neo4j.graphdb.StopEvaluator; import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.Traverser; import org.neo4j.graphdb.Traverser.Order; import org.neo4j.graphdb.traversal.Evaluators; import org.neo4j.graphdb.traversal.TraversalDescription; import org.neo4j.kernel.EmbeddedGraphDatabase; import org.neo4j.kernel.Traversal; import org.neo4j.kernel.Uniqueness; public class Benchmark { private static enum RelTypes implements RelationshipType { FOLLOWS } public static void main(String[] args) throws IOException { // String path = "/usr/java/gstar/test.dat"; // Initilize graph EmbeddedGraphDatabase graphDatabase = new EmbeddedGraphDatabase("/usr/java/neo4j-community-1.6.1/galaxy"); Transaction tr = graphDatabase.beginTx(); System.out.println("Graph Generation Started..."); generateGraph(graphDatabase); System.out.println("Graph Generation Finished!\n"); System.out.println("Graph Printing Started..."); // printGraph(); System.out.println("Graph Printing Finished...\n"); System.out.println("Degree Distribution Calculator Started..."); degreeDistributionCalculator(graphDatabase); System.out.println("Degree Distribution Calculator Finished...\n"); System.out.println("Single Source Shortest Path Calculator Started..."); singleSourceShortestPathCalculator(graphDatabase); System.out.println("Single Source Shortest Path Calculator Finished...\n"); System.out.println("Local Clustering Coefficient Calculator Started..."); localClusteringCoefficientCalculator(graphDatabase); System.out.println("Local Clustering Coefficient Calculator Finished..."); tr.success(); tr.finish(); graphDatabase.shutdown(); } private static void localClusteringCoefficientCalculator(EmbeddedGraphDatabase graphDatabase) { TraversalDescription followers = Traversal.description().depthFirst().relationships(RelTypes.FOLLOWS, Direction.OUTGOING) .uniqueness(Uniqueness.RELATIONSHIP_GLOBAL).evaluator(Evaluators.atDepth(1)); for (Node node : graphDatabase.getAllNodes()) { if (node.getId() != 0) { int countOfPathsBetweenNeighbour = 0; int countOfNeighbourNodes = 0; Iterator neighbourSource = followers.traverse(node).nodes().iterator(); while (neighbourSource.hasNext()) { countOfNeighbourNodes++; Node sourceNode = neighbourSource.next(); Iterator sourceAdjIter = followers.traverse(sourceNode).nodes().iterator(); while (sourceAdjIter.hasNext()) { Node sourceAdjNode = sourceAdjIter.next(); // Undirected paths between neighbours TraversalDescription followersSpecialForA = Traversal.description().depthFirst() .relationships(RelTypes.FOLLOWS, Direction.BOTH).uniqueness(Uniqueness.RELATIONSHIP_GLOBAL) .evaluator(Evaluators.atDepth(1)); Iterator neighbourDestination = followersSpecialForA.traverse(node).nodes().iterator(); while (neighbourDestination.hasNext()) { Node destinationNode = neighbourDestination.next(); if (sourceAdjNode.getProperty("id_x") == destinationNode.getProperty("id_x")) { countOfPathsBetweenNeighbour++; break; } } } } System.out.println("For S : " + node.getProperty("id_x") + " there are " + countOfNeighbourNodes + " neighbours with " + countOfPathsBetweenNeighbour + " external paths=> LCC " + ((double) countOfPathsBetweenNeighbour / ((countOfNeighbourNodes * (countOfNeighbourNodes - 1)) / 2))); } } } private static void singleSourceShortestPathCalculator(EmbeddedGraphDatabase graphDatabase) { RelationshipExpander expander = Traversal.expanderForTypes(RelTypes.FOLLOWS, Direction.OUTGOING); CostEvaluator costEvaluator = CommonEvaluators.doubleCostEvaluator("cost"); PathFinder dijkstraPathFinder = GraphAlgoFactory.dijkstra(expander, costEvaluator); for (Node nodeSource : graphDatabase.getAllNodes()) { HashMap ssspMap = new HashMap(); for (Node nodeDestination : graphDatabase.getAllNodes()) { if ((nodeSource.getId() != 0) && (nodeDestination.getId() != 0) && nodeSource.getId() != nodeDestination.getId()) { int distance = 0; WeightedPath path = dijkstraPathFinder.findSinglePath(nodeSource, nodeDestination); if (path != null) { for (Node node : path.nodes()) { distance++; // System.out.println( node.getProperty( "id_x" ) ); } // distance do not count first row distance = distance - 1; System.out.println("From S : " + nodeSource.getProperty("id_x") + " to D : " + nodeDestination.getProperty("id_x") + " with cost " + distance); if (ssspMap.get(distance) != null) { ssspMap.put(distance, ssspMap.get(distance) + 1); } else { ssspMap.put(distance, 1); } } } } for (Integer i : ssspMap.keySet()) { System.out.println("In outgoing direction on distance " + i + " there are " + ssspMap.get(i) + " nodes"); } System.out.println(); } } public static void generateGraph(EmbeddedGraphDatabase graphDatabase) throws IOException { // https://github.com/neo4j-examples/java-dijkstra/blob/master/src/main/java/org/neo4j/examples/dijkstra/ExampleGraphService.java String path = "/usr/java/gstar/galaxy.dat"; // String path = "/usr/java/gstar/test.dat"; HashMap nodeListMap = new HashMap(); // Parse from file File file = new File(path); FileInputStream fis = new FileInputStream(file); BufferedReader br = new BufferedReader(new InputStreamReader(fis)); StringBuffer sb = new StringBuffer(); String line = br.readLine(); sb.append(line); int edgeCount = 0; int sourceVertexId = 0; Node sourceVertex = null; while (line != null) { String[] arr = line.split(" "); if (arr.length > 1) { if (edgeCount == 0) { sourceVertexId = Integer.valueOf(arr[0]); edgeCount = Integer.valueOf(arr[1]); System.out.println("vertexId = " + sourceVertexId + ", edge count = " + edgeCount); if (nodeListMap.get(sourceVertexId) == null) { sourceVertex = graphDatabase.createNode(); sourceVertex.setProperty("id_x", sourceVertexId); nodeListMap.put(sourceVertexId, sourceVertex.getId()); } else { sourceVertex = graphDatabase.getNodeById(nodeListMap.get(sourceVertexId)); } } else { int destinationVertexId = Integer.valueOf(arr[1]); System.out.println("Source Vertex is " + sourceVertexId + ", destination vertex is " + destinationVertexId); Node destinationVertex = null; if (nodeListMap.get(destinationVertexId) == null) { destinationVertex = graphDatabase.createNode(); destinationVertex.setProperty("id_x", destinationVertexId); nodeListMap.put(destinationVertexId, destinationVertex.getId()); } else { destinationVertex = graphDatabase.getNodeById(nodeListMap.get(destinationVertexId)); } Relationship relationship = sourceVertex.createRelationshipTo(destinationVertex, RelTypes.FOLLOWS); relationship.setProperty("cost", 1); edgeCount--; } } line = br.readLine(); } } private static void degreeDistributionCalculator(EmbeddedGraphDatabase graphDatabase) { // TraversalDescription followers = Traversal.description().depthFirst() // .relationships(RelTypes.FOLLOWS, // Direction.OUTGOING).uniqueness(Uniqueness.RELATIONSHIP_GLOBAL); TraversalDescription followers = Traversal.description().depthFirst().relationships(RelTypes.FOLLOWS, Direction.BOTH) .uniqueness(Uniqueness.RELATIONSHIP_GLOBAL).evaluator(Evaluators.atDepth(1)); int degreeCount = 0; HashMap degree = new HashMap(); int nodeCount = 0; for (Node node : graphDatabase.getAllNodes()) { if (node.getId() != 0) { System.out.println("From S : " + node.getProperty("id_x")); Iterator iter = followers.traverse(node).nodes().iterator(); // Iterator iter = // followers.traverse(graphDatabase.getNodeById(i)).iterator(); while (iter.hasNext()) { System.out.println("To D : " + iter.next().getProperty("id_x")); degreeCount++; } // do not count itself // j=j-1; System.out.println("Count of Neighbours : " + degreeCount + "\n"); if (degree.get(degreeCount) != null) { degree.put(degreeCount, degree.get(degreeCount) + 1); } else { degree.put(degreeCount, 1); } nodeCount++; degreeCount = 0; } } for (Integer i : degree.keySet()) { System.out.println("In outgoing degree " + i + " there are " + degree.get(i) + " nodes, P(" + i + ")" + (((double) degree.get(i)) / ((double) nodeCount))); } // String output = ""; // for (Path position : // Traversal.description().depthFirst().relationships(RelTypes.FOLLOWS) // .relationships(RelTypes.FOLLOWS, // Direction.INCOMING).evaluator(Evaluators.toDepth(5)).traverse(sourceVertex)) // { // output += position + "\n"; // } // for (Node currentNode : followers.traverse(sourceVertex).nodes()) { // output += currentNode.getProperty("id_x") + "\n"; // } // System.out.println(output); } private static void degreeDistributionCalculatorXXX(EmbeddedGraphDatabase graphDatabase) { // TraversalDescription followers = Traversal.description().depthFirst() // .relationships(RelTypes.FOLLOWS, // Direction.OUTGOING).uniqueness(Uniqueness.RELATIONSHIP_GLOBAL); TraversalDescription followers = Traversal.description().depthFirst().relationships(RelTypes.FOLLOWS, Direction.OUTGOING) .uniqueness(Uniqueness.RELATIONSHIP_GLOBAL).evaluator(Evaluators.atDepth(1)); int j = 0; HashMap degree = new HashMap(); for (int i = 1; i < 7; i++) { System.out.println("From S : " + i); Iterator iter = followers.traverse(graphDatabase.getNodeById(i)).nodes().iterator(); // Iterator iter = // followers.traverse(graphDatabase.getNodeById(i)).iterator(); while (iter.hasNext()) { System.out.println("To T : " + iter.next().getProperty("id_x")); j++; } // do not count itself // j=j-1; System.out.println("Count of Neighbours : " + j + "\n"); if (degree.get(j) != null) { degree.put(j, degree.get(j) + 1); } else { degree.put(j, 1); } j = 0; } for (Integer i : degree.keySet()) { System.out.println("In degree " + i + " there are " + degree.get(i) + " nodes"); } } public static void printGraph() { EmbeddedGraphDatabase graphDatabase = new EmbeddedGraphDatabase("/usr/java/neo4j-community-1.6.1/galaxy"); Transaction tr = graphDatabase.beginTx(); for (Node sourceVertex : graphDatabase.getAllNodes()) { Traverser traverser = sourceVertex.traverse(Order.BREADTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL_BUT_START_NODE, RelTypes.FOLLOWS, Direction.OUTGOING); for (Node node : traverser) { node.getId(); if (sourceVertex.getId() != 0) { System.out.println("Source Vertex is " + sourceVertex.getProperty("id_x")); Node[] nodeList = sourceVertex.getRelationships(RelTypes.FOLLOWS).iterator().next().getNodes(); for (Node destinationVertex : nodeList) { System.out.println("Source Vertex is " + sourceVertex.getProperty("id_x") + " at depth " + traverser.currentPosition().depth() + ", destination vertex is " + destinationVertex.getProperty("id_x")); } } } } tr.success(); tr.finish(); } }