use of com.carrotsearch.hppc.IntArrayList in project graphhopper by graphhopper.
the class PrepareRoutingSubnetworks method doWork.
public void doWork() {
if (minNetworkSize <= 0 && minOneWayNetworkSize <= 0)
return;
int unvisitedDeadEnds = 0;
for (FlagEncoder encoder : encoders) {
// mark edges for one vehicle as inaccessible
PrepEdgeFilter filter = new PrepEdgeFilter(encoder);
if (minOneWayNetworkSize > 0)
unvisitedDeadEnds += removeDeadEndUnvisitedNetworks(filter);
List<IntArrayList> components = findSubnetworks(filter);
keepLargeNetworks(filter, components);
subnetworks = Math.max(components.size(), subnetworks);
logger.info(components.size() + " subnetworks found for " + encoder + ", " + Helper.getMemInfo());
}
markNodesRemovedIfUnreachable();
logger.info("optimize to remove subnetworks (" + subnetworks + "), " + "unvisited-dead-end-nodes (" + unvisitedDeadEnds + "), " + "maxEdges/node (" + maxEdgesPerNode.get() + ")");
ghStorage.optimize();
}
use of com.carrotsearch.hppc.IntArrayList in project graphhopper by graphhopper.
the class PrepareRoutingSubnetworks method removeDeadEndUnvisitedNetworks.
/**
* This method removes networks that will be never be visited by this filter. See #235 for
* example, small areas like parking lots are sometimes connected to the whole network through a
* one-way road. This is clearly an error - but is causes the routing to fail when a point gets
* connected to this small area. This routine removes all these networks from the graph.
* <p>
*
* @return number of removed edges
*/
int removeDeadEndUnvisitedNetworks(final PrepEdgeFilter bothFilter) {
StopWatch sw = new StopWatch(bothFilter.getEncoder() + " findComponents").start();
final EdgeFilter outFilter = new DefaultEdgeFilter(bothFilter.getEncoder(), false, true);
// partition graph into strongly connected components using Tarjan's algorithm
TarjansSCCAlgorithm tarjan = new TarjansSCCAlgorithm(ghStorage, outFilter, true);
List<IntArrayList> components = tarjan.findComponents();
logger.info(sw.stop() + ", size:" + components.size());
return removeEdges(bothFilter, components, minOneWayNetworkSize);
}
use of com.carrotsearch.hppc.IntArrayList in project graphhopper by graphhopper.
the class PrepareRoutingSubnetworks method findSubnetworks.
/**
* This method finds the double linked components according to the specified filter.
*/
List<IntArrayList> findSubnetworks(PrepEdgeFilter filter) {
final FlagEncoder encoder = filter.getEncoder();
final EdgeExplorer explorer = ghStorage.createEdgeExplorer(filter);
int locs = ghStorage.getNodes();
List<IntArrayList> list = new ArrayList<IntArrayList>(100);
final GHBitSet bs = new GHBitSetImpl(locs);
for (int start = 0; start < locs; start++) {
if (bs.contains(start))
continue;
final IntArrayList intList = new IntArrayList(20);
list.add(intList);
new BreadthFirstSearch() {
int tmpCounter = 0;
@Override
protected GHBitSet createBitSet() {
return bs;
}
@Override
protected final boolean goFurther(int nodeId) {
if (tmpCounter > maxEdgesPerNode.get())
maxEdgesPerNode.set(tmpCounter);
tmpCounter = 0;
intList.add(nodeId);
return true;
}
@Override
protected final boolean checkAdjacent(EdgeIteratorState edge) {
if (encoder.isForward(edge.getFlags()) || encoder.isBackward(edge.getFlags())) {
tmpCounter++;
return true;
}
return false;
}
}.start(explorer, start);
intList.trimToSize();
}
return list;
}
use of com.carrotsearch.hppc.IntArrayList in project graphhopper by graphhopper.
the class PrepareRoutingSubnetworks method removeEdges.
/**
* This method removes the access to edges available from the nodes contained in the components.
* But only if a components' size is smaller then the specified min value.
* <p>
*
* @return number of removed edges
*/
int removeEdges(final PrepEdgeFilter bothFilter, List<IntArrayList> components, int min) {
// remove edges determined from nodes but only if less than minimum size
FlagEncoder encoder = bothFilter.getEncoder();
EdgeExplorer explorer = ghStorage.createEdgeExplorer(bothFilter);
int removedEdges = 0;
for (IntArrayList component : components) {
removedEdges += removeEdges(explorer, encoder, component, min);
}
return removedEdges;
}
use of com.carrotsearch.hppc.IntArrayList in project graphhopper by graphhopper.
the class TarjansSCCAlgorithm method strongConnect.
/**
* Find all components reachable from firstNode, add them to 'components'
* <p>
*
* @param firstNode start search of SCC at this node
*/
private void strongConnect(int firstNode) {
final Stack<TarjanState> stateStack = new Stack<TarjanState>();
stateStack.push(TarjanState.startState(firstNode));
// nextState label is equivalent to the function entry point in the recursive Tarjan's algorithm.
nextState: while (!stateStack.empty()) {
TarjanState state = stateStack.pop();
final int start = state.start;
final EdgeIterator iter;
if (state.isStart()) {
// We're traversing a new node 'start'. Set the depth index for this node to the smallest unused index.
nodeIndex[start] = index;
nodeLowLink[start] = index;
index++;
nodeStack.addLast(start);
onStack.add(start);
iter = graph.createEdgeExplorer(edgeFilter).setBaseNode(start);
} else {
// We're resuming iteration over the next child of 'start', set lowLink as appropriate.
iter = state.iter;
int prevConnectedId = iter.getAdjNode();
nodeLowLink[start] = Math.min(nodeLowLink[start], nodeLowLink[prevConnectedId]);
}
// a successor with a lower nodeLowLink.
while (iter.next()) {
int connectedId = iter.getAdjNode();
if (ignoreSet.contains(start))
continue;
if (nodeIndex[connectedId] == 0) {
// Push resume and start states onto state stack to continue our DFS through the graph after the jump.
// Ideally we'd just call strongConnectIterative(connectedId);
stateStack.push(TarjanState.resumeState(start, iter));
stateStack.push(TarjanState.startState(connectedId));
continue nextState;
} else if (onStack.contains(connectedId)) {
nodeLowLink[start] = Math.min(nodeLowLink[start], nodeIndex[connectedId]);
}
}
// Add all nodes higher up on nodeStack to this component.
if (nodeIndex[start] == nodeLowLink[start]) {
IntArrayList component = new IntArrayList();
int node;
while ((node = nodeStack.removeLast()) != start) {
component.add(node);
onStack.remove(node);
}
component.add(start);
component.trimToSize();
onStack.remove(start);
components.add(component);
}
}
}
Aggregations