@Override public Result getResult() { long triangleTripletCount = edgeMetricsHelper.getAccumulator(env, TRIANGLE_TRIPLET_COUNT); long rectangleTripletCount = edgeMetricsHelper.getAccumulator(env, RECTANGLE_TRIPLET_COUNT); long maximumTriangleTriplets = edgeMetricsHelper.getAccumulator(env, MAXIMUM_TRIANGLE_TRIPLETS); long maximumRectangleTriplets = edgeMetricsHelper.getAccumulator(env, MAXIMUM_RECTANGLE_TRIPLETS); // each edge is counted twice, once from each vertex, so must be halved return new Result(triangleTripletCount, rectangleTripletCount, maximumTriangleTriplets, maximumRectangleTriplets); }
@Override public Result getResult() { long vertexCount = vertexMetricsHelper.getAccumulator(env, VERTEX_COUNT); long unidirectionalEdgeCount = vertexMetricsHelper.getAccumulator(env, UNIDIRECTIONAL_EDGE_COUNT); long bidirectionalEdgeCount = vertexMetricsHelper.getAccumulator(env, BIDIRECTIONAL_EDGE_COUNT); long tripletCount = vertexMetricsHelper.getAccumulator(env, TRIPLET_COUNT); long maximumDegree = vertexMetricsHelper.getAccumulator(env, MAXIMUM_DEGREE); long maximumOutDegree = vertexMetricsHelper.getAccumulator(env, MAXIMUM_OUT_DEGREE); long maximumInDegree = vertexMetricsHelper.getAccumulator(env, MAXIMUM_IN_DEGREE); long maximumTriplets = vertexMetricsHelper.getAccumulator(env, MAXIMUM_TRIPLETS); // each edge is counted twice, once from each vertex, so must be halved return new Result(vertexCount, unidirectionalEdgeCount / 2, bidirectionalEdgeCount / 2, tripletCount, maximumDegree, maximumOutDegree, maximumInDegree, maximumTriplets); }
/** * Get the average degree, the average number of in- plus out-edges per vertex. * * <p>A result of {@code Float.NaN} is returned for an empty graph for * which both the number of edges and number of vertices is zero. * * @return average degree */ public double getAverageDegree() { return vertexCount == 0 ? Double.NaN : getNumberOfEdges() / (double) vertexCount; }
@Override public EdgeMetrics<K, VV, EV> run(Graph<K, VV, EV> input) throws Exception { super.run(input); // s, t, (d(s), d(t)) DataSet<Edge<K, Tuple3<EV, Degrees, Degrees>>> edgeDegreesPair = input .run(new EdgeDegreesPair<K, VV, EV>() .setParallelism(parallelism)); // s, d(s), count of (u, v) where deg(u) < deg(v) or (deg(u) == deg(v) and u < v) DataSet<Tuple3<K, Degrees, LongValue>> edgeStats = edgeDegreesPair .flatMap(new EdgeStats<>()) .setParallelism(parallelism) .name("Edge stats") .groupBy(0, 1) .reduceGroup(new ReduceEdgeStats<>()) .setParallelism(parallelism) .name("Reduce edge stats") .groupBy(0) .reduce(new SumEdgeStats<>()) .setCombineHint(CombineHint.HASH) .setParallelism(parallelism) .name("Sum edge stats"); edgeMetricsHelper = new EdgeMetricsHelper<>(); edgeStats .output(edgeMetricsHelper) .setParallelism(parallelism) .name("Edge metrics"); return this; }
@Override public String toPrintableString() { NumberFormat nf = NumberFormat.getInstance(); // format for very small fractional numbers NumberFormat ff = NumberFormat.getInstance(); ff.setMaximumFractionDigits(8); return "vertex count: " + nf.format(vertexCount) + "; edge count: " + nf.format(getNumberOfEdges()) + "; unidirectional edge count: " + nf.format(unidirectionalEdgeCount) + "; bidirectional edge count: " + nf.format(bidirectionalEdgeCount) + "; average degree: " + nf.format(getAverageDegree()) + "; density: " + ff.format(getDensity()) + "; triplet count: " + nf.format(tripletCount) + "; maximum degree: " + nf.format(maximumDegree) + "; maximum out degree: " + nf.format(maximumOutDegree) + "; maximum in degree: " + nf.format(maximumInDegree) + "; maximum triplets: " + nf.format(maximumTriplets); }
@Override public DataSet plan(Graph<K, VV, EV> graph) throws Exception { switch (order.getValue()) { case DIRECTED: vertexMetrics = graph .run(new org.apache.flink.graph.library.metric.directed.VertexMetrics<K, VV, EV>() .setParallelism(parallelism.getValue().intValue())); edgeMetrics = graph .run(new org.apache.flink.graph.library.metric.directed.EdgeMetrics<K, VV, EV>() .setParallelism(parallelism.getValue().intValue())); break; case UNDIRECTED: vertexMetrics = graph .run(new org.apache.flink.graph.library.metric.undirected.VertexMetrics<K, VV, EV>() .setParallelism(parallelism.getValue().intValue())); edgeMetrics = graph .run(new org.apache.flink.graph.library.metric.undirected.EdgeMetrics<K, VV, EV>() .setParallelism(parallelism.getValue().intValue())); break; } return null; }
@Override public GlobalClusteringCoefficient<K, VV, EV> run(Graph<K, VV, EV> input) throws Exception { super.run(input); triangleCount = new Count<>(); DataSet<TriangleListing.Result<K>> triangles = input .run(new TriangleListing<K, VV, EV>() .setSortTriangleVertices(false) .setParallelism(parallelism)); triangleCount.run(triangles); vertexMetrics = new VertexMetrics<K, VV, EV>() .setParallelism(parallelism); input.run(vertexMetrics); return this; }
@Override public void close() throws IOException { addAccumulator(TRIANGLE_TRIPLET_COUNT, new LongCounter(triangleTripletCount)); addAccumulator(RECTANGLE_TRIPLET_COUNT, new LongCounter(rectangleTripletCount)); addAccumulator(MAXIMUM_TRIANGLE_TRIPLETS, new LongMaximum(maximumTriangleTriplets)); addAccumulator(MAXIMUM_RECTANGLE_TRIPLETS, new LongMaximum(maximumRectangleTriplets)); } }
@Override public void close() throws IOException { addAccumulator(VERTEX_COUNT, new LongCounter(vertexCount)); addAccumulator(UNIDIRECTIONAL_EDGE_COUNT, new LongCounter(unidirectionalEdgeCount)); addAccumulator(BIDIRECTIONAL_EDGE_COUNT, new LongCounter(bidirectionalEdgeCount)); addAccumulator(TRIPLET_COUNT, new LongCounter(tripletCount)); addAccumulator(MAXIMUM_DEGREE, new LongMaximum(maximumDegree)); addAccumulator(MAXIMUM_OUT_DEGREE, new LongMaximum(maximumOutDegree)); addAccumulator(MAXIMUM_IN_DEGREE, new LongMaximum(maximumInDegree)); addAccumulator(MAXIMUM_TRIPLETS, new LongMaximum(maximumTriplets)); } }
@Override public Result getResult() { // each triangle must be counted from each of the three vertices // as each triplet is counted in this manner long numberOfTriangles = 3 * triangleCount.getResult(); return new Result(vertexMetrics.getResult().getNumberOfTriplets(), numberOfTriangles); }
@Override public VertexMetrics<K, VV, EV> run(Graph<K, VV, EV> input) throws Exception { super.run(input); DataSet<Vertex<K, Degrees>> vertexDegree = input .run(new VertexDegrees<K, VV, EV>() .setIncludeZeroDegreeVertices(includeZeroDegreeVertices) .setParallelism(parallelism)); vertexMetricsHelper = new VertexMetricsHelper<>(); vertexDegree .output(vertexMetricsHelper) .name("Vertex metrics"); return this; }
@Override public String toString() { return toPrintableString(); }
@Override public String toString() { return toPrintableString(); }
@Override public Result getResult() { long triangleTripletCount = edgeMetricsHelper.getAccumulator(env, TRIANGLE_TRIPLET_COUNT); long rectangleTripletCount = edgeMetricsHelper.getAccumulator(env, RECTANGLE_TRIPLET_COUNT); long maximumTriangleTriplets = edgeMetricsHelper.getAccumulator(env, MAXIMUM_TRIANGLE_TRIPLETS); long maximumRectangleTriplets = edgeMetricsHelper.getAccumulator(env, MAXIMUM_RECTANGLE_TRIPLETS); // each edge is counted twice, once from each vertex, so must be halved return new Result(triangleTripletCount, rectangleTripletCount, maximumTriangleTriplets, maximumRectangleTriplets); }
@Override public Result getResult() { long vertexCount = vertexMetricsHelper.getAccumulator(env, VERTEX_COUNT); long unidirectionalEdgeCount = vertexMetricsHelper.getAccumulator(env, UNIDIRECTIONAL_EDGE_COUNT); long bidirectionalEdgeCount = vertexMetricsHelper.getAccumulator(env, BIDIRECTIONAL_EDGE_COUNT); long tripletCount = vertexMetricsHelper.getAccumulator(env, TRIPLET_COUNT); long maximumDegree = vertexMetricsHelper.getAccumulator(env, MAXIMUM_DEGREE); long maximumOutDegree = vertexMetricsHelper.getAccumulator(env, MAXIMUM_OUT_DEGREE); long maximumInDegree = vertexMetricsHelper.getAccumulator(env, MAXIMUM_IN_DEGREE); long maximumTriplets = vertexMetricsHelper.getAccumulator(env, MAXIMUM_TRIPLETS); // each edge is counted twice, once from each vertex, so must be halved return new Result(vertexCount, unidirectionalEdgeCount / 2, bidirectionalEdgeCount / 2, tripletCount, maximumDegree, maximumOutDegree, maximumInDegree, maximumTriplets); }
/** * Get the density, the ratio of actual to potential edges between vertices. * * <p>A result of {@code Float.NaN} is returned for a graph with fewer than * two vertices for which the number of edges is zero. * * @return density */ public double getDensity() { return vertexCount <= 1 ? Double.NaN : getNumberOfEdges() / (double) (vertexCount * (vertexCount - 1)); }
@Override public Result getResult() { long triangleTripletCount = edgeMetricsHelper.getAccumulator(env, TRIANGLE_TRIPLET_COUNT); long rectangleTripletCount = edgeMetricsHelper.getAccumulator(env, RECTANGLE_TRIPLET_COUNT); long maximumTriangleTriplets = edgeMetricsHelper.getAccumulator(env, MAXIMUM_TRIANGLE_TRIPLETS); long maximumRectangleTriplets = edgeMetricsHelper.getAccumulator(env, MAXIMUM_RECTANGLE_TRIPLETS); // each edge is counted twice, once from each vertex, so must be halved return new Result(triangleTripletCount, rectangleTripletCount, maximumTriangleTriplets, maximumRectangleTriplets); }
/** * Get the average degree, the average number of in- plus out-edges per vertex. * * A result of {@code Float.NaN} is returned for an empty graph for * which both the number of edges and number of vertices is zero. * * @return average degree */ public double getAverageDegree() { return vertexCount == 0 ? Double.NaN : getNumberOfEdges() / (double)vertexCount; }
@Override public Result getResult() { long triangleTripletCount = edgeMetricsHelper.getAccumulator(env, TRIANGLE_TRIPLET_COUNT); long rectangleTripletCount = edgeMetricsHelper.getAccumulator(env, RECTANGLE_TRIPLET_COUNT); long maximumTriangleTriplets = edgeMetricsHelper.getAccumulator(env, MAXIMUM_TRIANGLE_TRIPLETS); long maximumRectangleTriplets = edgeMetricsHelper.getAccumulator(env, MAXIMUM_RECTANGLE_TRIPLETS); // each edge is counted twice, once from each vertex, so must be halved return new Result(triangleTripletCount, rectangleTripletCount, maximumTriangleTriplets, maximumRectangleTriplets); }
/** * Get the density, the ratio of actual to potential edges between vertices. * * A result of {@code Float.NaN} is returned for a graph with fewer than * two vertices for which the number of edges is zero. * * @return density */ public double getDensity() { return vertexCount <= 1 ? Double.NaN : getNumberOfEdges() / (double)(vertexCount*(vertexCount-1)); }