Exemplo n.º 1
0
        public Vertex MergeVertices(int id1, int id2)
        {
            var v1 = Vertices.SingleOrDefault(e => e.Id == id1);
            var v2 = Vertices.SingleOrDefault(e => e.Id == id2);

            if (v1 == null)
            {
                throw new Exception($"Vertex '{id1}' not found");
            }
            if (v2 == null)
            {
                throw new Exception($"Vertex '{id2}' not found");
            }

            int maxId  = Vertices.Select(e => e.Id).Max();
            var merged = new Vertex(maxId + 1);

            // add all neighbors
            foreach (var neighbor in v1.Neighbors.ToList())
            {
                merged.AddNeighborBiDirection(neighbor);
            }
            foreach (var neighbor in v2.Neighbors.ToList())
            {
                merged.AddNeighborBiDirection(neighbor);
            }

            // remove old neighbor references from graph
            foreach (var neighbor in v1.Neighbors.ToList())
            {
                v1.RemoveNeighborBiDirection(neighbor);
            }
            foreach (var neighbor in v2.Neighbors.ToList())
            {
                v2.RemoveNeighborBiDirection(neighbor);
            }

            merged.IdsBeforeMerge.AddRange(v1.IdsBeforeMerge);
            merged.IdsBeforeMerge.AddRange(v2.IdsBeforeMerge);

            Vertices.Remove(v1);
            Vertices.Remove(v2);
            Vertices.Add(merged);

            return(merged);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Generate graph by Holme & Kim model
        /// </summary>
        /// <param name="n">Number of vertices</param>
        /// <param name="m0">Number of fundamental nodes</param>
        /// <param name="m">Number of edges for new created vertices</param>
        /// <para name="p">Probability of making a triad formation</para>
        /// <returns></returns>
        public Graph GenerateHolmeKimModel(int n, int m0, int m, double p)
        {
            var vertices = Enumerable.Range(0, m0).Select(id => new Vertex(id)).ToList();

            // create base graph (complete graph)
            for (int i = 0; i < m0; i++)
            {
                for (int j = 0; j < m0; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    vertices[i].AddNeighborBiDirection(vertices[j]);
                }
            }

            var vertexDegreeDistribution = new List <int>();

            foreach (var vertex in vertices)
            {
                for (int i = 0; i < vertex.Degree; i++)
                {
                    vertexDegreeDistribution.Add(vertex.Id);
                }
            }

            // add new nodes
            for (int i = m0; i < n; i++)
            {
                var vertex      = new Vertex(m0 + i + 1);
                var usedNodeIds = new List <int>();

                Vertex newNeighbor = null;
                for (int j = 0; j < m; j++)
                {
                    if (j == 0 || p < _random.NextDouble())
                    {
                        int randomIndex = _random.Next(vertexDegreeDistribution.Count - 1);
                        while (usedNodeIds.Contains(vertexDegreeDistribution[randomIndex]))
                        {
                            randomIndex = _random.Next(vertexDegreeDistribution.Count - 1);
                        }

                        newNeighbor = vertices.Single(e => e.Id == vertexDegreeDistribution[randomIndex]);
                        bool isAdded = newNeighbor.AddNeighborBiDirection(vertex);
                        usedNodeIds.Add(vertexDegreeDistribution[randomIndex]);
                    }
                    else
                    {
                        if (newNeighbor == null)
                        {
                            throw new Exception();
                        }
                        var possibleNeighborsToAdd = newNeighbor.Neighbors.Except(new[] { vertex }).ToList();
                        var otherNeighbor          = possibleNeighborsToAdd[_random.Next(possibleNeighborsToAdd.Count)];
                        vertex.AddNeighborBiDirection(otherNeighbor);
                    }
                }

                for (int j = 0; j < m; j++)
                {
                    vertexDegreeDistribution.Add(vertex.Id);
                    vertexDegreeDistribution.Add(vertex.Neighbors[j].Id);
                }

                vertices.Add(vertex);
            }

            return(new Graph(vertices));
        }