Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <summary>
        /// Creates a temporal network instance from an ordered sequence of edges
        /// </summary>
        /// <param name="sequence">An ordered sequence of edges</param>
        /// <returns>An instance of a temporal network</returns>
        public static TemporalNetwork FromEdgeSequence(List <Tuple <string, string> > sequence)
        {
            TemporalNetwork net  = new TemporalNetwork();
            int             time = 0;

            foreach (Tuple <string, string> t in sequence)
            {
                net.AddTemporalEdge(time++, t.Item1, t.Item2);
            }
            return(net);
        }
Пример #3
0
        /// <summary>
        /// Reads a temporal network from a file containing lines with trigrams a,b,c
        /// </summary>
        /// <param name="path">The path to the data file</param>
        /// <returns>A temporal network instance</returns>
        public static TemporalNetwork FromTrigramsFile(string path)
        {
            TemporalNetwork temp_net = new TemporalNetwork();

            string[] lines = System.IO.File.ReadAllLines(path);

            // if empty
            if (lines.Length == 0)
            {
                return(temp_net);
            }

            char[] split_chars = new char[] { ' ', '\t', ';', ',' };
            char   split_char  = ' ';

            // detect split character
            string[] line = null;
            foreach (char c in split_chars)
            {
                line = lines[0].Split(c);
                if (line.Length == 3)
                {
                    split_char = c;
                    break;
                }
            }

            // Read trigrams and generate temporal network representation
            int time = 0;

            for (int i = 0; i < lines.Length; i++)
            {
                string[] components = lines[i].Split(split_char);
                temp_net.AddTemporalEdge(time, components[0], components[1]);
                temp_net.AddTemporalEdge(time + 1, components[1], components[2]);
                time = time + 3;
            }

            return(temp_net);
        }
Пример #4
0
        /// <summary>
        /// Reads an edge sequence from a file containing ordered edges and creates a temporal network instance. The file is
        /// assumed to have one line per edge, each possibly consisting of several colums and separated by a special delimiter character.
        /// The caller can specify which (zero-based) column number indicate the source and the target of an interaction. If no parameters
        /// are specified apart from the path, each line in the file is assumed to contain two strings representing the source and target of an
        /// edge in the first two columns separated by a space. No header line is assumed by default.
        /// </summary>
        /// <param name="path">The path of the file containing the edge sequence.</param>
        /// <param name="source_col">The zero-based column number on the source node of an edge. 0 by default</param>
        /// <param name="target_col">The zero-based column number on the target node of an edge. 1 by default</param>
        /// <param name="header">Whether or not there is a header line that shall be ignored</param>
        /// <param name="split_char">The character used to separate columns in each line</param>
        /// <returns>An instance of a temporal network corresponding to the input sequence</returns>
        public static TemporalNetwork ReadFromFile(string path, bool undirected = false)
        {
            TemporalNetwork temp_net = new TemporalNetwork();

            // Read all data from file
            string[] lines = System.IO.File.ReadAllLines(path);

            // If empty ...
            if (lines.Length == 0)
            {
                return(temp_net);
            }

            // Extract header
            char[] split_chars = new char[] { ' ', '\t', ';', ',' };
            char   split_char  = ' ';

            // Detect the correct separator character in CSV format
            string[] header = null;
            foreach (char c in split_chars)
            {
                header = lines[0].Split(c);
                if (header.Length >= 2 && ((header.Contains("node1") && header.Contains("node2")) || (header.Contains("source") && header.Contains("target"))))
                {
                    split_char = c;
                    break;
                }
            }

            if (header.Length < 2)
            {
                return(temp_net);
            }

            // Extract indices of columns
            int time_ix   = -1;
            int source_ix = -1;
            int target_ix = -1;

            for (int i = 0; i < header.Length; i++)
            {
                if (header[i] == "time")
                {
                    time_ix = i;
                }
                else if (header[i] == "node1" || header[i] == "source")
                {
                    source_ix = i;
                }
                else if (header[i] == "node2" || header[i] == "target")
                {
                    target_ix = i;
                }
            }

            // If there is no source and target column
            if (source_ix < 0 || target_ix < 0)
            {
                return(temp_net);
            }
            for (int i = 1; i < lines.Length; i++)
            {
                string[] components = lines[i].Split(split_char);
                if (components[source_ix] != "" && components[target_ix] != "")
                {
                    // If there is no explicit time, just consider each edge occuring at consecutive time steps
                    int t = time_ix >= 0 ? int.Parse(components[time_ix]) : i;

                    temp_net.AddTemporalEdge(t, components[source_ix], components[target_ix]);
                    if (undirected)
                    {
                        temp_net.AddTemporalEdge(t, components[target_ix], components[source_ix]);
                    }
                }
            }
            return(temp_net);
        }
Пример #5
0
        /// <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);
        }