/// <summary>
        /// Utility method, for creating new layer in the multilayer network.
        /// </summary>
        /// <param name="mnet">Multilayer network.</param>
        /// <param name="newLayerName">Name of the new layer.</param>
        /// <param name="layers">Layers of the network.</param>
        /// <param name="forceDirected">True if new edges should be directed, false if not.</param>
        /// <param name="forceActors">True if all actors should be on the new layer, false if not.</param>
        /// <returns>Newly created layer.</returns>
        private Layer createLayer(MultilayerNetwork mnet, string newLayerName, HashSet <Layer> layers,
                                  bool forceDirected, bool forceActors)
        {
            var directed = forceDirected;

            // Check if there are any directed layers, if YES, then new layer will be directed as well.
            if (!directed)
            {
                foreach (var layer1 in layers)
                {
                    foreach (var layer2 in layers)
                    {
                        if (mnet.IsDirected(layer1, layer2))
                        {
                            directed = true;
                            break;
                        }
                    }

                    if (directed)
                    {
                        break;
                    }
                }
            }

            var dir      = directed ? EdgeDirectionality.Directed : EdgeDirectionality.Undirected;
            var newLayer = mnet.AddLayer(newLayerName, dir);

            if (newLayer == null)
            {
                throw new ArgumentException("Layer " + newLayerName + " already exists.");
            }

            if (forceActors)
            {
                foreach (var actor in mnet.GetActors())
                {
                    mnet.AddNode(actor, newLayer);
                }
            }
            else
            {
                foreach (var layer in layers)
                {
                    foreach (var node in mnet.GetNodes(layer))
                    {
                        mnet.AddNode(node.Actor, newLayer);
                    }
                }
            }

            return(newLayer);
        }
예제 #2
0
        // Do for each layer random walk for every pair of nodes on the layer.
        // Average the value over all possible starting layers for the actor.

        /// <summary>
        /// Returns dictionary, where actors are keys and random walk betweenness centrality is their value.
        /// </summary>
        /// <param name="mnet">Multilayer network.</param>
        /// <param name="jump">Jump probability for random walker, default value is 0.2.</param>
        /// <param name="transitions">Matrix of transition probabilities between layers. Default is uniform for each pair of layers.</param>
        /// <returns>Dictionary, where actors are keys and random walk betweenness centrality is their value.</returns>
        public ConcurrentDictionary <Actor, int> RandomWalkBetweenness(MultilayerNetwork mnet, double jump = 0.2, double[][] transitions = null)
        {
            // If not set transitions, use uniform probability for every layer.
            transitions = new double[mnet.Layers.Count][];

            for (int i = 0; i < mnet.Layers.Count; i++)
            {
                transitions[i] = new double[mnet.Layers.Count];
                for (int j = 0; j < transitions[i].Length; j++)
                {
                    transitions[i][j] = 1.0 / transitions[i].Length;
                }
            }

            var rw = new Walker(mnet, jump, transitions);

            // Number of random walks passing through given actor.
            var actorRandomWalkCount = new ConcurrentDictionary <Actor, int>();

            //foreach (var a in mnet.GetActors())
            Parallel.ForEach(mnet.GetActors(), (a) =>
            {
                actorRandomWalkCount.TryAdd(a, 0);
            });

            // Do random walk between every pair of nodes.
            // Average it over the layers.
            var nodes = mnet.GetNodes().ToArray();

            for (int i = 0; i < nodes.Length - 1; i++)
            {
                //for (int j = i + 1; j < nodes.Length; j++)
                Parallel.For(i + 1, nodes.Length, j =>
                {
                    RandomWalkActors(rw, nodes[i], nodes[j], ref actorRandomWalkCount);
                });
            }


            var temp = new ConcurrentDictionary <Actor, int>(actorRandomWalkCount);

            // Average it - divide by number of nodes with the corresponding actor.
            //foreach (var a in temp.Keys)
            Parallel.ForEach(temp.Keys, (a) =>
            {
                if (mnet.NodesByActor.ContainsKey(a.Id))
                {
                    var nodesCount          = mnet.NodesByActor[a.Id].Count;
                    actorRandomWalkCount[a] = temp[a] / nodesCount;
                }
            });

            return(actorRandomWalkCount);
        }
