### * Added new package org.graphstream.algorithm.util

```* Moved FibonacciHeap there
* Added a class RandomTools with methods generating random stuff
* On the fly, added in Toolkit several useful methods for picking random
subsets of nodes/edges```
parent 369ce4d2
 ... ... @@ -35,6 +35,7 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.Stack; import org.graphstream.algorithm.util.FibonacciHeap; import org.graphstream.graph.Edge; import org.graphstream.graph.Graph; import org.graphstream.graph.Node; ... ...
 ... ... @@ -31,6 +31,7 @@ package org.graphstream.algorithm; import java.util.*; import org.graphstream.algorithm.util.RandomTools; import org.graphstream.graph.*; import org.graphstream.stream.GraphReplay; import org.graphstream.ui.layout.Layout; ... ... @@ -1347,9 +1348,9 @@ public class Toolkit extends * The adjacency matrix of a graph is a n times n matrix * {@code a}, where n is the number of nodes of the graph. The * element {@code a[i][j]} of this matrix is equal to the number of edges * from the node {@code graph.getNode(i)} to the node {@code * graph.getNode(j)}. An undirected edge between i-th and j-th node is * counted twice: in {@code a[i][j]} and in {@code a[j][i]}. * from the node {@code graph.getNode(i)} to the node * {@code graph.getNode(j)}. An undirected edge between i-th and j-th node * is counted twice: in {@code a[i][j]} and in {@code a[j][i]}. * * @param graph * A graph. ... ... @@ -1381,9 +1382,9 @@ public class Toolkit extends * The adjacency matrix of a graph is a n times n matrix * {@code a}, where n is the number of nodes of the graph. The * element {@code a[i][j]} of this matrix is equal to the number of edges * from the node {@code graph.getNode(i)} to the node {@code * graph.getNode(j)}. An undirected edge between i-th and j-th node is * counted twice: in {@code a[i][j]} and in {@code a[j][i]}. * from the node {@code graph.getNode(i)} to the node * {@code graph.getNode(j)}. An undirected edge between i-th and j-th node * is counted twice: in {@code a[i][j]} and in {@code a[j][i]}. * * @param graph * A graph ... ... @@ -1407,12 +1408,12 @@ public class Toolkit extends * number of edges of the graph. The coefficients {@code a[i][j]} of this * matrix have the following values: *
