private double AddAttractionDirection(int index, ref Vector direction)
        {
            double       direction2 = 0.0;
            LinLogVertex vertex     = _vertices[index];

            foreach (LinLogEdge edge in vertex.Attractions)
            {
                // Avoid loop
                if (edge.Target == vertex)
                {
                    continue;
                }

                Vector attractionVector = edge.Target.Position - vertex.Position;
                double distance         = attractionVector.Length;
                if (distance <= 0)
                {
                    continue;
                }

                double tmp = edge.AttractionWeight * Math.Pow(distance, Parameters.AttractionExponent - 2);
                direction2 += tmp * Math.Abs(Parameters.AttractionExponent - 1);

                direction += (edge.Target.Position - vertex.Position) * tmp;
            }

            return(direction2);
        }
        private double GetRepulsionEnergy(int index, [CanBeNull] QuadTree quadTree)
        {
            if (quadTree is null || quadTree.Index == index || index >= _vertices.Length)
            {
                return(0.0);
            }

            LinLogVertex vertex = _vertices[index];

            double dist = (vertex.Position - quadTree.Position).Length;

            if (quadTree.Index < 0 && dist < 2 * quadTree.Width)
            {
                double energy = 0.0;
                foreach (QuadTree childTree in quadTree.Children)
                {
                    energy += GetRepulsionEnergy(index, childTree);
                }
                return(energy);
            }

            if (IsZero(Parameters.RepulsiveExponent))
            {
                return(-_repulsionMultiplier *vertex.RepulsionWeight *quadTree.Weight *Math.Log(dist));
            }

            return(-_repulsionMultiplier
                   * vertex.RepulsionWeight
                   * quadTree.Weight
                   * Math.Pow(dist, Parameters.RepulsiveExponent) / Parameters.RepulsiveExponent);
        }
        private double AddRepulsionDirection(int index, [CanBeNull] QuadTree quadTree, ref Vector direction)
        {
            LinLogVertex vertex = _vertices[index];

            if (quadTree is null || quadTree.Index == index || vertex.RepulsionWeight <= 0)
            {
                return(0.0);
            }

            Vector repulsionVector = quadTree.Position - vertex.Position;
            double distance        = repulsionVector.Length;

            if (quadTree.Index < 0 && distance < 2.0 * quadTree.Width)
            {
                double direction2 = 0.0;
                foreach (QuadTree childTree in quadTree.Children)
                {
                    direction2 += AddRepulsionDirection(index, childTree, ref direction);
                }
                return(direction2);
            }

            if (!IsZero(distance))
            {
                double tmp = _repulsionMultiplier
                             * vertex.RepulsionWeight
                             * quadTree.Weight
                             * Math.Pow(distance, Parameters.RepulsiveExponent - 2);
                direction -= repulsionVector * tmp;
                return(tmp * Math.Abs(Parameters.RepulsiveExponent - 1));
            }

            return(0.0);
        }