예제 #3
0
        /// <summary>
        /// Moves the walker
        /// </summary>
        /// <returns>Node where walker moved onto.</returns>
        public Node Next()
        {
            if (mathUtils.Test(jump))
            {
                current    = Utils.Extensions.GetAtRandom(mnet.GetNodes());
                justJumped = true;
                noAction   = false;
            }
            else
            {
                Layer flattened   = mnet.GetLayer("flattenedNetwork");
                var   layerId     = layerIds[current.Layer.Id];
                var   layerIdTest = mathUtils.Test(transitions, layerId);
                var   newLayer    = mnet.GetLayers().Except(new HashSet <Layer>()
                {
                    flattened
                }).ElementAt(layerIdTest);

                if (current.Layer == newLayer)
                {
                    // Inside same layer.
                    var neigh = mnet.Neighbors(current, EdgeMode.Out);
                    if (neigh.Count == 0)
                    {
                        // Cant move.
                        // No action.
                        noAction = true;
                        return(current);
                    }

                    var rand = mathUtils.GetRandomInt(neigh.Count);
                    current    = neigh.ElementAt(rand);
                    justJumped = false;
                    noAction   = false;
                }
                else
                {
                    // Changing to another node with this actor.
                    var nextNode = mnet.GetNode(current.Actor, newLayer);
                    if (nextNode == null)
                    {
                        // No other nodes with this actor.
                        noAction = true;
                        return(current);
                    }

                    current    = nextNode;
                    justJumped = false;
                    noAction   = false;
                }
            }

            return(current);
        }
예제 #4
0
        /// <summary>
        /// Returns degree on provided layer.
        /// </summary>
        /// <param name="mnet">Multlayer network model.</param>
        /// <param name="actor">Actor.</param>
        /// <param name="layer">Single Layer.</param>
        /// <param name="edgeMode">In / Out / All, mode of edge.</param>
        /// <returns>Degree of the Actor.</returns>
        public int Degree(MultilayerNetwork mnet, Actor actor, Layer layer, EdgeMode edgeMode)
        {
            var degree = 0;

            // All nodes with this ACTOR.
            foreach (var node in mnet.GetNodes(actor))
            {
                // All neighbors of this NODE, with the correct edgeMode (In / Out / Or both).
                foreach (var neighbor in mnet.Neighbors(node, edgeMode))
                {
                    // We go through all his neighbors, and if the neighbor is on the provided layer
                    // we increase his degree by 1.
                    if (neighbor.Layer == layer)
                    {
                        degree += 1;
                    }
                }
            }

            return(degree);
        }
예제 #5
0
        private MathUtils mathUtils = MathUtils.Instance; //new MathUtils();


        #region Degree

        /// <summary>
        /// Returns degree of the actor on provided layers.
        /// </summary>
        /// <param name="mnet">Multilayer network model.</param>
        /// <param name="actor">Actor.</param>
        /// <param name="layers">HashSet of layers.</param>
        /// <param name="edgeMode">In / Out / All, mode of edge.</param>
        /// <returns>Degree of the Actor.</returns>
        public int Degree(MultilayerNetwork mnet, Actor actor, HashSet <Layer> layers, EdgeMode edgeMode)
        {
            var degree = 0;

            // All nodes with this ACTOR.
            foreach (var node in mnet.GetNodes(actor))
            {
                // All neighbors of this NODE, with the correct edgeMode (In / Out / Or both).
                foreach (var neighbor in mnet.Neighbors(node, edgeMode))
                {
                    // If there is a layer with this neighbor it means, that this NODE has this neighbor
                    // on this layer, so we increase his degree by 1.
                    if (layers.Contains(neighbor.Layer))
                    {
                        degree += 1;
                    }
                }
            }

            return(degree);
        }
예제 #6
0
        /// <summary>
        /// Returns neighbors of given actor on given layer with specific edgemode.
        /// </summary>
        /// <param name="mnet">Multilayer network model.</param>
        /// <param name="actor">Actor to get neighbors of.</param>
        /// <param name="layer">Layer to get neighbors on.</param>
        /// <param name="edgeMode">In/Out/InOut edges.</param>
        /// <returns>Neighbors of given actor on given layer with specific edgemode.</returns>
        private HashSet <Actor> Neighbors(MultilayerNetwork mnet, Actor actor, Layer layer, EdgeMode edgeMode = EdgeMode.InOut)
        {
            // Empty hashset to add checked actors.
            var neighbors = new HashSet <Actor>();

            // All nodes with this ACTOR.
            foreach (var node in mnet.GetNodes(actor))
            {
                // All neighbors of this NODE, with the correct edgeMode (In / Out / Or both).
                foreach (var neighbor in mnet.Neighbors(node, edgeMode))
                {
                    // If there is a layer with this neighbor it means, that this NODE has this neighbor
                    // on this layer, so we increase his degree by 1 IF actor on this node is still available.
                    if (layer == neighbor.Layer)
                    {
                        neighbors.Add(neighbor.Actor);
                    }
                }
            }

            return(neighbors);
        }
