public static void CreateBitmap(TemporalNetwork net, string output_path, bool square = true, int border_width=5) { int columns = 1; if(square) columns = ((int)Math.Sqrt(net.AggregateNetwork.VertexCount * net.Length)) / net.VertexCount + 1; int width = (border_width + net.AggregateNetwork.VertexCount) * columns; int height = (int) Math.Ceiling( (double) net.Length / (double) columns); Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); Console.WriteLine("Exporting to png, output dimensions: {0} x {1}", width, height); Color[] colorWheel = new Color[] {Color.Red, Color.Green, Color.LightBlue, Color.Orange, Color.Blue, Color.Brown, Color.DarkViolet}; Random r = new Random(); Dictionary<string, int> vertex_map = new Dictionary<string, int>(); int i = 0, line = 0; foreach (var v in net.AggregateNetwork.Vertices) vertex_map[v] = i++; foreach(int t in net.Keys) { int y = line % height; int x = (line / height) * (net.AggregateNetwork.VertexCount + border_width); int c = r.Next(colorWheel.Length); foreach (var edge in net[t]) { bmp.SetPixel(x + vertex_map[edge.Item1], y, colorWheel[c%colorWheel.Length]); bmp.SetPixel(x + vertex_map[edge.Item2], y, colorWheel[c % colorWheel.Length]); c++; } for (int j = 0; j < border_width; j++) bmp.SetPixel(x+net.AggregateNetwork.VertexCount+j, y, Color.White); line++; } bmp.Save(output_path, System.Drawing.Imaging.ImageFormat.Png); }
/// <summary> /// Creates an instance of a random walk process /// </summary> /// <param name="network"></param> /// <param name="walkmode"></param> public RandomWalk(TemporalNetwork network, RandomWalkMode walkmode) { RandomWalkMode = walkmode; _network = network; rand = new Random(); _current_visitations = new Dictionary<string, int>(); _last_visits = new Dictionary<string, int>(); // Set visitations to 0 foreach (string v in network.AggregateNetwork.Vertices) _current_visitations[v] = 0; foreach (string v in network.AggregateNetwork.Vertices) _last_visits[v] = -1000; // Reduce first and second-order aggregate network to strongly connected component _network.AggregateNetwork.ReduceToLargestStronglyConnectedComponent(); _network.SecondOrderAggregateNetwork.ReduceToLargestStronglyConnectedComponent(); // Initialize random walk CurrentEdge = StringToTuple(_network.SecondOrderAggregateNetwork.RandomNode); CurrentNode = CurrentEdge.Item2; _current_visitations[CurrentNode] = 1; Time = 1; // Compute stationary distribution _stationary_dist = ComputeStationaryDist(); InitializeCumulatives(); }
public void GetUncorrelatedBetweennessPrefMatrixTest() { TemporalNetwork temp_net = ExampleData.GetTestNetwork(); Dictionary <string, int> index_pred = null; Dictionary <string, int> index_succ = null; double[,] actual = null; actual = BetweennessPref.GetUncorrelatedBetweennessPrefMatrix(temp_net, "e", out index_pred, out index_succ); Assert.IsNotNull(index_pred); Assert.IsNotNull(index_succ); Assert.IsNotNull(actual); // Check whether all entries in the normalized betweenness preference matrix returned match the expected values Assert.AreEqual(actual[index_pred["a"], index_succ["b"]], (2d / 11d) * (1d / 10d)); Assert.AreEqual(actual[index_pred["b"], index_succ["b"]], (1d / 11d) * (1d / 10d)); Assert.AreEqual(actual[index_pred["c"], index_succ["b"]], (6d / 11d) * (1d / 10d)); Assert.AreEqual(actual[index_pred["f"], index_succ["b"]], (1d / 11d) * (1d / 10d)); Assert.AreEqual(actual[index_pred["g"], index_succ["b"]], (1d / 11d) * (1d / 10d)); Assert.AreEqual(actual[index_pred["a"], index_succ["f"]], (2d / 11d) * (6d / 10d)); Assert.AreEqual(actual[index_pred["b"], index_succ["f"]], (1d / 11d) * (6d / 10d)); Assert.AreEqual(actual[index_pred["c"], index_succ["f"]], (6d / 11d) * (6d / 10d)); Assert.AreEqual(actual[index_pred["f"], index_succ["f"]], (1d / 11d) * (6d / 10d)); Assert.AreEqual(actual[index_pred["g"], index_succ["f"]], (1d / 11d) * (6d / 10d)); Assert.AreEqual(actual[index_pred["a"], index_succ["g"]], (2d / 11d) * (3d / 10d)); Assert.AreEqual(actual[index_pred["b"], index_succ["g"]], (1d / 11d) * (3d / 10d)); Assert.AreEqual(actual[index_pred["c"], index_succ["g"]], (6d / 11d) * (3d / 10d)); Assert.AreEqual(actual[index_pred["f"], index_succ["g"]], (1d / 11d) * (3d / 10d)); Assert.AreEqual(actual[index_pred["g"], index_succ["g"]], (1d / 11d) * (3d / 10d)); }
/// <summary> /// Checks whether the weighted aggregate representation of two temporal networks match /// </summary> /// <param name="args"></param> public static void Run(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage: TempNet match [temporal_network_a] [temporal_network_b]"); return; } string file_1 = args[1]; string file_2 = args[2]; Console.Write("Reading temporal network 1 ..."); TemporalNetwork temp_net_1 = TemporalNetwork.ReadFromFile(file_1); Console.WriteLine("done."); Console.Write("Reading temporal network 1 ..."); TemporalNetwork temp_net_2 = TemporalNetwork.ReadFromFile(file_2); Console.WriteLine("done."); Console.WriteLine("Comparing weighted aggregate networks ..."); WeightedNetwork net_1 = temp_net_1.AggregateNetwork; WeightedNetwork net_2 = temp_net_2.AggregateNetwork; if (net_1.Equals(net_2)) { Console.WriteLine("Both networks are identical."); } else { Console.WriteLine("The networks are NOT identical."); } }
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 WeightTest() { TemporalNetwork net1 = ExampleData.GetTestNetwork_weighted_1(); TemporalNetwork net2 = ExampleData.GetTestNetwork_weighted_2(); Assert.AreEqual(net1.TwoPathWeights["a,b,c"], net2.TwoPathWeights["a,b,c"]); Assert.AreEqual(net1.TwoPathWeights["a,b,a"], net2.TwoPathWeights["a,b,a"]); }
public void TimeReversalTest() { TemporalNetwork test = ExampleData.GetTestNetwork(); test.ReduceToTwoPaths(true); Assert.AreEqual(test.TwoPathCount, 10, "Number of paths in time-reversed temporal network is incorrect!"); }
public static void Run(string[] args) { if (args.Length < 2) { Console.WriteLine("Usage: TempNet stats [temporal_network_file] [aggregationWindow=1] [undirected=false] [absoluteTime=false]"); return; } bool undirected = false; bool absoluteTime = false; int aggregationWindow = 1; if (args.Length >= 3) { aggregationWindow = Int32.Parse(args[2]); } if (args.Length >= 4) { undirected = Boolean.Parse(args[3]); } if (args.Length >= 5) { absoluteTime = Boolean.Parse(args[4]); } Console.Write("Reading temporal network as {0} network...", undirected?"undirected":"directed"); TemporalNetwork temp_net = TemporalNetwork.ReadFromFile(args[1], undirected: undirected); Console.WriteLine("done."); int interactions_total = temp_net.EdgeCount; Console.WriteLine("\nOriginal Temporal network"); Console.WriteLine("================="); Console.WriteLine("Number of nodes: \t{0}", temp_net.VertexCount); Console.WriteLine("Number of time steps: \t{0}", temp_net.Length); Console.WriteLine("Number of interactions: \t{0}", interactions_total); Console.WriteLine("Highest granularity \t{0} edges per time step", temp_net.MaxGranularity); Console.WriteLine("Lowest granularity \t{0} edges per time step", temp_net.MinGranularity); temp_net.AggregateTime(aggregationWindow); temp_net.ReduceToTwoPaths(false, absoluteTime); Console.WriteLine("Fraction of two-path interactions \t{0:0.00}", (double)temp_net.AggregateNetwork.CumulativeWeight / (double)interactions_total); Console.WriteLine("\nAggregate network (only nodes and edges contributing to two-paths)"); Console.WriteLine("=================================================================="); Console.WriteLine("Number of nodes: \t{0}", temp_net.AggregateNetwork.VertexCount); Console.WriteLine("Number of interactions: \t{0}", temp_net.AggregateNetwork.CumulativeWeight); Console.WriteLine("Number of two-paths: \t{0}", temp_net.TwoPathCount); Console.WriteLine("Number of edges in aggregate net \t{0}", temp_net.AggregateNetwork.EdgeCount); Console.WriteLine("Max in-degree in aggregate net \t{0}", temp_net.AggregateNetwork.MaxIndeg); Console.WriteLine("Max out-degree in aggregate net \t{0}", temp_net.AggregateNetwork.MaxOutdeg); Console.WriteLine("Max weight in aggregate net \t{0}", temp_net.AggregateNetwork.MaxWeight); Console.WriteLine("Min weight in aggregate net \t{0}", temp_net.AggregateNetwork.MinWeight); Console.WriteLine("Max rel. weight in aggregate net \t{0:0.00000}", (double)temp_net.AggregateNetwork.MaxWeight / (double)temp_net.AggregateNetwork.CumulativeWeight); Console.WriteLine("Min rel. weight in aggregate net \t{0:0.00000}", (double)temp_net.AggregateNetwork.MinWeight / (double)temp_net.AggregateNetwork.CumulativeWeight); }
public void LoadTemporalNetworkTest() { TemporalNetwork net = ExampleData.GetTestNetwork(); TemporalNetwork.SaveToFile("test.net", net); TemporalNetwork net2 = TemporalNetwork.ReadFromFile("test.net"); Assert.AreEqual(net, net2); }
public void BWPTest() { TemporalNetwork net = ExampleData.GetTestNetwork6(); Dictionary <string, int> index_pred = null; Dictionary <string, int> index_succ = null; double[,] actual = null; actual = BetweennessPref.GetBetweennessPrefMatrix(net, "B", out index_pred, out index_succ); double bwp = BetweennessPref.GetBetweennessPref(net, "B"); }
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 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> /// 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> /// Assumption: networks has the same predefined structure /// </summary> public static NetGroup CrossOver(NetGroup a, NetGroup b) { NetGroup output = new NetGroup(a.inputLenght); bool connectionsParent = Convert.ToBoolean(Math.Round(new Random(DateTime.Now.Millisecond).NextDouble())); for (int networkIndex = 0; networkIndex < a.networks.Count; networkIndex++) { List <ConnectedNet.Connection> connections = connectionsParent? b.networks[networkIndex].Connections : a.networks[networkIndex].Connections; output.networks.Add(new ConnectedNet(TemporalNetwork.CrossOver(a.networks[networkIndex].Network, b.networks[networkIndex].Network, -1, true, connectionsParent) , connections, a.networks[networkIndex].OutputToGatherBounds)); } return(output); }
public void AbsoluteTimeTest() { TemporalNetwork test = ExampleData.GetTestNetwork3(); // Default behavior is relative time test.ReduceToTwoPaths(); Assert.IsTrue(test.TwoPathWeights.ContainsKey("a,c,e") && test.TwoPathWeights["a,c,e"] == 1); test = ExampleData.GetTestNetwork3(); test.ReduceToTwoPaths(false, true); Assert.IsFalse(test.TwoPathWeights.ContainsKey("a,c,e")); }
/// <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> /// 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 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); }
public static void CreateBitmap(TemporalNetwork net, string output_path, bool square = true, int border_width = 5) { int columns = 1; if (square) { columns = ((int)Math.Sqrt(net.AggregateNetwork.VertexCount * net.Length)) / net.VertexCount + 1; } int width = (border_width + net.AggregateNetwork.VertexCount) * columns; int height = (int)Math.Ceiling((double)net.Length / (double)columns); Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); Console.WriteLine("Exporting to png, output dimensions: {0} x {1}", width, height); Color[] colorWheel = new Color[] { Color.Red, Color.Green, Color.LightBlue, Color.Orange, Color.Blue, Color.Brown, Color.DarkViolet }; Random r = new Random(); Dictionary <string, int> vertex_map = new Dictionary <string, int>(); int i = 0, line = 0; foreach (var v in net.AggregateNetwork.Vertices) { vertex_map[v] = i++; } foreach (int t in net.Keys) { int y = line % height; int x = (line / height) * (net.AggregateNetwork.VertexCount + border_width); int c = r.Next(colorWheel.Length); foreach (var edge in net[t]) { bmp.SetPixel(x + vertex_map[edge.Item1], y, colorWheel[c % colorWheel.Length]); bmp.SetPixel(x + vertex_map[edge.Item2], y, colorWheel[c % colorWheel.Length]); c++; } for (int j = 0; j < border_width; j++) { bmp.SetPixel(x + net.AggregateNetwork.VertexCount + j, y, Color.White); } line++; } bmp.Save(output_path, System.Drawing.Imaging.ImageFormat.Png); }
/// <summary> /// Parallely computes the betweenness preference distribution of a given temporal network /// </summary> /// <param name="args"></param> public static void Run(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage: TempNet T2 [temporal_network_file] [output_file] [aggregationWndow=1] [undirected=false]"); return; } string out_file = args[2]; if (!CmdlTools.PromptExistingFile(out_file)) { Console.WriteLine("User opted to exit."); return; } bool undirected = false; int aggregationWindow = 1; if (args.Length >= 4) { aggregationWindow = int.Parse(args[3]); } if (args.Length >= 5) { undirected = Boolean.Parse(args[4]); } Console.Write("Reading temporal network as {0} network...", undirected ? "undirected" : "directed"); TemporalNetwork temp_net = TemporalNetwork.ReadFromFile(args[1], undirected: undirected); Console.WriteLine(" done."); Console.WriteLine("Applying aggregation window, length = {0}, time steps before = {1}", aggregationWindow, temp_net.Length); temp_net.AggregateTime(aggregationWindow); Console.WriteLine("done, time steps after = {0}", temp_net.Length); Console.Write("Building aggregate networks ..."); temp_net.ReduceToTwoPaths(); Console.WriteLine(" done."); Console.Write("Writing transition matrix ..."); WriteTwopathTransitionMatrix(temp_net, out_file); Console.WriteLine("done."); }
/// <summary> /// /// </summary> /// <returns></returns> public static void WriteTwopathTransitionMatrix(TemporalNetwork temp_net, string file) { // Dictionary that takes transition probabilities for pairs of edges (i.e. two-paths) var P = new Dictionary <Tuple <string, string>, double>(); var edge_nodes = temp_net.SecondOrderAggregateNetwork.Vertices; foreach (var source in edge_nodes) { foreach (var target in edge_nodes) { var two_path = new Tuple <string, string>(source, target); if (temp_net.SecondOrderAggregateNetwork.ContainsKey(two_path)) { P[two_path] = temp_net.SecondOrderAggregateNetwork[two_path] / temp_net.SecondOrderAggregateNetwork.GetCumulativeOutWeight(source); } else { P[two_path] = 0d; } } } System.IO.StreamWriter sw = new System.IO.StreamWriter(file); // Write column header foreach (var target in edge_nodes) { sw.Write(target + " "); } sw.WriteLine(); foreach (var source in edge_nodes) { sw.Write(source + " "); foreach (var target in edge_nodes) { var two_path = new Tuple <string, string>(source, target); sw.Write("{0} ", string.Format(System.Globalization.CultureInfo.GetCultureInfo("en-US").NumberFormat, "{0:0.000000}", P[two_path])); } sw.WriteLine(); } sw.Close(); }
/// <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); }
/// <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 GetBetweennessPrefMatrixTest() { TemporalNetwork temp_net = ExampleData.GetTestNetwork(); Dictionary <string, int> index_pred = null; Dictionary <string, int> index_succ = null; double[,] actual; actual = BetweennessPref.GetBetweennessPrefMatrix(temp_net, "e", out index_pred, out index_succ); Assert.IsNotNull(index_pred); Assert.IsNotNull(index_succ); Assert.IsNotNull(actual); // Check whether all entries in the normalized betweenness preference matrix returned match the expected values Assert.AreEqual(0d, actual[index_pred["a"], index_succ["b"]]); Assert.AreEqual(0d, actual[index_pred["b"], index_succ["b"]]); Assert.AreEqual(0d, actual[index_pred["c"], index_succ["b"]]); Assert.AreEqual(1d / 10d, actual[index_pred["f"], index_succ["b"]]); Assert.AreEqual(0d, actual[index_pred["g"], index_succ["b"]]); Assert.AreEqual(actual[index_pred["a"], index_succ["f"]], 0d); Assert.AreEqual(actual[index_pred["b"], index_succ["f"]], 0d); Assert.AreEqual(actual[index_pred["c"], index_succ["f"]], 11d / 20d); Assert.AreEqual(actual[index_pred["f"], index_succ["f"]], 0d); Assert.AreEqual(actual[index_pred["g"], index_succ["f"]], 1d / 20d); Assert.AreEqual(actual[index_pred["a"], index_succ["g"]], 2d / 10d); Assert.AreEqual(actual[index_pred["b"], index_succ["g"]], 1d / 10d); Assert.AreEqual(actual[index_pred["c"], index_succ["g"]], 0d); Assert.AreEqual(actual[index_pred["f"], index_succ["g"]], 0d); Assert.AreEqual(actual[index_pred["g"], index_succ["g"]], 0d); Assert.AreEqual(BetweennessPref.GetBetweennessPref(temp_net, "e"), 1.2954618442383219d); actual = BetweennessPref.GetBetweennessPrefMatrix(temp_net, "f", out index_pred, out index_succ); Assert.IsNotNull(index_pred); Assert.IsNotNull(index_succ); Assert.IsNotNull(actual); Assert.AreEqual(actual[index_pred["e"], index_succ["e"]], 1d); }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("\nUsage: Visualize [network-file] [iterations=50]\n"); return; } string network_file = args[0]; int iterations = args.Length >= 2 ? int.Parse(args[1]) : 50; // Load the temporal and aggregate network Console.Write("Loading temporal network ..."); TemporalNetwork net = TemporalNetwork.ReadFromFile(network_file); Console.WriteLine("done"); Console.Write("Computing aggregate network ..."); WeightedNetwork agg = net.AggregateNetwork; Console.WriteLine("done"); // Change the colors NetworkColorizer colors = new NetworkColorizer(); colors.DefaultBackgroundColor = Color.White; colors.DefaultVertexColor = Color.DarkBlue; colors.DefaultEdgeColor = Color.Black; Renderer.CurvedEdges = true; RenderableTempNet temp_net = new RenderableTempNet(net); // Start rendering ... Renderer.Start(temp_net, new FRLayout(iterations), colors); // Asynchronously compute the layout ... Renderer.Layout.DoLayout(); Application.Run(new VisualizationController(temp_net)); }
public static ConnectedNet FromString(string str) { string outRangeS = str.Remove(str.IndexOf("\nnetwork:")); outRangeS = outRangeS.Replace("outRange: ", ""); Range outRange = Range.FromString(outRangeS); string[] srs = str.Split(new string[] { "\nNetConnection: " }, StringSplitOptions.RemoveEmptyEntries); string toRemove = "network:\n"; srs[0] = srs[0].Remove(0, srs[0].IndexOf(toRemove) + toRemove.Length); TemporalNetwork network = TemporalNetwork.FromString(srs[0]); List <Connection> connections = new List <Connection>(); for (int i = 1; i < srs.Length; i++) { connections.Add(Connection.FromString(srs[i])); } return(new ConnectedNet(network, connections, outRange)); }
/// <summary> /// /// </summary> /// <returns></returns> public static void WriteTwopathTransitionMatrix(TemporalNetwork temp_net, string file) { // Dictionary that takes transition probabilities for pairs of edges (i.e. two-paths) var P = new Dictionary<Tuple<string, string>, double>(); var edge_nodes = temp_net.SecondOrderAggregateNetwork.Vertices; foreach (var source in edge_nodes) { foreach (var target in edge_nodes) { var two_path = new Tuple<string, string>(source, target); if (temp_net.SecondOrderAggregateNetwork.ContainsKey(two_path)) P[two_path] = temp_net.SecondOrderAggregateNetwork[two_path] / temp_net.SecondOrderAggregateNetwork.GetCumulativeOutWeight(source); else P[two_path] = 0d; } } System.IO.StreamWriter sw = new System.IO.StreamWriter(file); // Write column header foreach (var target in edge_nodes) sw.Write(target + " "); sw.WriteLine(); foreach (var source in edge_nodes) { sw.Write(source + " "); foreach (var target in edge_nodes) { var two_path = new Tuple<string, string>(source, target); sw.Write("{0} ", string.Format(System.Globalization.CultureInfo.GetCultureInfo("en-US").NumberFormat, "{0:0.000000}", P[two_path])); } sw.WriteLine(); } sw.Close(); }
public static void Run(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage: TempNet filter [temporal_network_original] [filter_file] [temporal_network_new] [undirected=true]"); return; } string file_orig = args[1]; string filter = args[2]; string file_new = args[3]; bool undirected = true; if (args.Length >= 5) { undirected = Boolean.Parse(args[4]); } Console.Write("Reading temporal network as {0} network...", undirected?"undirected":"directed"); TemporalNetwork temp_net = TemporalNetwork.ReadFromFile(file_orig, undirected: undirected); Console.WriteLine("done."); string[] filtered_edges = System.IO.File.ReadAllLines(filter); foreach (string x in filtered_edges) { if (x.Contains(";")) { string[] comps = x.Split(';'); temp_net.Remove(new Tuple <string, string>(comps[0], comps[1])); } } TemporalNetwork.SaveToFile(file_new, temp_net); }
public static void Run(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage: TempNet visualize [temporal_network_file] [output_png] [square=TRUE] [border=5]"); return; } string out_file = args[2]; bool square = true; int border = 5; if (args.Length >= 4) { square = bool.Parse(args[3]); } if (args.Length >= 5) { border = int.Parse(args[4]); } if (!CmdlTools.PromptExistingFile(out_file)) { Console.WriteLine("User opted to exit."); return; } Console.Write("Reading temporal network ..."); TemporalNetwork temp_net = TemporalNetwork.ReadFromFile(args[1]); Console.WriteLine("done."); CreateBitmap(temp_net, out_file, square, border); Console.WriteLine(" done."); }
public static void Run(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage: TempNet tikz [temporal_network_file] [output_file]"); return; } string out_file = args[2]; if (!CmdlTools.PromptExistingFile(out_file)) { Console.WriteLine("User opted to exit."); return; } Console.Write("Reading temporal network ..."); TemporalNetwork temp_net = TemporalNetwork.ReadFromFile(args[1]); Console.WriteLine("done."); Console.Write("Exporting to tikz..."); TikzExporter.CreateTikzUnfolding(out_file, null, temp_net); Console.WriteLine(" done."); }
/// <summary> /// Runs an SI spreading process on a temporal network and outputs the dynamics of the infection size /// </summary> /// <param name="args"></param> public static void Run(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage: TempNet spreading [temporal_network_file] [output_file]"); return; } string out_file = args[2]; if (!CmdlTools.PromptExistingFile(out_file)) { Console.WriteLine("User opted to exit."); return; } Console.Write("Reading temporal network as directed..."); TemporalNetwork temp_net = TemporalNetwork.ReadFromFile(args[1]); // Prevent the network from being reduced to two paths temp_net.StripEdgesToTwoPaths = false; Console.WriteLine("done."); Console.Write("Running SI spreading on temporal network with {0} time steps ...", temp_net.Length); string times = null; string output = SISpreading.RunSpreading(temp_net, out times, 1d); Console.WriteLine(" done."); if (output != null) { Console.Write("Finished path discovery. Writing path length matrix"); System.IO.File.WriteAllText(out_file, output); System.IO.File.WriteAllText(out_file + ".times", times); Console.WriteLine("done."); } }
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> /// 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; }
public RenderableTempNet(TemporalNetwork temp_net) { Network = temp_net; CurrentTime = 0; }
/// <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."); }
/// <summary> /// Parallely computes the betweenness preference distribution of all nodes in a temporal network /// </summary> /// <param name="temp_net">The temporal network to analyze</param> /// <returns>An IEnumerable containing betweenness preferences of all nodes</returns> public static IEnumerable<double> GetBetweennessPrefDist(TemporalNetwork temp_net) { List<double> dist = new List<double>(temp_net.AggregateNetwork.VertexCount); Parallel.ForEach<string>(temp_net.AggregateNetwork.Vertices, v => { double betweennessPref = BetweennessPref.GetBetweennessPref(temp_net, v); // Synchronized access to the list if(temp_net.AggregateNetwork.GetIndeg(v)>0 && temp_net.AggregateNetwork.GetOutdeg(v)>0) lock (dist) dist.Add(betweennessPref); }); return dist; }
public void AggregateTimeTest() { TemporalNetwork net = ExampleData.GetTestNetwork3(); net.AggregateTime(3); }
/// <summary> /// Runs a random walk process on an aggregate networks and outputs the dynamics of the infection size /// </summary> /// <param name="args"></param> public static void Run(string[] args) { if (args.Length < 3) { Console.WriteLine("Usage: TempNet rw [network_file] [output_file] [RWMode=static_first] [aggregationWindow=1] [steps=1000]"); Console.WriteLine("\t where RWMode can be ... "); Console.WriteLine("\t static_first\t Performs a random walk on the aggregate network that considers betweenness preferences computed from the temporal network"); Console.WriteLine("\t static_second\t ..."); return; } string out_file = args[2]; RandomWalkMode mode = RandomWalkMode.StaticFirstOrder; int runs = 1; int length = 1000; int aggregationWindow = 1; if (args.Length >= 4) { if (args[3] == "static_second") { mode = RandomWalkMode.StaticSecondOrder; } else { Console.WriteLine("Unknown walk mode '{0}'", args[3]); } } if (args.Length >= 5) { aggregationWindow = int.Parse(args[4]); } if (args.Length >= 6) { runs = int.Parse(args[5]); } if (args.Length >= 7) { length = int.Parse(args[6]); } if (!CmdlTools.PromptExistingFile(out_file)) { Console.WriteLine("User opted to exit."); return; } Console.Write("Reading temporal network as undirected network..."); TemporalNetwork temp_net = TemporalNetwork.ReadFromFile(args[1], true); Console.WriteLine("done."); if (aggregationWindow != 1) { Console.WriteLine("Applying aggregation window, length = {0}, time steps before = {1}", aggregationWindow, temp_net.Length); temp_net.AggregateTime(aggregationWindow); Console.WriteLine("done, time steps after = {0}", temp_net.Length); } Console.Write("Building aggregate network..."); WeightedNetwork aggregateNet = temp_net.AggregateNetwork; Console.WriteLine("done."); Console.WriteLine("Starting random walk ..."); Dictionary <int, double> tvd = new Dictionary <int, double>(); RandomWalk walk = new RandomWalk(temp_net, mode); for (int t = 0; t < length; t++) { walk.Step(); tvd[t] = walk.TVD; Console.WriteLine("Node = {0}, step = {1}, tvd={2:0.000}", walk.CurrentNode, t, tvd[t]); } Console.Write("Writing time series of total variation distance ..."); StringBuilder sb = new StringBuilder(); foreach (var step in tvd) { sb.AppendLine(string.Format(System.Globalization.CultureInfo.GetCultureInfo("en-US").NumberFormat, "{0} {1}", step.Key, step.Value)); } System.IO.File.WriteAllText(out_file + ".dat", sb.ToString()); Console.WriteLine(" done."); }
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 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; }
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 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> /// Computes the betweenness preference matrix of a node based on the set of two-paths of a node. /// By this we essentially implement equations (1) and (2). /// If additionally the normalization parameter is set, equation (3) will be computed. /// </summary> /// <param name="temp_net">The temporal network to compute betweeness preference for</param> /// <param name="x">The node for which to compute the betweenness preference matrix</param> /// <param name="ego_net">The weighted, aggregate ego network</param> /// <param name="index_pred">A mapping of nodes to columns in the betweenness preference matrix</param> /// <param name="index_succ">A mapping of nodes to rows in the betweenness preference matrix</param> /// <param name="normalize">Whether or not to normalize the matrix, i.e. whether B (eq. 2) or P (eq. 3) shall be returned</param> /// <returns>Depending on the normalization, a betweenness preference matrix B or the normalized version P will be returned</returns> public static double[,] GetBetweennessPrefMatrix(TemporalNetwork temp_net, string x, out Dictionary<string, int> index_pred, out Dictionary<string, int> index_succ, bool normalized=true) { // Use a mapping of indices to node labels index_pred = new Dictionary<string, int>(); index_succ = new Dictionary<string, int>(); // Create an empty matrix double[,] B = new double[temp_net.AggregateNetwork.GetIndeg(x), temp_net.AggregateNetwork.GetOutdeg(x)]; // Create the index-to-node mapping int i = 0; foreach (string u in temp_net.AggregateNetwork.GetPredecessors(x)) index_pred[u] = i++; i = 0; foreach (string w in temp_net.AggregateNetwork.GetSuccessors(x)) index_succ[w] = i++; // Here we implement equation (1) and (2), i.e. we normalize PER TIME STEP foreach (var t in temp_net.TwoPathsByNode[x].Keys) foreach (var two_path in temp_net.TwoPathsByNode[x][t]) B[index_pred[two_path.Item1], index_succ[two_path.Item2]] += 1d / (double) temp_net.TwoPathsByNode[x][t].Count; // This is equation 3, i.e. we normalize ACROSS THE MATRIX if(normalized) return NormalizeMatrix(x, temp_net.AggregateNetwork, B); else return B; }
/// <summary> /// Runs a simple SI spreading on a given temporal network and returns the dynamics of the infections /// </summary> /// <param name="temp_net">The temporal network to use</param> /// <param name="p">The infection probability (default is 1)</param> /// <returns>An enumerable of infection numbers, each entry giving the number of infected individuals at a certain time of the simulation</returns> public static string RunSpreading(TemporalNetwork temp_net, out string times, double p=1d) { // Which nodes are already infected? Dictionary<string, bool> discovered = new Dictionary<string, bool>(); Dictionary<int,int> infections = new Dictionary<int,int>(temp_net.Count); // Initialize foreach (string s in temp_net.AggregateNetwork.Vertices) discovered[s] = false; // Build the initial matrix of fastestPathLengths Dictionary<string, int> indices = new Dictionary<string, int>(temp_net.AggregateNetwork.VertexCount); short[,] fastestPathLengths = new short[temp_net.AggregateNetwork.VertexCount, temp_net.AggregateNetwork.VertexCount]; short[,] fastestPath_mid_Lengths = new short[temp_net.AggregateNetwork.VertexCount, temp_net.AggregateNetwork.VertexCount]; uint[,] fastestPathDurations= new uint[temp_net.AggregateNetwork.VertexCount, temp_net.AggregateNetwork.VertexCount]; // Build the indices int i = 0; foreach (string s in temp_net.AggregateNetwork.Vertices) indices[s] = i++; // Initialize with maximum values ... foreach (string s in temp_net.AggregateNetwork.Vertices) foreach (string d in temp_net.AggregateNetwork.Vertices) { fastestPathLengths[indices[s], indices[d]] = short.MaxValue; fastestPath_mid_Lengths[indices[s], indices[d]] = short.MaxValue; fastestPathDurations[indices[s], indices[d]] = uint.MaxValue; } // Run a spreading process starting at each node in the network ... foreach (var start in temp_net.AggregateNetwork.Vertices) { // Reset the infected state for all foreach (string s in temp_net.AggregateNetwork.Vertices) discovered[s] = false; // Infect the start node int discovered_n = 1; discovered[start] = true; fastestPathLengths[indices[start], indices[start]] = 0; fastestPathDurations[indices[start], indices[start]] = 0; try { // Get the first time stamp where the start node was source of two path var start_time = temp_net.TwoPathsByStartTime.Keys.First(z => { foreach (string twopath in temp_net.TwoPathsByStartTime[z]) if (twopath.StartsWith(start)) return true; return false; }); uint t_ = (uint) start_time; // Create a list of ordered time stamps starting with the first activity of the start node var time_stamps = from x in temp_net.TwoPathsByStartTime.Keys where x >= start_time orderby x ascending select x; // Extract all paths consisting of "two path" building blocks foreach (int t in time_stamps) { // A path continues if the source node of a two-path has already been discovered foreach (var two_path in temp_net.TwoPathsByStartTime[t]) { // Get the three components of the two path string[] comps = two_path.Split(','); // Record the geodesic distance between the start and the middle node comps[1] fastestPath_mid_Lengths[indices[start], indices[comps[1]]] = (short) Math.Min(fastestPath_mid_Lengths[indices[start], indices[comps[1]]], fastestPathLengths[indices[start], indices[comps[0]]]+1); // If the target node of a two path has not been discovered before, we just discovered a new fastest time-respecting path! if (discovered[comps[0]] && !discovered[comps[2]]) { // Add to nodes already discovered discovered_n++; discovered[comps[2]] = true; // Record geodesic distance of fastest time-respecting path fastestPathLengths[indices[start], indices[comps[2]]] = (short)(fastestPathLengths[indices[start], indices[comps[0]]] + 2); // Record temporal length of fastest time-respecting path fastestPathDurations[indices[start], indices[comps[2]]] = (uint) (t-start_time); } } // Stop as soon as all nodes have been discovered if (discovered_n == temp_net.AggregateNetwork.VertexCount) break; // Advance the time by two t_ += 2; } } catch(Exception) { // In this case, a start node is never the source of two-path, so we just ignore it ... } } // Aggregate the matrices foreach(string s in temp_net.AggregateNetwork.Vertices) foreach (string d in temp_net.AggregateNetwork.Vertices) fastestPathLengths[indices[s], indices[d]] = Math.Min(fastestPathLengths[indices[s], indices[d]], fastestPath_mid_Lengths[indices[s], indices[d]]); StringBuilder sb = new StringBuilder(); StringBuilder sb_t = new StringBuilder(); var nodes = from n in temp_net.AggregateNetwork.Vertices.AsParallel() orderby n ascending select n; foreach (string s in nodes) { foreach (string d in nodes) { sb.Append(fastestPathLengths[indices[s], indices[d]]+"\t"); sb_t.Append(fastestPathDurations[indices[s], indices[d]] + "\t"); } sb.Append("\n"); sb_t.Append("\n"); } times = sb_t.ToString(); return sb.ToString(); }
/// <summary> /// Creates a TikZ representation of the temporal unfolding of the temporal network /// </summary> /// <param name="path">The path to which to write the tikz file</param> /// <param name="temp_net">The temporal network that shall be exported</param> public static void CreateTikzUnfolding(string path, string between_node, TemporalNetwork temp_net) { WeightedNetwork net = WeightedNetwork.FromTemporalNetwork(temp_net); StringBuilder strB = new StringBuilder(); strB.AppendLine(@"\documentclass{article} \usepackage{tikz} \usepackage{verbatim} \usepackage[active,tightpage]{preview} \PreviewEnvironment{tikzpicture} \setlength\PreviewBorder{5pt}% \usetikzlibrary{arrows} \usetikzlibrary{positioning} \begin{document} \begin{center}"); strB.AppendLine("\\newcounter{a}"); strB.AppendLine("\\begin{tikzpicture}[->,>=stealth',auto,scale=0.5, every node/.style={scale=0.9}]"); strB.AppendLine("\\tikzstyle{node} = [fill=lightgray,text=black,circle]"); strB.AppendLine("\\tikzstyle{v} = [fill=black,text=white,circle]"); strB.AppendLine("\\tikzstyle{dst} = [fill=lightgray,text=black,circle]"); strB.AppendLine("\\tikzstyle{lbl} = [fill=white,text=black,circle]"); string last = ""; foreach (string v in net.Vertices.OrderBy(s => s)) { if (last == "") strB.AppendLine("\\node[lbl] (" + v + "-0) {$" + v + "$};"); else strB.AppendLine("\\node[lbl,right=0.5cm of "+last+"-0] (" + v + "-0) {$" + v + "$};"); last = v; } strB.AppendLine("\\setcounter{a}{0}"); strB.AppendLine("\\foreach \\number in {1,...," + (temp_net.Length + 1) + "}{"); strB.AppendLine("\\setcounter{a}{\\number}"); strB.AppendLine("\\addtocounter{a}{-1}"); strB.AppendLine("\\pgfmathparse{\\thea}"); foreach (string v in net.Vertices) { if (v != between_node) strB.AppendLine("\\node[node,below=0.3cm of " + v + "-\\pgfmathresult] (" + v + "-\\number) {};"); else strB.AppendLine("\\node[v,below=0.3cm of " + v + "-\\pgfmathresult] (" + v + "-\\number) {};"); } strB.AppendLine("\\node[lbl,left=0.5cm of " + net.Vertices.OrderBy(s => s).ElementAt(0) + "-\\number] (col-\\pgfmathresult) {$t=$\\number};"); strB.AppendLine("}"); strB.AppendLine("\\path[->,thick]"); int i = 1; foreach (var t in temp_net.Keys) { foreach (var edge in temp_net[t]) { strB.AppendLine("(" + edge.Item1 + "-" + (t+1) + ") edge (" + edge.Item2 + "-" + (t + 2) + ")"); i++; } } strB.AppendLine(";"); strB.AppendLine(@"\end{tikzpicture} \end{center} \end{document}"); System.IO.File.WriteAllText(path, strB.ToString()); }
/// <summary> /// Computes the baseline betweenness preference matrix of a node under the assumption /// that the temporal network does not contain a betweenness preference correlation. This corresponds to /// equation (5) in the paper. /// </summary> /// <param name="temp_net">The temporal network for which to compute the matrix</param> /// <param name="x">The node to compute the baseline betweenness preference for</param> /// <param name="ego_net">The weighted, aggregate ego network of node x</param> /// <param name="index_pred">Indices of predecessor nodes in the betweenness preference matrix</param> /// <param name="index_succ">Indices of successor nodes in the betweenness preference matric</param> /// <param name="normalize">Whether or not to normalize the betweenness preference matrix (i.e. whether B or P shall be returned)</param> /// <returns>Depending on the normalization, a betweenness preference matrix B or the normalized version P will be returned</returns> public static double[,] GetUncorrelatedBetweennessPrefMatrix(TemporalNetwork temp_net, string x, out Dictionary<string, int> index_pred, out Dictionary<string, int> index_succ) { // Use a mapping of indices to node labels index_pred = new Dictionary<string, int>(); index_succ = new Dictionary<string, int>(); // Compute the matrix from the weighted ego network return GetUncorrelatedBetweennessPrefMatrix(temp_net.AggregateNetwork, x, out index_pred, out index_succ); }
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 ReduceToTwoPathsTest() { TemporalNetwork test = ExampleData.GetTestNetwork(); test.ReduceToTwoPaths(); // There should be 12 two paths Assert.AreEqual(test.TwoPathCount, 12); // And 21 edges Assert.AreEqual(test.EdgeCount, 21); // The stripped network should contain 20 time steps Assert.AreEqual(test.Length, 20); Assert.AreEqual(test.MaxGranularity, 1); Assert.AreEqual(test.MinGranularity, 2); // The aggregate network should contain 8 weighted edges with a cumulative weight that matches 2 * twoPathCount Assert.AreEqual(test.AggregateNetwork.EdgeCount, 8); Assert.AreEqual(test.AggregateNetwork.CumulativeWeight, 22); // The second-order aggregate network should countain edges representing 6 different two-paths ... Assert.AreEqual(test.SecondOrderAggregateNetwork.EdgeCount, 6); // ... with a total weight of 11 Assert.AreEqual(test.SecondOrderAggregateNetwork.CumulativeWeight, 11); Assert.AreEqual(test.SecondOrderAggregateNetwork[new Tuple <string, string>("(c;e)", "(e;f)")], 5.5d); Assert.AreEqual(test.SecondOrderAggregateNetwork[new Tuple <string, string>("(g;e)", "(e;f)")], 0.5d); Assert.AreEqual(test.SecondOrderAggregateNetwork[new Tuple <string, string>("(e;f)", "(f;e)")], 1d); Assert.AreEqual(test.SecondOrderAggregateNetwork[new Tuple <string, string>("(f;e)", "(e;b)")], 1d); Assert.AreEqual(test.SecondOrderAggregateNetwork[new Tuple <string, string>("(a;e)", "(e;g)")], 2d); Assert.AreEqual(test.SecondOrderAggregateNetwork[new Tuple <string, string>("(b;e)", "(e;g)")], 1d); // Check whether all the weights are correctly computed ... Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("e", "f")], 7, "The weight of egde (e,f) in the aggregate network is wrong!"); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("e", "b")], 1, "The weight of egde (e,b) in the aggregate network is wrong!"); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("b", "e")], 1, "The weight of egde (b,e) in the aggregate network is wrong!"); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("g", "e")], 1d / 2d, "The weight of egde (g,e) in the aggregate network is wrong!"); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("e", "g")], 3, "The weight of egde (e,g) in the aggregate network is wrong!"); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("f", "e")], 2, "The weight of egde (f,e) in the aggregate network is wrong!"); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("a", "e")], 2, "The weight of egde (a,e) in the aggregate network is wrong!"); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("c", "e")], 5 + 1d / 2d, "The weight of egde (c,e) in the aggregate network is wrong!"); Assert.AreEqual(test.AggregateNetwork.MaxWeight, 7, "The maximum weight in the aggregate network is wrong!"); Assert.AreEqual(test.AggregateNetwork.MinWeight, 0.5d, "The minimum weight in the aggregate network is wrong!"); test = ExampleData.GetTestNetwork2(); test.ReduceToTwoPaths(); Assert.AreEqual(test.TwoPathCount, 7); Assert.AreEqual(test.Length, 3); Assert.AreEqual(test.MaxGranularity, 1); Assert.AreEqual(test.MinGranularity, 3); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("a", "b")], 1); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("b", "c")], 1d + 1d / 6d + 1d / 6d + 1d / 6d); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("d", "c")], 1d / 2d); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("c", "d")], 1d / 3d); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("c", "b")], 1d / 3d); Assert.AreEqual(test.AggregateNetwork[new Tuple <string, string>("c", "a")], 1d / 3d); }
/// <summary> /// Computes the (scalar) betwenness preference of a node /// </summary> /// <param name="temp_net">The temporal network for which to compute betweenness preference</param> /// <param name="x">The node for which to compute betweenness preference</param> /// <returns>The betweenness preference, defined as the mutual information of the source and target of two-paths</returns> public static double GetBetweennessPref(TemporalNetwork temp_net, string x, bool normalized = false) { // This will be used to store the index mappings in the betweenness preference matrix Dictionary<string, int> index_pred; Dictionary<string, int> index_succ; // Compute the normalized betweenness preference matrix of x according to equation (2) and (3) double[,] P = GetBetweennessPrefMatrix(temp_net, x, out index_pred, out index_succ); return GetBetweennessPref(temp_net.AggregateNetwork, x, P, normalized); }