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); }
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); }
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; }