예제 #7
0
        /// <summary>
        /// Returns dictionary, where actors are keys and their random walk closeness centrality is value.
        /// </summary>
        /// <param name="mnet">Multilayer network.</param>
        /// <param name="jump">Jump probability, default value is 0.2.</param>
        /// <param name="transitions">Matrix of transition probabilities between layers. Default is uniform for each pair of layers.</param>
        /// <returns>Dictionary, where actors are keys and their random walk closeness centrality is value.</returns>
        public ConcurrentDictionary <Actor, double> RandomWalkCloseness(MultilayerNetwork mnet, double jump = 0.2, double[][] transitions = null)
        {
            // If not set transitions, use uniform probability for every layer.
            transitions = new double[mnet.Layers.Count][];

            for (int i = 0; i < mnet.Layers.Count; i++)
            {
                transitions[i] = new double[mnet.Layers.Count];
                for (int j = 0; j < transitions[i].Length; j++)
                {
                    transitions[i][j] = 1.0 / transitions[i].Length;
                }
            }

            var rw = new Walker(mnet, jump, transitions);

            // Create adjacency matrix for actors.
            // Every actor has its Id.
            // First Id starts at 0.
            // Last Id is actors count - 1.
            var adjActors = new int[mnet.GetActors().Count][];

            for (int i = 0; i < mnet.Actors.Count; i++)
            {
                adjActors[i] = new int[mnet.Actors.Count];
            }

            // Traverse the matrix for every pair of nodes.
            var nodes = mnet.GetNodes().ToArray();

            for (int i = 0; i < nodes.Length - 1; i++)
            {
                //for (int j = i + 1; j < nodes.Length; j++)
                Parallel.For(i + 1, nodes.Length, (j) =>
                {
                    //Console.WriteLine(i + ":" + j);
                    // Do random walk from i to j.
                    // And save only the first walk length.
                    var walkLen = RandomWalkSteps(rw, nodes[i], nodes[j]);

                    // Use only first walk.
                    if (adjActors[nodes[i].Actor.Id][nodes[j].Actor.Id] == 0)
                    {
                        adjActors[nodes[i].Actor.Id][nodes[j].Actor.Id] = walkLen;
                        adjActors[nodes[j].Actor.Id][nodes[i].Actor.Id] = walkLen;
                    }
                });
            }

            var actorById = new ConcurrentDictionary <int, Actor>();

            //foreach (var actor in mnet.GetActors())
            Parallel.ForEach(mnet.GetActors(), (a) =>
            {
                actorById.TryAdd(a.Id, a);
            });

            // Actual Clonesess centrality.
            // Harmonic mean distance.
            var closenessByActor = new ConcurrentDictionary <Actor, double>();

            for (int i = 0; i < adjActors[0].Length; i++)
            {
                double sum = 0;
                //for (int j = 0; j < adjActors[0].Length; j++)
                Parallel.For(0, adjActors[0].Length, (j) =>
                {
                    if (i == j)
                    {
                        adjActors[i][j] = 0;
                    }
                    else
                    {
                        if (adjActors[i][j] != 0)
                        {
                            sum += 1.0 / adjActors[i][j];
                        }
                    }
                });

                double closeness = (1.0 / (adjActors[0].Length - 1)) * sum;
                closenessByActor[actorById[i]] = closeness;
            }

            return(closenessByActor);
        }
예제 #8
0
        /// <summary>
        /// Returns dictionary, where actors are keys and their occupation centrality is value.
        /// </summary>
        /// <param name="mnet">Multilayer network.</param>
        /// <param name="jump">Jump probability for random walker, default value is 0.2.</param>
        /// <param name="transitions">Matrix of transition probabilities between layers. Default is uniform for each pair of layers.</param>
        /// <param name="numSteps">Maximum number of steps, if not specified it is number of edges times 100.</param>
        /// <param name="initialNode">Starting node for the random walker.</param>
        /// <returns>Dictionary, where actors are keys and their occupation centrality is value.</returns>
        public Dictionary <Actor, int> Occupation(MultilayerNetwork mnet, double jump = 0.2, double[][] transitions = null, int numSteps = 0, Node initialNode = null)
        {
            // If not set number of steps, set default number of steps to 100 times number of edges.
            // This was used in the R library.
            if (numSteps == 0)
            {
                numSteps = mnet.Edges.Count * 100;
            }

            // If not set transitions, use uniform probability for every layer.
            transitions = new double[mnet.Layers.Count][];

            for (int i = 0; i < mnet.Layers.Count; i++)
            {
                transitions[i] = new double[mnet.Layers.Count];
                for (int j = 0; j < transitions[i].Length; j++)
                {
                    transitions[i][j] = 1.0 / transitions[i].Length;
                }
            }

            var rw = new Walker(mnet, jump, transitions);

            if (initialNode == null)
            {
                rw.SetInitialNode(mnet.GetNodes().FirstOrDefault());
            }
            else
            {
                rw.SetInitialNode(initialNode);
            }

            var occupation = new Dictionary <Actor, int>();

            var node = rw.Now();
            var flag = true;

            while (numSteps-- > 0)
            {
                if (flag)
                {
                    // Initial node.
                    flag = false;
                }
                else
                {
                    node = rw.Next();
                }

                if (!rw.Action())
                {
                    continue;
                }

                if (rw.Jumped())
                {
                    // Jumped to a new node - not counting.
                }
                else
                {
                    // If actor is not present yet.
                    if (!occupation.ContainsKey(node.Actor))
                    {
                        occupation.Add(node.Actor, 0);
                    }
                    // Then increase his occupancy.
                    occupation[node.Actor]++;
                }
            }

            return(occupation);
        }
