mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-15 06:49:56 +00:00
Improved mst graph generator
This commit is contained in:
1 parent
8563a7b21f
commit
acdbe2afef
1 file changed
+49
-26
+49
-26
@@ -2,46 +2,46 @@ package com.sap.sailing.windestimation.aggregator.msthmm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sse.common.Util.Triple;
|
||||
|
||||
public abstract class AbstractMstGraphGenerator<T> {
|
||||
|
||||
private List<NodeWithNeighbors<T>> nodes = new ArrayList<>();
|
||||
private final List<NodeWithNeighbors<T>> nodes;
|
||||
|
||||
private static final int MAX_DEPTH_FOR_DFS = 10;
|
||||
|
||||
public AbstractMstGraphGenerator() {
|
||||
this(new ArrayList<>());
|
||||
}
|
||||
|
||||
// for object cloning
|
||||
protected AbstractMstGraphGenerator(List<NodeWithNeighbors<T>> nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
public void addNode(T observation) {
|
||||
NodeWithNeighbors<T> newNode = new NodeWithNeighbors<>(observation);
|
||||
LinkedList<NodeWithDistance<T>> distancesFromOtherNodes = getDistancesFromNearestOtherNodes(observation);
|
||||
nodes.add(newNode);
|
||||
if (!distancesFromOtherNodes.isEmpty()) {
|
||||
Collections.sort(distancesFromOtherNodes);
|
||||
NodeWithDistance<T> closestNeighborWithDistance = distancesFromOtherNodes.removeFirst();
|
||||
NodeWithDistance<T> closestNeighborWithDistance = distancesFromOtherNodes.get(0);
|
||||
addEdge(newNode, closestNeighborWithDistance);
|
||||
optimizeEdges(newNode, distancesFromOtherNodes, closestNeighborWithDistance);
|
||||
}
|
||||
}
|
||||
|
||||
private void optimizeEdges(NodeWithNeighbors<T> newNode, List<NodeWithDistance<T>> distancesFromNewNodeToOtherNodes,
|
||||
NodeWithDistance<T> currentNeighborWithDistance) {
|
||||
NodeWithNeighbors<T> currentNeighborNode = currentNeighborWithDistance.getNodeWithNeighbors();
|
||||
List<NodeWithDistance<T>> neighborsOfCurrentNeighborNode = new ArrayList<>(currentNeighborNode.getNeighbors());
|
||||
for (NodeWithDistance<T> subNeighborWithDistance : neighborsOfCurrentNeighborNode) {
|
||||
NodeWithNeighbors<T> subNeighborNode = subNeighborWithDistance.getNodeWithNeighbors();
|
||||
if (subNeighborNode != newNode) {
|
||||
for (NodeWithDistance<T> candidate : distancesFromNewNodeToOtherNodes) {
|
||||
Triple<Double, NodeWithNeighbors<T>, NodeWithNeighbors<T>> canReachAndEdgeWithHighestDistance = canReach(
|
||||
candidate.getNodeWithNeighbors(), currentNeighborNode, newNode);
|
||||
if (canReachAndEdgeWithHighestDistance != null
|
||||
&& canReachAndEdgeWithHighestDistance.getA() > candidate.getDistance()) {
|
||||
removeEdge(canReachAndEdgeWithHighestDistance.getB(),
|
||||
canReachAndEdgeWithHighestDistance.getC());
|
||||
addEdge(newNode, candidate);
|
||||
optimizeEdges(newNode, distancesFromNewNodeToOtherNodes, candidate);
|
||||
}
|
||||
for (ListIterator<NodeWithDistance<T>> iterator = distancesFromOtherNodes.listIterator(1); iterator
|
||||
.hasNext();) {
|
||||
NodeWithDistance<T> otherCloseNeighbor = iterator.next();
|
||||
Triple<Double, NodeWithNeighbors<T>, NodeWithNeighbors<T>> canReachAndEdgeWithHighestDistance = canReach(
|
||||
otherCloseNeighbor.getNodeWithNeighbors(), newNode);
|
||||
if (canReachAndEdgeWithHighestDistance != null
|
||||
&& canReachAndEdgeWithHighestDistance.getA() > otherCloseNeighbor.getDistance()) {
|
||||
removeEdge(canReachAndEdgeWithHighestDistance.getB(), canReachAndEdgeWithHighestDistance.getC());
|
||||
addEdge(newNode, otherCloseNeighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,9 +72,8 @@ public abstract class AbstractMstGraphGenerator<T> {
|
||||
}
|
||||
|
||||
private Triple<Double, NodeWithNeighbors<T>, NodeWithNeighbors<T>> canReach(NodeWithNeighbors<T> nodeToReach,
|
||||
NodeWithNeighbors<T> nodeToStartFrom, NodeWithNeighbors<T> firstNodeOfPathToIgnore) {
|
||||
return canReach(nodeToReach, nodeToStartFrom, firstNodeOfPathToIgnore, 0,
|
||||
new Triple<>(0.0, nodeToReach, nodeToStartFrom));
|
||||
NodeWithNeighbors<T> nodeToStartFrom) {
|
||||
return canReach(nodeToReach, nodeToStartFrom, null, 0, new Triple<>(0.0, nodeToReach, nodeToStartFrom));
|
||||
}
|
||||
|
||||
private Triple<Double, NodeWithNeighbors<T>, NodeWithNeighbors<T>> canReach(NodeWithNeighbors<T> nodeToReach,
|
||||
@@ -106,6 +105,30 @@ public abstract class AbstractMstGraphGenerator<T> {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public List<NodeWithNeighbors<T>> getClonedNodes() {
|
||||
List<NodeWithNeighbors<T>> clonedNodes = new ArrayList<>(nodes.size());
|
||||
Map<NodeWithNeighbors<T>, NodeWithNeighbors<T>> existingToNewNodesMapping = new HashMap<>();
|
||||
for (NodeWithNeighbors<T> node : nodes) {
|
||||
NodeWithNeighbors<T> clonedNode = existingToNewNodesMapping.get(node);
|
||||
if (clonedNode == null) {
|
||||
clonedNode = new NodeWithNeighbors<T>(node.getObservation());
|
||||
existingToNewNodesMapping.put(node, clonedNode);
|
||||
}
|
||||
for (NodeWithDistance<T> neighborNodeWithDistance : node.getNeighbors()) {
|
||||
NodeWithNeighbors<T> neighborNode = neighborNodeWithDistance.getNodeWithNeighbors();
|
||||
NodeWithNeighbors<T> clonedNeighborNode = existingToNewNodesMapping.get(neighborNode);
|
||||
if (clonedNeighborNode == null) {
|
||||
clonedNeighborNode = new NodeWithNeighbors<T>(neighborNode.getObservation());
|
||||
existingToNewNodesMapping.put(neighborNode, clonedNeighborNode);
|
||||
}
|
||||
NodeWithDistance<T> clonedNeighborNodeWithDistance = new NodeWithDistance<>(clonedNeighborNode,
|
||||
neighborNodeWithDistance.getDistance());
|
||||
clonedNode.addNeighbor(clonedNeighborNodeWithDistance);
|
||||
}
|
||||
}
|
||||
return clonedNodes;
|
||||
}
|
||||
|
||||
protected static class NodeWithNeighbors<T> {
|
||||
private final List<NodeWithDistance<T>> neighbors = new ArrayList<>(2);
|
||||
private final T observation;
|
||||
|
||||
Reference in new issue
Block a user