From acdbe2afef6a1c7fcc015fe66154fc82681a6a04 Mon Sep 17 00:00:00 2001 From: Vladislav Chumak Date: Thu, 17 Jan 2019 12:59:08 +0100 Subject: [PATCH] Improved mst graph generator --- .../msthmm/AbstractMstGraphGenerator.java | 75 ++++++++++++------- 1 file changed, 49 insertions(+), 26 deletions(-) diff --git a/java/com.sap.sailing.windestimation/src/com/sap/sailing/windestimation/aggregator/msthmm/AbstractMstGraphGenerator.java b/java/com.sap.sailing.windestimation/src/com/sap/sailing/windestimation/aggregator/msthmm/AbstractMstGraphGenerator.java index b7cdbfea7b5..21e0082b796 100644 --- a/java/com.sap.sailing.windestimation/src/com/sap/sailing/windestimation/aggregator/msthmm/AbstractMstGraphGenerator.java +++ b/java/com.sap.sailing.windestimation/src/com/sap/sailing/windestimation/aggregator/msthmm/AbstractMstGraphGenerator.java @@ -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 { - private List> nodes = new ArrayList<>(); + private final List> nodes; private static final int MAX_DEPTH_FOR_DFS = 10; + public AbstractMstGraphGenerator() { + this(new ArrayList<>()); + } + + // for object cloning + protected AbstractMstGraphGenerator(List> nodes) { + this.nodes = nodes; + } + public void addNode(T observation) { NodeWithNeighbors newNode = new NodeWithNeighbors<>(observation); LinkedList> distancesFromOtherNodes = getDistancesFromNearestOtherNodes(observation); nodes.add(newNode); if (!distancesFromOtherNodes.isEmpty()) { Collections.sort(distancesFromOtherNodes); - NodeWithDistance closestNeighborWithDistance = distancesFromOtherNodes.removeFirst(); + NodeWithDistance closestNeighborWithDistance = distancesFromOtherNodes.get(0); addEdge(newNode, closestNeighborWithDistance); - optimizeEdges(newNode, distancesFromOtherNodes, closestNeighborWithDistance); - } - } - - private void optimizeEdges(NodeWithNeighbors newNode, List> distancesFromNewNodeToOtherNodes, - NodeWithDistance currentNeighborWithDistance) { - NodeWithNeighbors currentNeighborNode = currentNeighborWithDistance.getNodeWithNeighbors(); - List> neighborsOfCurrentNeighborNode = new ArrayList<>(currentNeighborNode.getNeighbors()); - for (NodeWithDistance subNeighborWithDistance : neighborsOfCurrentNeighborNode) { - NodeWithNeighbors subNeighborNode = subNeighborWithDistance.getNodeWithNeighbors(); - if (subNeighborNode != newNode) { - for (NodeWithDistance candidate : distancesFromNewNodeToOtherNodes) { - Triple, NodeWithNeighbors> 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> iterator = distancesFromOtherNodes.listIterator(1); iterator + .hasNext();) { + NodeWithDistance otherCloseNeighbor = iterator.next(); + Triple, NodeWithNeighbors> 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 { } private Triple, NodeWithNeighbors> canReach(NodeWithNeighbors nodeToReach, - NodeWithNeighbors nodeToStartFrom, NodeWithNeighbors firstNodeOfPathToIgnore) { - return canReach(nodeToReach, nodeToStartFrom, firstNodeOfPathToIgnore, 0, - new Triple<>(0.0, nodeToReach, nodeToStartFrom)); + NodeWithNeighbors nodeToStartFrom) { + return canReach(nodeToReach, nodeToStartFrom, null, 0, new Triple<>(0.0, nodeToReach, nodeToStartFrom)); } private Triple, NodeWithNeighbors> canReach(NodeWithNeighbors nodeToReach, @@ -106,6 +105,30 @@ public abstract class AbstractMstGraphGenerator { return nodes; } + public List> getClonedNodes() { + List> clonedNodes = new ArrayList<>(nodes.size()); + Map, NodeWithNeighbors> existingToNewNodesMapping = new HashMap<>(); + for (NodeWithNeighbors node : nodes) { + NodeWithNeighbors clonedNode = existingToNewNodesMapping.get(node); + if (clonedNode == null) { + clonedNode = new NodeWithNeighbors(node.getObservation()); + existingToNewNodesMapping.put(node, clonedNode); + } + for (NodeWithDistance neighborNodeWithDistance : node.getNeighbors()) { + NodeWithNeighbors neighborNode = neighborNodeWithDistance.getNodeWithNeighbors(); + NodeWithNeighbors clonedNeighborNode = existingToNewNodesMapping.get(neighborNode); + if (clonedNeighborNode == null) { + clonedNeighborNode = new NodeWithNeighbors(neighborNode.getObservation()); + existingToNewNodesMapping.put(neighborNode, clonedNeighborNode); + } + NodeWithDistance clonedNeighborNodeWithDistance = new NodeWithDistance<>(clonedNeighborNode, + neighborNodeWithDistance.getDistance()); + clonedNode.addNeighbor(clonedNeighborNodeWithDistance); + } + } + return clonedNodes; + } + protected static class NodeWithNeighbors { private final List> neighbors = new ArrayList<>(2); private final T observation;