Esempio n. 1
0
        public void NegativeModularity()
        {
            var N = NetworkHelper.InitBarabasi();
            var A = N.Actors;
            var C = A.Select(a => new Community(a)).ToList();
            var M = Modularity.Compute(N, C);

            Assert.Equal(-0.12, Math.Round(M, 2));
        }
Esempio n. 2
0
        public void SingleCommunity()
        {
            var N = NetworkHelper.InitBarabasi();
            var A = N.Actors;
            var C = new List <Community>
            {
                new Community(A),
            };
            var M = Modularity.Compute(N, C);

            Assert.Equal(0.0, M);
        }
Esempio n. 3
0
        public void SuboptimalParition()
        {
            var N = NetworkHelper.InitBarabasi();
            var A = N.Actors;
            var C = new List <Community>
            {
                new Community(A[0], A[1], A[2]),
                new Community(A[3], A[4], A[5], A[6], A[7], A[8])
            };
            var M = Modularity.Compute(N, C);

            Assert.Equal(0.22, Math.Round(M, 2));
        }
Esempio n. 4
0
        public void Zero()
        {
            for (var i = 0; i < 10; i++)
            {
                var network     = new MNCD.Generators.CompleteGraphGenerator().Generate(2 + i);
                var communities = new List <Community> {
                    new Community(network.Actors)
                };
                var modularity = Modularity.Compute(network, communities);

                Assert.Equal(0.0, modularity);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Computes communities hierarchy.
        /// </summary>
        /// <param name="inputNetwork">Input network.</param>
        /// <returns>Hierarchy of communities and it's modularities.</returns>
        public List <(double modularity, List <Community> communities)> GetHierarchy(Network inputNetwork)
        {
            if (inputNetwork.LayerCount > 1)
            {
                throw new ArgumentException("Louvain works only on single layered networks.");
            }

            var network = inputNetwork;
            List <Community> communities;
            Dictionary <Actor, Community>     actorToCommunity;
            Dictionary <Actor, List <Actor> > actorToActors = null;

            var hierarchy = new List <(double modularity, List <Community> communities)>();

            while (true)
            {
                (communities, actorToCommunity) = PhaseOne(network);

                var com = communities;
                if (actorToActors != null)
                {
                    var original = new List <Community>();
                    foreach (var c in communities)
                    {
                        var actors = c.Actors.SelectMany(a => actorToActors[a]);
                        original.Add(new Community(actors));
                    }

                    com = original;
                }

                com = com.Where(c => c.Size > 0).ToList();
                hierarchy.Add((Modularity.Compute(inputNetwork, com), com));

                (network, actorToActors) = PhaseTwo(network, communities, actorToCommunity);

                var edges = network.FirstLayer.Edges;
                if (network.ActorCount == 1 ||
                    edges.Count == 0 ||
                    (edges.Count == 1 && edges.Any(e => e.From == e.To)))
                {
                    break;
                }
            }

            return(hierarchy);
        }
Esempio n. 6
0
        /// <summary>
        /// Phase one of louvain.
        /// </summary>
        /// <param name="network">Network.</param>
        /// <returns>list of communities and mapping of actor to community.</returns>
        internal (List <Community>, Dictionary <Actor, Community>) PhaseOne(Network network)
        {
            var actorToCommunity = network.Actors
                                   .ToDictionary(a => a, a => new Community(a));
            var communities       = actorToCommunity.Values.ToList();
            var actorToNeighbours = network.FirstLayer.GetNeighboursDict();

            // First Phase - Local Optimum
            var change     = true;
            var iterations = 0;

            while (change && iterations < 1000)
            {
                iterations++;
                change = false;

                foreach (var actor in network.Actors)
                {
                    if (!actorToNeighbours.ContainsKey(actor))
                    {
                        continue;
                    }

                    var ac            = actorToCommunity[actor];
                    var mc            = Modularity.Compute(network, communities);
                    var maxModularity = mc;
                    var com           = ac;

                    foreach (var neighbour in actorToNeighbours[actor])
                    {
                        var nc = actorToCommunity[neighbour];

                        if (ac == nc)
                        {
                            continue;
                        }

                        ac.Actors.Remove(actor);
                        nc.Actors.Add(actor);

                        var comms = communities.Where(c => c.Size > 0).ToList();
                        var nm    = Modularity.Compute(network, comms);

                        if (nm > maxModularity)
                        {
                            maxModularity = nm;
                            com           = nc;
                        }

                        ac.Actors.Add(actor);
                        nc.Actors.Remove(actor);
                    }

                    if (maxModularity > mc)
                    {
                        change = true;
                        ac.Actors.Remove(actor);
                        com.Actors.Add(actor);
                        actorToCommunity[actor] = com;
                    }
                }
            }

            return(communities, actorToCommunity);
        }