*
• -1 if {@code graph.getEdge(j)} is directed and {@code * graph.getNode(i)} is its source.
• *
• 1 if {@code graph.getEdge(j)} is undirected and {@code * graph.getNode(i)} is its source.
• *
• 1 if {@code graph.getNode(i)} is the target of {@code * graph.getEdge(j)}.
• *
• -1 if {@code graph.getEdge(j)} is directed and * {@code graph.getNode(i)} is its source.
• *
• 1 if {@code graph.getEdge(j)} is undirected and * {@code graph.getNode(i)} is its source.
• *
• 1 if {@code graph.getNode(i)} is the target of * {@code graph.getEdge(j)}.
• *
• 0 otherwise. *
* In the special case when the j-th edge is a loop connecting the i-th node ... ... @@ -1450,12 +1451,12 @@ public class Toolkit extends * number of edges of the graph. The coefficients {@code a[i][j]} of this * matrix have the following values: *
*
• -1 if {@code graph.getEdge(j)} is directed and {@code * graph.getNode(i)} is its source.
• *
• 1 if {@code graph.getEdge(j)} is undirected and {@code * graph.getNode(i)} is its source.
• *
• 1 if {@code graph.getNode(i)} is the target of {@code * graph.getEdge(j)}.
• *
• -1 if {@code graph.getEdge(j)} is directed and * {@code graph.getNode(i)} is its source.
• *
• 1 if {@code graph.getEdge(j)} is undirected and * {@code graph.getNode(i)} is its source.
• *
• 1 if {@code graph.getNode(i)} is the target of * {@code graph.getEdge(j)}.
• *
• 0 otherwise.
• *
* In the special case when the j-th edge is a loop connecting the i-th node ... ... @@ -1523,4 +1524,190 @@ public class Toolkit extends public static void computeLayout(Graph g) { computeLayout(g, new SpringBox(), 0.99); } /** * Returns a random subset of nodes of fixed size. Each node has the same * chance to be chosen. * * @param graph * A graph. * @param k * The size of the subset. * @return A random subset of nodes of size k. * @throws IllegalArgumentException * If k is negative or greater than the number of * nodes. * @complexity O(k) */ public static List randomNodeSet(Graph graph, int k) { return randomNodeSet(graph, k, new Random()); } /** * Returns a random subset of nodes of fixed size. Each node has the same * chance to be chosen. * * @param graph * A graph. * @param k * The size of the subset. * @param random * A source of randomness. * @return A random subset of nodes of size k. * @throws IllegalArgumentException * If k is negative or greater than the number of * nodes. * @complexity O(k) */ public static List randomNodeSet(Graph graph, int k, Random random) { if (k < 0 || k > graph.getNodeCount()) throw new IllegalArgumentException("k must be between 0 and " + graph.getNodeCount()); Set subset = RandomTools.randomKsubset(graph.getNodeCount(), k, null, random); List result = new ArrayList(subset.size()); for (int i : subset) result.add(graph. getNode(i)); return result; } /** * Returns a random subset of nodes. Each node is chosen with given * probability. * * @param graph * A graph. * @param p * The probability to choose each node. * @return A random subset of nodes. * @throws IllegalArgumentException * If p is negative or greater than one. * @complexity In average O(n * p), where n is the * number of nodes. */ public static List randomNodeSet(Graph graph, double p) { return randomNodeSet(graph, p, new Random()); } /** * Returns a random subset of nodes. Each node is chosen with given * probability. * * @param graph * A graph. * @param p * The probability to choose each node. * @param random * A source of randomness. * @return A random subset of nodes. * @throws IllegalArgumentException * If p is negative or greater than one. * @complexity In average O(n * p), where n is the * number of nodes. */ public static List randomNodeSet(Graph graph, double p, Random random) { if (p < 0 || p > 1) throw new IllegalArgumentException("p must be between 0 and 1"); Set subset = RandomTools.randomPsubset(graph.getNodeCount(), p, null, random); List result = new ArrayList(subset.size()); for (int i : subset) result.add(graph. getNode(i)); return result; } /** * Returns a random subset of edges of fixed size. Each edge has the same * chance to be chosen. * * @param graph * A graph. * @param k * The size of the subset. * @return A random subset of edges of size k. * @throws IllegalArgumentException * If k is negative or greater than the number of * edges. * @complexity O(k) */ public static List randomEdgeSet(Graph graph, int k) { return randomEdgeSet(graph, k, new Random()); } /** * Returns a random subset of edges of fixed size. Each edge has the same * chance to be chosen. * * @param graph * A graph. * @param k * The size of the subset. * @param random * A source of randomness. * @return A random subset of edges of size k. * @throws IllegalArgumentException * If k is negative or greater than the number of * edges. * @complexity O(k) */ public static List randomEdgeSet(Graph graph, int k, Random random) { if (k < 0 || k > graph.getEdgeCount()) throw new IllegalArgumentException("k must be between 0 and " + graph.getEdgeCount()); Set subset = RandomTools.randomKsubset(graph.getEdgeCount(), k, null, random); List result = new ArrayList(subset.size()); for (int i : subset) result.add(graph. getEdge(i)); return result; } /** * Returns a random subset of edges. Each edge is chosen with given * probability. * * @param graph * A graph. * @param p * The probability to choose each edge. * @return A random subset of edges. * @throws IllegalArgumentException * If p is negative or greater than one. * @complexity In average O(m * p), where m is the * number of edges. */ public static List randomEdgeSet(Graph graph, double p) { return randomEdgeSet(graph, p, new Random()); } /** * Returns a random subset of edges. Each edge is chosen with given * probability. * * @param graph * A graph. * @param p * The probability to choose each edge. * @param random * A source of randomness. * @return A random subset of edges. * @throws IllegalArgumentException * If p is negative or greater than one. * @complexity In average O(m * p), where m is the * number of edges. */ public static List randomEdgeSet(Graph graph, double p, Random random) { if (p < 0 || p > 1) throw new IllegalArgumentException("p must be between 0 and 1"); Set subset = RandomTools.randomPsubset(graph.getEdgeCount(), p, null, random); List result = new ArrayList(subset.size()); for (int i : subset) result.add(graph. getEdge(i)); return result; } }
 ... ... @@ -27,7 +27,7 @@ * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms. */ package org.graphstream.algorithm; package org.graphstream.algorithm.util; import java.util.ArrayList; ... ...
 package org.graphstream.algorithm.util; import java.util.HashSet; import java.util.Random; import java.util.Set; /** * This class provides several static methods for generating random numbers and * sets */ public class RandomTools { /** * Returns a pseudorandom number drawn from exponential distribution with * mean 1. * * Uses the von Neumann's exponential generator. * * @param rnd * source of randomness * @return a pseudorandom number drawn from exponential distribution with * mean 1. * @complexity O(1) average complexity. The expected number of uniformly * distributed numbers used is e^2 / (e - 1) * */ public static double exponential(Random rnd) { double y, w, u; int z, k; z = -1; do { w = y = rnd.nextDouble(); k = 1; while (true) { u = rnd.nextDouble(); if (u > w) break; w = u; k++; } z++; } while ((k & 1) == 0); return z + y; } /** * Returns a pseudorandom number drawn from binomial distribution B(n, p). * * Uses a simple waiting time method based on exponential distribution. * * @param n * number of tries * @param p * success probability * @param rnd * source of randomness * @return a pseudorandom number drawn from binomial distribution * @complexity Average complexity O(np) */ public static int binomial(int n, double p, Random rnd) { double q = -Math.log(1 - p); int x = 0; double s = 0; do { s += exponential(rnd) / (n - x); x++; } while (s <= q); return x - 1; } /** * Generates a pseudorandom subset of size k of the set {0, 1,...,n - 1}. * Each element has the same chance to be chosen. * * Uses Floyd's method of subset generation with only k iterations. Note * that the quality of this generator is limited by Java's random generator. * Java stores the internal state in 48 bits, so in the best case we can * only generate 2^48 different subsets. * * @param n * the size of the initial set * @param k * the size of the generated set * @param subset * if not null, this set is cleared and the result is stored * here. This avoids creations of sets at each call of this * method * @param rnd * source of randomness * @return a pseudorandom subset of size k of the set {0, 1,...,n} * @complexity Depends on the set implementation. If add and lookup * operations take constant time, the complexity is O(k) */ public static Set randomKsubset(int n, int k, Set subset, Random rnd) { if (subset == null) subset = new HashSet(4 * k / 3 + 1); else subset.clear(); for (int i = n - k; i < n; i++) { int j = rnd.nextInt(i + 1); subset.add(subset.contains(j) ? i : j); } return subset; } /** * Generates a pseudorandom subset of the set {0, 1,...,n - 1}. Each element * is chosen with probability p. * * @param n * the size of the initial set * @param p * the probability to choose each element * @param subset * if not null, this set is cleared and the result is stored * here. This avoids creations of sets at each call of this * method * @param rnd * source of randomness * @return a pseudorandom subset of the set {0, 1,...,n}. * @complexity Depends on the set implementation. If add and lookup * operations take constant time, the complexity is O(np) */ public static Set randomPsubset(int n, double p, Set subset, Random rnd) { return randomKsubset(n, binomial(n, p, rnd), subset, rnd); } }