예제 #9
0
        private IO io = IO.Instance; //new IO();
        public void TransformationTest()
        {
            var transform = new Transformation.Transformation();

            Console.WriteLine("Transformation test begin...");
            Console.WriteLine("Creating the network...");

            var mnet   = new MultilayerNetwork("Transformation Test");
            var a1     = mnet.AddActor("a1");
            var a2     = mnet.AddActor("a2");
            var a3     = mnet.AddActor("a3");
            var a4     = mnet.AddActor("a4");
            var a5     = mnet.AddActor("a5");
            var a6     = mnet.AddActor("a6");
            var i1     = mnet.AddActor("I1");
            var i2     = mnet.AddActor("I2");
            var i3     = mnet.AddActor("I3");
            var L1     = mnet.AddLayer("People 1", EdgeDirectionality.Undirected);
            var L2     = mnet.AddLayer("People 2", EdgeDirectionality.Undirected);
            var people = new HashSet <Layer> {
                L1, L2
            };
            var L3   = mnet.AddLayer("Institutions", EdgeDirectionality.Undirected);
            var a1l1 = mnet.AddNode(a1, L1);
            var a2l1 = mnet.AddNode(a2, L1);
            var a3l1 = mnet.AddNode(a3, L1);
            var a4l1 = mnet.AddNode(a4, L1);
            var a5l1 = mnet.AddNode(a5, L1);
            var a1l2 = mnet.AddNode(a1, L2);
            var a2l2 = mnet.AddNode(a2, L2);
            var a3l2 = mnet.AddNode(a3, L2);
            var a4l2 = mnet.AddNode(a4, L2);
            var a5l2 = mnet.AddNode(a5, L2);
            var i1l3 = mnet.AddNode(i1, L3);
            var i2l3 = mnet.AddNode(i2, L3);
            var i3l3 = mnet.AddNode(i3, L3);

            mnet.AddEdge(a1l1, a2l1);
            mnet.AddEdge(a1l1, a3l1);
            mnet.AddEdge(a1l2, a2l2);
            mnet.AddEdge(a3l2, a4l2);
            mnet.AddEdge(a1l2, i1l3);
            mnet.AddEdge(a2l2, i1l3);
            mnet.AddEdge(a2l2, i2l3);
            mnet.AddEdge(a3l2, i2l3);
            mnet.AddEdge(a4l2, i2l3);
            mnet.AddEdge(a5l2, i3l3);
            Console.WriteLine("Creating network end.");


            Console.WriteLine("Flattening L1 and L2 (unweighted, only existing actors)...");
            var f1 = transform.FlattenUnweighted(mnet, "flattened1", people, false, false);

            if (mnet.IsDirected(f1, f1))
            {
                Console.WriteLine("Layer should be undirected");
            }
            if (mnet.GetNodes(f1).Count != 5)
            {
                Console.WriteLine("Wrong number of nodes");
            }
            if (mnet.GetEdges(f1, f1).Count != 3)
            {
                Console.WriteLine("Wrong number of edges");
            }
            Console.WriteLine("Done! " + mnet.ToString());
            Console.WriteLine();

            Console.WriteLine("Flattening L1 and L2 (unweighted, all actors)...");
            var f2 = transform.FlattenUnweighted(mnet, "flattened2", people, false, true);

            if (mnet.IsDirected(f2, f2))
            {
                Console.WriteLine("Layer should be undirected");
            }
            if (mnet.GetNodes(f2).Count != 9)
            {
                Console.WriteLine("Wrong number of nodes, {0}\t != {1}", mnet.GetNodes(f2).Count, 9);
            }
            if (mnet.GetEdges(f2, f2).Count != 3)
            {
                Console.WriteLine("Wrong number of edges");
            }
            Console.WriteLine("Done! " + mnet.ToString());
            Console.WriteLine();



            Console.WriteLine("Transformation test end.");
            Console.ReadLine();
        }