示例#4
0
        private void InitAlgorithm()
        {
            vertices = new LinLogVertex[VisitedGraph.VertexCount];

            var vertexMap = new Dictionary <TVertex, LinLogVertex>();

            //vertexek indexelése
            int i = 0;

            foreach (TVertex v in VisitedGraph.Vertices)
            {
                vertices[i] = new LinLogVertex
                {
                    Index           = i,
                    OriginalVertex  = v,
                    Attractions     = new LinLogEdge[VisitedGraph.Degree(v)],
                    RepulsionWeight = 0,
                    Position        = VertexPositions[v]
                };
                vertexMap[v] = vertices[i];
                i++;
            }

            //minden vertex-hez felépíti az attractionWeights, attractionIndexes,
            //és a repulsionWeights struktúrát, valamint átmásolja a pozícióját a VertexPositions-ból
            foreach (var v in vertices)
            {
                int attrIndex = 0;
                foreach (var e in VisitedGraph.InEdges(v.OriginalVertex))
                {
                    double weight = e is WeightedEdge <TVertex>?((e as WeightedEdge <TVertex>).Weight) : 1;
                    v.Attractions[attrIndex] = new LinLogEdge
                    {
                        Target           = vertexMap[e.Source],
                        AttractionWeight = weight
                    };
                    //TODO look at this line below
                    //v.RepulsionWeight += weight;
                    v.RepulsionWeight += 1;
                    attrIndex++;
                }

                foreach (var e in VisitedGraph.OutEdges(v.OriginalVertex))
                {
                    double weight = e is WeightedEdge <TVertex>?((e as WeightedEdge <TVertex>).Weight) : 1;
                    v.Attractions[attrIndex] = new LinLogEdge
                    {
                        Target           = vertexMap[e.Target],
                        AttractionWeight = weight
                    };
                    //v.RepulsionWeight += weight;
                    v.RepulsionWeight += 1;
                    attrIndex++;
                }

                v.RepulsionWeight = Math.Max(v.RepulsionWeight, Parameters.gravitationMultiplier);
            }

            repulsionMultiplier = ComputeRepulsionMultiplier();
        }
        private double GetGravitationEnergy(int index)
        {
            LinLogVertex vertex = _vertices[index];

            double distance = (vertex.Position - _barycenter).Length;

            return(Parameters.GravitationMultiplier
                   * _repulsionMultiplier
                   * Math.Max(vertex.RepulsionWeight, 1)
                   * Math.Pow(distance, Parameters.AttractionExponent) / Parameters.AttractionExponent);
        }
        private double AddGravitationDirection(int index, ref Vector direction)
        {
            LinLogVertex vertex            = _vertices[index];
            Vector       gravitationVector = _barycenter - vertex.Position;
            double       distance          = gravitationVector.Length;
            double       tmp = Parameters.GravitationMultiplier
                               * _repulsionMultiplier
                               * Math.Max(vertex.RepulsionWeight, 1)
                               * Math.Pow(distance, Parameters.AttractionExponent - 2);

            direction += gravitationVector * tmp;

            return(tmp * Math.Abs(Parameters.AttractionExponent - 1));
        }
        private void MoveNode([NotNull] QuadTree quadTree, int index)
        {
            LinLogVertex vertex    = _vertices[index];
            double       oldEnergy = GetEnergy(index, quadTree);

            // Compute direction of the move of the node
            GetDirection(index, quadTree, out Vector bestDirection);

            // Line search: compute length of the move
            Point oldPosition = vertex.Position;

            double bestEnergy   = oldEnergy;
            int    bestMultiple = 0;

            bestDirection /= 32;
            // Determine the best multiple (for little moves)
            for (int multiple = 32;
                 multiple >= 1 && (bestMultiple == 0 || bestMultiple / 2 == multiple);
                 multiple /= 2)
            {
                vertex.Position = oldPosition + bestDirection * multiple;
                double curEnergy = GetEnergy(index, quadTree);
                if (curEnergy < bestEnergy)
                {
                    bestEnergy   = curEnergy;
                    bestMultiple = multiple;
                }
            }

            // Try to determine a better multiple (for larger moves)
            for (int multiple = 64;
                 multiple <= 128 && bestMultiple == multiple / 2;
                 multiple *= 2)
            {
                vertex.Position = oldPosition + bestDirection * multiple;
                double curEnergy = GetEnergy(index, quadTree);
                if (curEnergy < bestEnergy)
                {
                    bestEnergy   = curEnergy;
                    bestMultiple = multiple;
                }
            }

            // Best move
            vertex.Position = oldPosition + bestDirection * bestMultiple;
            if (bestMultiple > 0)
            {
                quadTree.MoveNode(oldPosition, vertex.Position, vertex.RepulsionWeight);
            }
        }
        private void InitAlgorithm()
        {
            _vertices = new LinLogVertex[VisitedGraph.VertexCount];

            var verticesMap = new Dictionary <TVertex, LinLogVertex>();

            // Index vertices
            int i = 0;

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                _vertices[i] = new LinLogVertex(i, vertex, new LinLogEdge[VisitedGraph.Degree(vertex)])
                {
                    RepulsionWeight = 0,
                    Position        = VerticesPositions[vertex]
                };
                verticesMap[vertex] = _vertices[i];
                ++i;
            }

            // Compute best attraction weight and attraction index for each vertex
            foreach (LinLogVertex vertex in _vertices)
            {
                int attractionIndex = 0;
                foreach (TEdge edge in VisitedGraph.InEdges(vertex.OriginalVertex))
                {
                    var    weightedEdge = edge as WeightedEdge <TVertex>;
                    double weight       = weightedEdge?.Weight ?? 1;
                    vertex.Attractions[attractionIndex] = new LinLogEdge(verticesMap[edge.Source], weight);
                    // TODO update repulsion weight?
                    ++vertex.RepulsionWeight;
                    ++attractionIndex;
                }

                foreach (TEdge edge in VisitedGraph.OutEdges(vertex.OriginalVertex))
                {
                    var    weightedEdge = edge as WeightedEdge <TVertex>;
                    double weight       = weightedEdge?.Weight ?? 1;
                    vertex.Attractions[attractionIndex] = new LinLogEdge(verticesMap[edge.Target], weight);
                    ++vertex.RepulsionWeight;
                    ++attractionIndex;
                }

                vertex.RepulsionWeight = Math.Max(vertex.RepulsionWeight, Parameters.GravitationMultiplier);
            }

            _repulsionMultiplier = ComputeRepulsionMultiplier();
        }
        private double GetAttractionEnergy(int index)
        {
            double       energy = 0.0;
            LinLogVertex vertex = _vertices[index];

            foreach (LinLogEdge edge in vertex.Attractions)
            {
                if (edge.Target == vertex)
                {
                    continue;
                }

                double distance = (edge.Target.Position - vertex.Position).Length;
                energy += edge.AttractionWeight * Math.Pow(distance, Parameters.AttractionExponent) / Parameters.AttractionExponent;
            }

            return(energy);
        }
