/// <summary>
        /// Creates a weighted network representation of a temporal network by aggregating edge occurences
        /// (and thus discarding information on the temporal ordering of edges)
        /// </summary>
        /// <param name="temp_net">he temporal network that shall be aggregated</param>
        /// <returns>An instance of a weighted aggregate network</returns>
        public static WeightedNetwork FromTemporalNetwork(TemporalNetwork temp_net)
        {
            WeightedNetwork weighted_net = new WeightedNetwork();

            foreach (var t in temp_net.Keys)
            {
                foreach (Tuple <string, string> edge in temp_net[t])
                {
                    weighted_net.AddEdge(edge.Item1, edge.Item2);
                }
            }
            return(weighted_net);
        }
Example #2
0
        /// <summary>
        /// This methods extracts all two paths from the sequence of edges in the temporal network (two-paths according to eq. (1) of the paper).
        /// It will also extract the correct (statistical) weights for both the two paths and the edges in the aggregate network.
        /// After this method returns, the weighted TwoPaths list as well as the weighted AggregateNetwork are available.
        /// If an explicit call to preprocess is ommitted, the preprocessing will be triggered whenever the AggregateNetwork or the TwoPaths dictionary
        /// is used for the first time. Changing the temporal network (i.e. adding or removing and edge) will invalidate both, so this method has to be called
        /// again.
        /// </summary>
        /// <seealso cref="TwoPathsByNode"/>
        /// <seealso cref="AggregateNetwork"/>
        public void ReduceToTwoPaths()
        {
            _twoPathsByNode      = new Dictionary <string, Dictionary <int, List <Tuple <string, string> > > >();
            _twoPathWeights      = new Dictionary <string, double>();
            _twoPathsByStartTime = new Dictionary <int, List <string> >();
            var two_path_edges = new Dictionary <int, List <Tuple <string, string> > >();

            int prev_t = -1;

            var ordered_time = Keys.OrderBy(k => k, new CompareInts());

            // Walk through time ...
            foreach (int t in ordered_time)
            {
                if (prev_t == -1)
                {
                    prev_t = t; // We skip the first time step and just set the prev_t index ...
                }
                else
                {
                    // N.B.: Only two-paths consisting of edges in time steps immediately following each other are found
                    // N.B.: We also account for multiple edges happening at the same time, i.e. multiple two-paths can pass through a node at a given time t!
                    // N.B.: For three consecutive edges (a,b), (b,c), (c,d) , two two-paths (a,b,c) and (b,c,d) will be found
                    foreach (var in_edge in this[prev_t])
                    {
                        foreach (var out_edge in this[t])
                        {
                            // In this case, we found the two_path (in_edge) -> (out_edge) = (s,v) -> (v,d)
                            if (in_edge.Item2 == out_edge.Item1)
                            {
                                // Use notation from the paper
                                string s = in_edge.Item1;
                                string v = in_edge.Item2;
                                string d = out_edge.Item2;

                                string two_path = s + "," + v + "," + d;

                                double indeg_v  = 0d;
                                double outdeg_v = 0d;

                                indeg_v = (from x in this[prev_t].AsParallel() where x.Item2 == v select x).Count();

                                //foreach (var edge in this[prev_t])
                                //   if (edge.Item2 == v)
                                //       indeg_v++;

                                outdeg_v = (from x in this[t].AsParallel() where x.Item1 == v select x).Count();

                                //foreach (var edge in this[t])
                                //   if (edge.Item1 == v)
                                //      outdeg_v++;

                                if (!_twoPathWeights.ContainsKey(two_path))
                                {
                                    _twoPathWeights[two_path] = 0d;
                                }

                                _twoPathWeights[two_path] += 1d / (indeg_v * outdeg_v);

                                if (!two_path_edges.ContainsKey(prev_t))
                                {
                                    two_path_edges[prev_t] = new List <Tuple <string, string> >();
                                }
                                if (!two_path_edges.ContainsKey(t))
                                {
                                    two_path_edges[t] = new List <Tuple <string, string> >();
                                }

                                // Important: In the reduced temporal network, we only use edges belonging to two paths. Each edge is added only once,
                                // even if it belongs to several two paths (this is the case for continued two paths as well as for two paths with multiple edges
                                // in one time step
                                if (!two_path_edges[prev_t].Contains(in_edge))
                                {
                                    two_path_edges[prev_t].Add(in_edge);
                                }
                                if (!two_path_edges[t].Contains(out_edge))
                                {
                                    two_path_edges[t].Add(out_edge);
                                }

                                // Add the identified two paths to the list of two paths passing through v at time t
                                if (!_twoPathsByNode.ContainsKey(v))
                                {
                                    _twoPathsByNode[v] = new Dictionary <int, List <Tuple <string, string> > >();
                                }
                                if (!_twoPathsByNode[v].ContainsKey(t))
                                {
                                    _twoPathsByNode[v][t] = new List <Tuple <string, string> >();
                                }

                                if (!_twoPathsByStartTime.ContainsKey(prev_t))
                                {
                                    _twoPathsByStartTime[prev_t] = new List <string>();
                                }

                                _twoPathsByNode[v][t].Add(new Tuple <string, string>(s, d));
                                _twoPathsByStartTime[prev_t].Add(s + "," + v + "," + d);
                            }
                        }
                    }
                    prev_t = t;
                }
            }

            // Replace the edges of the temporal network by those contributing to two paths
            if (_stripEdges)
            {
                this.Clear();
                foreach (int t in two_path_edges.Keys)
                {
                    this[t] = two_path_edges[t];
                }
            }

            // Build the aggregate networks with the correct weights ...
            _cachedWeightedNetwork            = new WeightedNetwork();
            _cachedWeightedNetworkSecondOrder = new WeightedNetwork();

            foreach (var two_path in _twoPathWeights.Keys)
            {
                string[] split = two_path.Split(',');
                _cachedWeightedNetwork.AddEdge(split[0], split[1], EdgeType.Directed, _twoPathWeights[two_path]);
                _cachedWeightedNetwork.AddEdge(split[1], split[2], EdgeType.Directed, _twoPathWeights[two_path]);

                _cachedWeightedNetworkSecondOrder.AddEdge(string.Format("({0};{1})", split[0], split[1]), string.Format("({0};{1})", split[1], split[2]), EdgeType.Directed, _twoPathWeights[two_path]);
            }

            foreach (string v in _cachedWeightedNetwork.Vertices)
            {
                if (!_twoPathsByNode.ContainsKey(v))
                {
                    _twoPathsByNode[v] = new Dictionary <int, List <Tuple <string, string> > >();
                }
            }
        }