private boolean isInDistanceInternal( int distance, NetworkNode from, NetworkNode to, TwoNetworkNodes cachePairKey) { if (from.equals(to)) return true; if (distance == 0) return false; if (SimpleNetwork.areNodesConnecting(from, to)) return true; // Breadth-first search of the network Set<NetworkNode> visitedNodes = Sets.newHashSet(); visitedNodes.add(from); Set<NetworkNode> networkingNodesToTest = Sets.newHashSet(); listConnectedNotVisitedNetworkingNodes(visitedNodes, from, networkingNodesToTest); int distanceSearched = 1; while (distanceSearched < distance) { distanceSearched++; for (NetworkNode nodeToTest : networkingNodesToTest) { if (SimpleNetwork.areNodesConnecting(nodeToTest, to)) { distanceCache.put(cachePairKey, distanceSearched); return true; } visitedNodes.add(nodeToTest); } Set<NetworkNode> nextNetworkingNodesToTest = Sets.newHashSet(); for (NetworkNode nodeToTest : networkingNodesToTest) listConnectedNotVisitedNetworkingNodes(visitedNodes, nodeToTest, nextNetworkingNodesToTest); networkingNodesToTest = nextNetworkingNodesToTest; } return false; }
@Override public int getDistance(NetworkNode from, NetworkNode to) { TwoNetworkNodes nodePair = new TwoNetworkNodes(from, to); final Integer cachedDistance = distanceCache.get(nodePair); if (cachedDistance != null) return cachedDistance; if ((!hasNetworkingNode(from) && !hasLeafNode(from)) || (!hasNetworkingNode(to) && !hasLeafNode(to))) throw new IllegalArgumentException("Cannot test nodes not in network"); if (from.equals(to)) return 0; if (SimpleNetwork.areNodesConnecting(from, to)) return 1; // Breadth-first search of the network Set<NetworkNode> visitedNodes = Sets.newHashSet(); visitedNodes.add(from); Set<NetworkNode> networkingNodesToTest = Sets.newHashSet(); listConnectedNotVisitedNetworkingNodes(visitedNodes, from, networkingNodesToTest); int distanceSearched = 1; while (networkingNodesToTest.size() > 0) { distanceSearched++; for (NetworkNode nodeToTest : networkingNodesToTest) { if (SimpleNetwork.areNodesConnecting(nodeToTest, to)) { distanceCache.put(new TwoNetworkNodes(from, to), distanceSearched); return distanceSearched; } visitedNodes.add(nodeToTest); } Set<NetworkNode> nextNetworkingNodesToTest = Sets.newHashSet(); for (NetworkNode nodeToTest : networkingNodesToTest) listConnectedNotVisitedNetworkingNodes(visitedNodes, nodeToTest, nextNetworkingNodesToTest); networkingNodesToTest = nextNetworkingNodesToTest; } return -1; }