package iwocs; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import org.graphstream.algorithm.Toolkit; import org.graphstream.graph.BreadthFirstIterator; import org.graphstream.graph.Graph; import org.graphstream.graph.Node; import org.graphstream.graph.implementations.SingleGraph; import org.graphstream.stream.file.FileSource; import org.graphstream.stream.file.FileSourceEdge; /** * App which purpose is to experiment on a real life scaled * interaction network (scientific collaboration). */ public class App { public static void main(String[] args) { Graph g = getNerdsGraph(); int nb_nodes = g.getNodeCount(); int nb_links = g.getEdgeCount(); System.out.format("N: %d\nL: %d\n: %.3f\n: %.3f\nConnected: %b\n: %.3f\n", nb_nodes, nb_links, Toolkit.averageDegree(g), Toolkit.averageClusteringCoefficient(g), Toolkit.isConnected(g), calculateMeanDistanceFromSample(g, 1000) ); exportHashMapDistribution(calculateDistancesDistributionFromSample(g, 1000), "distance_distrib"); } /** * Export the distribution in a simple x\ty file. * * @param distribution the map to write in the file. * @param destFile the path to the file in which we'll write the distribution. */ private static void exportHashMapDistribution(HashMap distribution, String destFile) { try(BufferedWriter w = new BufferedWriter(new FileWriter(new File(destFile)))) { for(Entry entry : distribution.entrySet()) w.write(String.format("%d\t\t%f\n", entry.getKey(), entry.getValue())); } catch(Exception e) { e.printStackTrace(); } } /** * Calculate a mean distance from a sample of nodes from a given graph. * * @param g the graph to analyse. * @param sampleSize number of nodes to include in the analysis. * @return mean distance calculated from the sample. */ public static double calculateMeanDistanceFromSample(Graph g, int sampleSize) { List sampleNodes = Toolkit.randomNodeSet(g, sampleSize); double meanSum = 0; for(Node n : sampleNodes) { System.out.format("\r(%d/%d)", sampleNodes.indexOf(n), sampleSize); double localSum = 0; int nbVisited; BreadthFirstIterator iter = (BreadthFirstIterator)n.getBreadthFirstIterator(); for(nbVisited = 0; iter.hasNext(); nbVisited++) localSum += iter.getDepthOf(iter.next()); meanSum += localSum / nbVisited; } System.out.println(); return meanSum / sampleSize; } /** * Creates a distribution of distances from a random set of nodes from a given * graph of a given size. * * @param g the graph to analyse. * @param sampleSize number of nodes to analyse. * @return the distribution calculated. */ public static HashMap calculateDistancesDistributionFromSample(Graph g, int sampleSize) { List sampleNodes = Toolkit.randomNodeSet(g, sampleSize); HashMap distribution = new HashMap<>(); int i = 0; for(Node n : sampleNodes) { System.out.format("\r(%d/%d)", ++i, sampleSize); BreadthFirstIterator iter = (BreadthFirstIterator)n.getBreadthFirstIterator(); while(iter.hasNext()) { int depth = iter.getDepthOf(iter.next()); Double depthCount = distribution.get(depth); if(depthCount == null) distribution.put(depth, 1.0); else distribution.put(depth, depthCount + 1); } } System.out.println(); Double totalMeasures = distribution.values().stream().reduce(0.0, Double::sum); distribution.forEach((k, v) -> distribution.put(k, v / totalMeasures)); return distribution; } /** * Export degrees distribution of a graph to a given file. * * @param g the graph from which we get the degree distribution. * @param destFile the path to the file in which the distribution will be written. * @param normalized if the values of the distribution will be normalized or not. */ public static void exportDegreeDistribution(Graph g, String destFile, boolean normalized) { int[] degreesDistribution = Toolkit.degreeDistribution(g); double[] convertedDistribution = new double[degreesDistribution.length]; for(int i=0; i < degreesDistribution.length; i++) convertedDistribution[i] = normalized ? (double)degreesDistribution[i] / g.getNodeCount() : (double)degreesDistribution[i]; try(BufferedWriter w = new BufferedWriter(new FileWriter(new File(destFile)))) { for(int i=0; i < convertedDistribution.length; i++) if(convertedDistribution[i] != 0) w.write(String.format("%d\t%f\n", i, convertedDistribution[i])); } catch(Exception e) { e.printStackTrace(); } } public static Graph getNerdsGraph() { Graph g = new SingleGraph("nerds"); FileSource fs = new FileSourceEdge(); fs.addSink(g); try { InputStream stream = App.class.getClassLoader().getResourceAsStream("nerds.txt"); fs.readAll(stream); } catch (IOException e) { e.printStackTrace(); } return g; } }