示例#10
0
        private void InitAlgorithm()
        {
            vertices = new LinLogVertex[graph.nodes.Count];
            var vertexMap = new Dictionary <Representation.node, LinLogVertex>();
            int i         = 0;

            foreach (Representation.node v in graph.nodes)
            {
                vertices[i] = new LinLogVertex
                {
                    Index           = i,
                    OriginalVertex  = v,
                    Attractions     = new LinLogEdge[v.degree],
                    RepulsionWeight = 0,
                    Position        = VertexPositions[v]
                };
                vertexMap[v] = vertices[i];
                i++;
            }
            backgroundWorker.ReportProgress(40);
            if (backgroundWorker.CancellationPending)
            {
                return;
            }
            //minden vertex-hez felépíti az attractionWeights, attractionIndexes,
            //és a repulsionWeights struktúrát, valamint átmásolja a pozícióját a VertexPositions-ból
            foreach (var v in vertices)
            {
                int attrIndex = 0;
                foreach (var e in v.OriginalVertex.arcsTo)
                {
                    double weight = 1;
                    v.Attractions[attrIndex] = new LinLogEdge
                    {
                        Target           = vertexMap[e.From],
                        AttractionWeight = weight
                    };
                    v.RepulsionWeight += 1;
                    attrIndex++;
                }

                foreach (var e in v.OriginalVertex.arcsFrom)
                {
                    double weight = 1;
                    v.Attractions[attrIndex] = new LinLogEdge
                    {
                        Target           = vertexMap[e.To],
                        AttractionWeight = weight
                    };

                    v.RepulsionWeight += 1;
                    attrIndex++;
                }
                v.RepulsionWeight = Math.Max(v.RepulsionWeight, gravitationMultiplier);
            }
            backgroundWorker.ReportProgress(50);
            if (backgroundWorker.CancellationPending)
            {
                return;
            }
            repulsionMultiplier = ComputeRepulsionMultiplier();
        }
 public LinLogEdge([NotNull] LinLogVertex target, double weight)
 {
     Target           = target;
     AttractionWeight = weight;
 }