public static TemporalNetwork GetTestNetwork_weighted_2() { TemporalNetwork temporal_net = new TemporalNetwork(); temporal_net.AddTemporalEdge(1, "a", "b", 2); temporal_net.AddTemporalEdge(2, "b", "c", 2); temporal_net.AddTemporalEdge(4, "a", "b"); temporal_net.AddTemporalEdge(5, "b", "a"); return(temporal_net); }
/// <summary> /// Creates a random temporal network by shuffling the edges present in an original weighted network /// </summary> /// <param name="net">The weighted network to draw the microstate from</param> /// <param name="length">The length of the sequence in terms of the number of time-stamped interactions</param> /// <returns></returns> public static TemporalNetwork ShuffleEdges(TemporalNetwork net, int length=0, int precision = 1000) { // If no length is specified (i.e. length has the default value of 0), use the length of the original network length = length > 0 ? length : (int) net.AggregateNetwork.CumulativeWeight; int lcm = 1; foreach (var twopath in net.TwoPathWeights.Keys) { int whole, numerator, denominator; MathHelper.RoundToMixedFraction(net.TwoPathWeights[twopath], precision, out whole, out numerator, out denominator); lcm = MathHelper.LCM(lcm, denominator); } // Collect edges in two sampling sets for in and outgoing edges of two paths List<Tuple<string, string>> in_edges = new List<Tuple<string, string>>(); List<Tuple<string, string>> out_edges = new List<Tuple<string, string>>(); string[] split = null; foreach (var twopath in net.TwoPathWeights.Keys) for (int k = 0; k < Math.Round(net.TwoPathWeights[twopath] * lcm); k++) { split = twopath.Split(','); in_edges.Add(new Tuple<string,string>(split[0],split[1])); out_edges.Add(new Tuple<string, string>(split[1], split[2])); } TemporalNetwork output = new TemporalNetwork(); int l = 0; while (l < length) { // Draw edges uniformly at random and add them to temporal network var edge1 = in_edges.ElementAt(rand.Next(in_edges.Count)); Tuple<string,string> edge2 = null; while (edge2 == null) { edge2 = out_edges.ElementAt(rand.Next(out_edges.Count)); if(edge1.Item2 != edge2.Item1) edge2 = null; } // Add to the output network output.AddTemporalEdge(l++, edge1.Item1, edge1.Item2); output.AddTemporalEdge(l++, edge2.Item1, edge2.Item2); } return output; }
public void AddTemporalEdgeTest() { TemporalNetwork target = new TemporalNetwork(); target.AddTemporalEdge(0, "a", "b"); Assert.IsTrue(target[0].Contains(new Tuple <string, string>("a", "b"))); }
public void FromEdgeSequenceTest() { List <Tuple <string, string> > sequence = new List <Tuple <string, string> >(); sequence.Add(new Tuple <string, string>("a", "b")); sequence.Add(new Tuple <string, string>("b", "c")); TemporalNetwork expected = new TemporalNetwork(); expected.AddTemporalEdge(0, "a", "b"); expected.AddTemporalEdge(1, "b", "c"); TemporalNetwork actual; actual = TemporalNetwork.FromEdgeSequence(sequence); Assert.AreEqual(expected, actual); }
/// <summary> /// Returns a second test network /// </summary> /// <returns></returns> public static TemporalNetwork GetTestNetwork2() { TemporalNetwork temporal_net = new TemporalNetwork(); temporal_net.AddTemporalEdge(1, "a", "b"); temporal_net.AddTemporalEdge(2, "b", "c"); temporal_net.AddTemporalEdge(2, "d", "c"); temporal_net.AddTemporalEdge(3, "c", "a"); temporal_net.AddTemporalEdge(3, "c", "b"); temporal_net.AddTemporalEdge(3, "c", "d"); return temporal_net; }
/// <summary> /// Returns a second test network /// </summary> /// <returns></returns> public static TemporalNetwork GetTestNetwork2() { TemporalNetwork temporal_net = new TemporalNetwork(); temporal_net.AddTemporalEdge(1, "a", "b"); temporal_net.AddTemporalEdge(2, "b", "c"); temporal_net.AddTemporalEdge(2, "d", "c"); temporal_net.AddTemporalEdge(3, "c", "a"); temporal_net.AddTemporalEdge(3, "c", "b"); temporal_net.AddTemporalEdge(3, "c", "d"); return(temporal_net); }
/// <summary> /// Returns a test network suitable for testing the AggregateWindow method /// </summary> /// <returns></returns> public static TemporalNetwork GetTestNetwork3() { TemporalNetwork temporal_net = new TemporalNetwork(); temporal_net.AddTemporalEdge(1, "a", "b"); temporal_net.AddTemporalEdge(2, "a", "c"); temporal_net.AddTemporalEdge(7, "c", "e"); temporal_net.AddTemporalEdge(8, "c", "g"); temporal_net.AddTemporalEdge(9, "g", "f"); temporal_net.AddTemporalEdge(10, "f", "h"); return(temporal_net); }
public static TemporalNetwork GetTestNetwork_weighted_2() { TemporalNetwork temporal_net = new TemporalNetwork(); temporal_net.AddTemporalEdge(1, "a", "b", 2); temporal_net.AddTemporalEdge(2, "b", "c", 2); temporal_net.AddTemporalEdge(4, "a", "b"); temporal_net.AddTemporalEdge(5, "b", "a"); return temporal_net; }
/// <summary> /// Returns a test network in which node B should have betweenness preference 0 /// </summary> /// <returns></returns> public static TemporalNetwork GetTestNetwork6() { TemporalNetwork temporal_net = new TemporalNetwork(); // Create sequence based on edges in edge graph // two-paths ending in (a,b) temporal_net.AddTemporalEdge(1, "A", "B"); temporal_net.AddTemporalEdge(2, "B", "C"); temporal_net.AddTemporalEdge(3, "A", "B"); temporal_net.AddTemporalEdge(4, "B", "C"); // two-paths ending in (b,a) temporal_net.AddTemporalEdge(5, "D", "B"); temporal_net.AddTemporalEdge(6, "B", "A"); temporal_net.AddTemporalEdge(7, "C", "B"); temporal_net.AddTemporalEdge(8, "B", "D"); temporal_net.AddTemporalEdge(9, "X", "Y"); // two-paths ending in (b,c) temporal_net.AddTemporalEdge(10, "D", "B"); temporal_net.AddTemporalEdge(11, "B", "A"); // two-paths ending in (c,b) temporal_net.AddTemporalEdge(12, "C", "B"); temporal_net.AddTemporalEdge(13, "B", "D"); temporal_net.AddTemporalEdge(14, "C", "B"); temporal_net.AddTemporalEdge(15, "B", "D"); temporal_net.AddTemporalEdge(16, "X", "Y"); temporal_net.AddTemporalEdge(17, "D", "B"); temporal_net.AddTemporalEdge(18, "B", "A"); temporal_net.AddTemporalEdge(19, "X", "Y"); temporal_net.AddTemporalEdge(20, "A", "B"); temporal_net.AddTemporalEdge(21, "B", "C"); temporal_net.AddTemporalEdge(19, "A", "B"); temporal_net.AddTemporalEdge(20, "B", "A"); return temporal_net; }
/// <summary> /// Returns a test network /// </summary> /// <returns></returns> public static TemporalNetwork GetTestNetwork() { TemporalNetwork temporal_net = new TemporalNetwork(); // Add edges according to two paths temporal_net.AddTemporalEdge(1, "c", "e"); temporal_net.AddTemporalEdge(2, "e", "f"); temporal_net.AddTemporalEdge(3, "a", "e"); temporal_net.AddTemporalEdge(4, "e", "g"); temporal_net.AddTemporalEdge(5, "c", "e"); temporal_net.AddTemporalEdge(6, "e", "f"); temporal_net.AddTemporalEdge(7, "a", "e"); temporal_net.AddTemporalEdge(8, "e", "g"); temporal_net.AddTemporalEdge(9, "c", "e"); temporal_net.AddTemporalEdge(10, "e", "f"); // Note that the next added edge additionally continues a two-path e -> f -> e temporal_net.AddTemporalEdge(11, "f", "e"); temporal_net.AddTemporalEdge(12, "e", "b"); // An additional edge that should be filtered during preprocessing ... temporal_net.AddTemporalEdge(13, "e", "b"); // And one case where we have multiple edges in a single time step temporal_net.AddTemporalEdge(14, "g", "e"); temporal_net.AddTemporalEdge(14, "c", "e"); temporal_net.AddTemporalEdge(15, "e", "f"); temporal_net.AddTemporalEdge(16, "b", "e"); temporal_net.AddTemporalEdge(17, "e", "g"); temporal_net.AddTemporalEdge(18, "c", "e"); temporal_net.AddTemporalEdge(19, "e", "f"); temporal_net.AddTemporalEdge(20, "c", "e"); temporal_net.AddTemporalEdge(21, "e", "f"); return temporal_net; }
public void FromEdgeSequenceTest() { List<Tuple<string, string>> sequence = new List<Tuple<string, string>>(); sequence.Add(new Tuple<string, string>("a", "b")); sequence.Add(new Tuple<string, string>("b", "c")); TemporalNetwork expected = new TemporalNetwork(); expected.AddTemporalEdge(0, "a", "b"); expected.AddTemporalEdge(1, "b", "c"); TemporalNetwork actual; actual = TemporalNetwork.FromEdgeSequence(sequence); Assert.AreEqual(expected, actual); }
static void Main(string[] args) { /// Create a simple temporal network consisting of 11 repeated two-paths (this network corresponds two Fig. 2 (right part) in the paper) TemporalNetwork temporal_net = new TemporalNetwork(); int k = 0; for (int i = 0; i < 100; i++) { // Add edges according to two paths temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "a", "e"); temporal_net.AddTemporalEdge(k++, "e", "g"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "a", "e"); temporal_net.AddTemporalEdge(k++, "e", "g"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); // Note that the next added edge additionally continues a two-path e -> f -> e temporal_net.AddTemporalEdge(k++, "f", "e"); temporal_net.AddTemporalEdge(k++, "e", "b"); // An additional edge that should be filtered during preprocessing ... temporal_net.AddTemporalEdge(k++, "e", "b"); // And one case where we have multiple edges in a single time step temporal_net.AddTemporalEdge(k, "g", "e"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "b", "e"); temporal_net.AddTemporalEdge(k++, "e", "g"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); } // Preprocess two-paths and the aggregate network of the temporal network, if this is skipped it will be done automatically when the aggregate network is computed for the first time Console.Write("Preparing temporal network..."); temporal_net.ReduceToTwoPaths(); Console.WriteLine(" done."); // Aggregate the temporal network WeightedNetwork aggregate_net = temporal_net.AggregateNetwork; // Compute and output betweenness preference of v Console.WriteLine("Betw. pref. of e in empirical network = \t\t{0:0.00000}", BetweennessPref.GetBetweennessPref(temporal_net, "e")); // Create a random temporal network which only preserves the aggregate network (and destroys bet. pref.) TemporalNetwork microstate_random = TemporalNetworkEnsemble.ShuffleEdges(temporal_net, temporal_net.Length); microstate_random.ReduceToTwoPaths(); // Create a random temporal network that preserves both the aggregate network and betw. pref. TemporalNetwork microstate_betweennessPref = TemporalNetworkEnsemble.ShuffleTwoPaths(temporal_net, temporal_net.Length); microstate_betweennessPref.ReduceToTwoPaths(); // Compute and output betweenness preference of v in random temporal network Console.WriteLine("Betw. pref. of e with shuffled edges = \t\t\t{0:0.00000}", BetweennessPref.GetBetweennessPref(microstate_random, "e")); // Compute and output betweenness preference of v in temporal network preserving betw. pref. Console.WriteLine("Betw. pref. of e with shuffled two paths = \t\t{0:0.00000}", BetweennessPref.GetBetweennessPref(microstate_betweennessPref, "e")); // Compute the betweenness preference matrices of the networks Dictionary<string, int> ind_pred; Dictionary<string, int> ind_succ; double[,] m1 = BetweennessPref.GetBetweennessPrefMatrix(temporal_net, "e", out ind_pred, out ind_succ, normalized: false); double[,] m2 = BetweennessPref.GetBetweennessPrefMatrix(microstate_betweennessPref, "e", out ind_pred, out ind_succ, normalized: false); // Get the betweenness preference distribution IEnumerable<double> dist = BetweennessPref.GetBetweennessPrefDist(temporal_net); }
/// <summary> /// Returns a test network in which node B should have betweenness preference 0 /// </summary> /// <returns></returns> public static TemporalNetwork GetTestNetwork6() { TemporalNetwork temporal_net = new TemporalNetwork(); // Create sequence based on edges in edge graph // two-paths ending in (a,b) temporal_net.AddTemporalEdge(1, "A", "B"); temporal_net.AddTemporalEdge(2, "B", "C"); temporal_net.AddTemporalEdge(3, "A", "B"); temporal_net.AddTemporalEdge(4, "B", "C"); // two-paths ending in (b,a) temporal_net.AddTemporalEdge(5, "D", "B"); temporal_net.AddTemporalEdge(6, "B", "A"); temporal_net.AddTemporalEdge(7, "C", "B"); temporal_net.AddTemporalEdge(8, "B", "D"); temporal_net.AddTemporalEdge(9, "X", "Y"); // two-paths ending in (b,c) temporal_net.AddTemporalEdge(10, "D", "B"); temporal_net.AddTemporalEdge(11, "B", "A"); // two-paths ending in (c,b) temporal_net.AddTemporalEdge(12, "C", "B"); temporal_net.AddTemporalEdge(13, "B", "D"); temporal_net.AddTemporalEdge(14, "C", "B"); temporal_net.AddTemporalEdge(15, "B", "D"); temporal_net.AddTemporalEdge(16, "X", "Y"); temporal_net.AddTemporalEdge(17, "D", "B"); temporal_net.AddTemporalEdge(18, "B", "A"); temporal_net.AddTemporalEdge(19, "X", "Y"); temporal_net.AddTemporalEdge(20, "A", "B"); temporal_net.AddTemporalEdge(21, "B", "C"); temporal_net.AddTemporalEdge(19, "A", "B"); temporal_net.AddTemporalEdge(20, "B", "A"); return(temporal_net); }
/// <summary> /// Returns a test network /// </summary> /// <returns></returns> public static TemporalNetwork GetTestNetwork() { TemporalNetwork temporal_net = new TemporalNetwork(); // Add edges according to two paths temporal_net.AddTemporalEdge(1, "c", "e"); temporal_net.AddTemporalEdge(2, "e", "f"); temporal_net.AddTemporalEdge(3, "a", "e"); temporal_net.AddTemporalEdge(4, "e", "g"); temporal_net.AddTemporalEdge(5, "c", "e"); temporal_net.AddTemporalEdge(6, "e", "f"); temporal_net.AddTemporalEdge(7, "a", "e"); temporal_net.AddTemporalEdge(8, "e", "g"); temporal_net.AddTemporalEdge(9, "c", "e"); temporal_net.AddTemporalEdge(10, "e", "f"); // Note that the next added edge additionally continues a two-path e -> f -> e temporal_net.AddTemporalEdge(11, "f", "e"); temporal_net.AddTemporalEdge(12, "e", "b"); // An additional edge that should be filtered during preprocessing ... temporal_net.AddTemporalEdge(13, "e", "b"); // And one case where we have multiple edges in a single time step temporal_net.AddTemporalEdge(14, "g", "e"); temporal_net.AddTemporalEdge(14, "c", "e"); temporal_net.AddTemporalEdge(15, "e", "f"); temporal_net.AddTemporalEdge(16, "b", "e"); temporal_net.AddTemporalEdge(17, "e", "g"); temporal_net.AddTemporalEdge(18, "c", "e"); temporal_net.AddTemporalEdge(19, "e", "f"); temporal_net.AddTemporalEdge(20, "c", "e"); temporal_net.AddTemporalEdge(21, "e", "f"); return(temporal_net); }
static void Main(string[] args) { /// Create a simple temporal network consisting of 11 repeated two-paths (this network corresponds two Fig. 2 (right part) in the paper) TemporalNetwork temporal_net = new TemporalNetwork(); int k = 0; for (int i = 0; i < 100; i++) { // Add edges according to two paths temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "a", "e"); temporal_net.AddTemporalEdge(k++, "e", "g"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "a", "e"); temporal_net.AddTemporalEdge(k++, "e", "g"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); // Note that the next added edge additionally continues a two-path e -> f -> e temporal_net.AddTemporalEdge(k++, "f", "e"); temporal_net.AddTemporalEdge(k++, "e", "b"); // An additional edge that should be filtered during preprocessing ... temporal_net.AddTemporalEdge(k++, "e", "b"); // And one case where we have multiple edges in a single time step temporal_net.AddTemporalEdge(k, "g", "e"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "b", "e"); temporal_net.AddTemporalEdge(k++, "e", "g"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); } // Preprocess two-paths and the aggregate network of the temporal network, if this is skipped it will be done automatically when the aggregate network is computed for the first time Console.Write("Preparing temporal network..."); temporal_net.ReduceToTwoPaths(); Console.WriteLine(" done."); // Aggregate the temporal network WeightedNetwork aggregate_net = temporal_net.AggregateNetwork; // Compute and output betweenness preference of v Console.WriteLine("Betw. pref. of e in empirical network = \t\t{0:0.00000}", BetweennessPref.GetBetweennessPref(temporal_net, "e")); // Create a random temporal network which only preserves the aggregate network (and destroys bet. pref.) TemporalNetwork microstate_random = TemporalNetworkEnsemble.ShuffleEdges(temporal_net, temporal_net.Length); microstate_random.ReduceToTwoPaths(); // Create a random temporal network that preserves both the aggregate network and betw. pref. TemporalNetwork microstate_betweennessPref = TemporalNetworkEnsemble.ShuffleTwoPaths(temporal_net, temporal_net.Length); microstate_betweennessPref.ReduceToTwoPaths(); // Compute and output betweenness preference of v in random temporal network Console.WriteLine("Betw. pref. of e with shuffled edges = \t\t\t{0:0.00000}", BetweennessPref.GetBetweennessPref(microstate_random, "e")); // Compute and output betweenness preference of v in temporal network preserving betw. pref. Console.WriteLine("Betw. pref. of e with shuffled two paths = \t\t{0:0.00000}", BetweennessPref.GetBetweennessPref(microstate_betweennessPref, "e")); // Compute the betweenness preference matrices of the networks Dictionary <string, int> ind_pred; Dictionary <string, int> ind_succ; double[,] m1 = BetweennessPref.GetBetweennessPrefMatrix(temporal_net, "e", out ind_pred, out ind_succ, normalized: false); double[,] m2 = BetweennessPref.GetBetweennessPrefMatrix(microstate_betweennessPref, "e", out ind_pred, out ind_succ, normalized: false); // Get the betweenness preference distribution IEnumerable <double> dist = BetweennessPref.GetBetweennessPrefDist(temporal_net); }
/// <summary> /// Returns a test network suitable for testing the AggregateWindow method /// </summary> /// <returns></returns> public static TemporalNetwork GetTestNetwork3() { TemporalNetwork temporal_net = new TemporalNetwork(); temporal_net.AddTemporalEdge(1, "a", "b"); temporal_net.AddTemporalEdge(2, "a", "c"); temporal_net.AddTemporalEdge(7, "c", "e"); temporal_net.AddTemporalEdge(8, "c", "g"); temporal_net.AddTemporalEdge(9, "g", "f"); temporal_net.AddTemporalEdge(10, "f", "h"); return temporal_net; }
/// <summary> /// Creates the simple example network with betweenness preference that can be seen in the paper in Figure 2 (right) /// </summary> /// <param name="args"></param> public static void Run(string[] args) { if (args.Length < 2) { Console.WriteLine("Usage: TempNet example [output_file]"); return; } string out_file = args[1]; if (!CmdlTools.PromptExistingFile(out_file)) { Console.WriteLine("User opted to exit."); return; } TemporalNetwork temporal_net = new TemporalNetwork(); int k = 0; for (int i = 0; i < 1; i++) { // Add edges according to two paths temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "a", "e"); temporal_net.AddTemporalEdge(k++, "e", "g"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "a", "e"); temporal_net.AddTemporalEdge(k++, "e", "g"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); // Note that the next added edge additionally continues a two-path e -> f -> e temporal_net.AddTemporalEdge(k++, "f", "e"); temporal_net.AddTemporalEdge(k++, "e", "b"); // An additional edge that will be filtered during preprocessing temporal_net.AddTemporalEdge(k++, "e", "b"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "b", "e"); temporal_net.AddTemporalEdge(k++, "e", "g"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); temporal_net.AddTemporalEdge(k++, "c", "e"); temporal_net.AddTemporalEdge(k++, "e", "f"); } Console.Write("Saving to file ..."); TemporalNetwork.SaveToFile(out_file, temporal_net); Console.WriteLine(" done."); }
public void AddTemporalEdgeTest() { TemporalNetwork target = new TemporalNetwork(); target.AddTemporalEdge(0, "a", "b"); Assert.IsTrue(target[0].Contains(new Tuple<string,string>("a", "b"))); }
/// <summary> /// This method creates a random sequence of two paths, where the betweenness preferences as well as edge weights match those of a given temporal network. /// The model implemented here can be viewd in two different ways: /// 1.) It can be seen as a reshuffling of two paths realized in a given temporal network, while destroying other correlations like bursty activity patterns /// 2.) Alternatively, it can be seen as a random sampling based on the betweenness preference matrices of nodes as computed from an empirical network /// </summary> /// <param name="temp_net">The temporal network based on which a randomized sequence of two paths will be created</param> /// <param name="length">The length of the sequence in terms of the number of time-stamped interactions</param> /// <param name="precision">The numerical precision that will be used when sampling from the distribution. This /// at the same time affects the memory requirements of the procedure, which is at most precision*two_paths in the input network</param> /// <returns>A temporal network that preserves betweenness preferences as well as the aggregated network of the input</returns> public static TemporalNetwork ShuffleTwoPaths(TemporalNetwork temp_net, int length=0, int precision=1000) { // If no length is specified (i.e. length has the default value of 0), use the length of the original sequence length = length > 0 ? length : temp_net.Length; // This will take the betweenness pref. matrices of all nodes ... Dictionary<string, double[,]> betweenness_matrices = new Dictionary<string, double[,]>(); Dictionary<string, Dictionary<string, int>> pred_indices = new Dictionary<string, Dictionary<string, int>>(); Dictionary<string, Dictionary<string, int>> succ_indices = new Dictionary<string, Dictionary<string, int>>(); int lcm = 1; // Compute unnormalized betweenness preference matrices of all nodes in the aggregate network foreach (string x in temp_net.AggregateNetwork.Vertices) { Dictionary<string, int> preds = new Dictionary<string, int>(); Dictionary<string, int> succs = new Dictionary<string, int>(); betweenness_matrices[x] = BetweennessPref.GetBetweennessPrefMatrix(temp_net, x, out preds, out succs, normalized: false); pred_indices[x] = preds; succ_indices[x] = succs; // Compute the least common multiple of the denominators of all entries ... // Eventually we will multiply ALL entries of the matrices of ALL nodes with the LCM in order to // ensure that all two paths are represented with the correct relative frequencies foreach (string s in temp_net.AggregateNetwork.GetPredecessors(x)) foreach (string d in temp_net.AggregateNetwork.GetSuccessors(x)) { int whole, numerator, denominator; MathHelper.RoundToMixedFraction(betweenness_matrices[x][pred_indices[x][s], succ_indices[x][d]], precision, out whole, out numerator, out denominator); lcm = MathHelper.LCM(lcm, denominator); } } List<string> sampling_set = new List<string>(); // Create a list of two_paths whose relative frequencies match the betweenness preference matrix... foreach (string v in betweenness_matrices.Keys) { // Add source and target of two paths to list according to their relative frequencies in the matrices foreach (string s in temp_net.AggregateNetwork.GetPredecessors(v)) foreach (string d in temp_net.AggregateNetwork.GetSuccessors(v)) for (int k = 0; k < Math.Round(betweenness_matrices[v][pred_indices[v][s], succ_indices[v][d]] * lcm); k++) sampling_set.Add(s + "," + v + "," + d); } // Create an empty temporal network TemporalNetwork microstate = new TemporalNetwork(); int time = 0; // Draw two-paths at random from the sampling set, this is equivalent to reshuffling existing two paths of the original sequence // However, it additionally correctly accounts for continued two paths (in which case an edge overlaps) and for multiple edges in // a single step (such two paths will be counted fractionally) for (int l = 0; l < length/2; l++) { // Draw a random two path int r = rand.Next(sampling_set.Count); string tp = sampling_set[r]; string[] nodes = tp.Split(','); // Add two temporal edges microstate.AddTemporalEdge(time++, nodes[0], nodes[1]); microstate.AddTemporalEdge(time++, nodes[1], nodes[2]); } return microstate; }