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;
        }
Example #3
0
        public void AddTemporalEdgeTest()
        {
            TemporalNetwork target = new TemporalNetwork();

            target.AddTemporalEdge(0, "a", "b");
            Assert.IsTrue(target[0].Contains(new Tuple <string, string>("a", "b")));
        }
Example #4
0
        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);
        }
Example #12
0
        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);
        }
Example #13
0
        /// <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);
        }
Example #14
0
        /// <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);
        }
Example #15
0
        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;
        }
Example #17
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>
        /// 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;
        }