/** Build the weight table, parallelized according to the number of processors */ public void buildTable() { ArrayList<TransitStop> stopVertices; LOG.debug("Number of vertices: " + g.getVertices().size()); stopVertices = new ArrayList<TransitStop>(); for (Vertex gv : g.getVertices()) if (gv instanceof TransitStop) stopVertices.add((TransitStop) gv); int nStops = stopVertices.size(); stopIndices = new IdentityHashMap<Vertex, Integer>(nStops); for (int i = 0; i < nStops; i++) stopIndices.put(stopVertices.get(i), i); LOG.debug("Number of stops: " + nStops); table = new float[nStops][nStops]; for (float[] row : table) Arrays.fill(row, Float.POSITIVE_INFINITY); LOG.debug("Performing search at each transit stop."); int nThreads = Runtime.getRuntime().availableProcessors(); LOG.debug("number of threads: " + nThreads); ArrayBlockingQueue<Runnable> taskQueue = new ArrayBlockingQueue<Runnable>(nStops); ThreadPoolExecutor threadPool = new ThreadPoolExecutor(nThreads, nThreads, 10, TimeUnit.SECONDS, taskQueue); GenericObjectPool heapPool = new GenericObjectPool(new PoolableBinHeapFactory<State>(g.getVertices().size()), nThreads); // make one heap and recycle it TraverseOptions options = new TraverseOptions(); options.speed = maxWalkSpeed; final double MAX_WEIGHT = 60 * 60 * options.walkReluctance; final double OPTIMISTIC_BOARD_COST = options.boardCost; // create a task for each transit stop in the graph ArrayList<Callable<Void>> tasks = new ArrayList<Callable<Void>>(); for (TransitStop origin : stopVertices) { SPTComputer task = new SPTComputer(heapPool, options, MAX_WEIGHT, OPTIMISTIC_BOARD_COST, origin); tasks.add(task); } try { // invoke all of tasks. threadPool.invokeAll(tasks); threadPool.shutdown(); } catch (InterruptedException e) { throw new RuntimeException(e); } floyd(); }
public void testTriangle() { Coordinate c1 = new Coordinate(-122.575033, 45.456773); Coordinate c2 = new Coordinate(-122.576668, 45.451426); Vertex v1 = new Vertex("v1", c1, null); Vertex v2 = new Vertex("v2", c2, null); GeometryFactory factory = new GeometryFactory(); LineString geometry = factory.createLineString(new Coordinate[] {c1, c2}); double length = 650.0; PlainStreetEdge testStreet = new PlainStreetEdge( v1, v2, geometry, "Test Lane", length, StreetTraversalPermission.ALL, false); testStreet.setBicycleSafetyEffectiveLength(length * 0.74); // a safe street Coordinate[] profile = new Coordinate[] { new Coordinate(0, 0), // slope = 0.1 new Coordinate(length / 2, length / 20.0), new Coordinate(length, 0) // slope = -0.1 }; PackedCoordinateSequence elev = new PackedCoordinateSequence.Double(profile); testStreet.setElevationProfile(elev); double trueLength = ElevationUtils.getLengthMultiplierFromElevation(elev) * length; testStreet.setSlopeSpeedEffectiveLength(trueLength); // normalize length SlopeCosts costs = ElevationUtils.getSlopeCosts(elev, "test"); TraverseOptions options = new TraverseOptions(TraverseMode.BICYCLE); options.optimizeFor = OptimizeType.TRIANGLE; options.speed = 6.0; options.walkReluctance = 1; options.setTriangleSafetyFactor(0); options.setTriangleSlopeFactor(0); options.setTriangleTimeFactor(1); State startState = new State(v1, options); State result = testStreet.traverse(startState); double timeWeight = result.getWeight(); double expectedSpeedWeight = trueLength / options.speed; assertEquals(expectedSpeedWeight, timeWeight); options.setTriangleSafetyFactor(0); options.setTriangleSlopeFactor(1); options.setTriangleTimeFactor(0); startState = new State(v1, options); result = testStreet.traverse(startState); double slopeWeight = result.getWeight(); assertTrue(length * 1.5 / options.speed < slopeWeight); assertTrue(length * 1.5 * 10 / options.speed > slopeWeight); options.setTriangleSafetyFactor(1); options.setTriangleSlopeFactor(0); options.setTriangleTimeFactor(0); startState = new State(v1, options); result = testStreet.traverse(startState); double safetyWeight = result.getWeight(); double slopeSafety = costs.slopeSafetyCost; double expectedSafetyWeight = (trueLength * 0.74 + slopeSafety) / options.speed; assertTrue(expectedSafetyWeight - safetyWeight < 0.00001); final double ONE_THIRD = 1 / 3.0; options.setTriangleSafetyFactor(ONE_THIRD); options.setTriangleSlopeFactor(ONE_THIRD); options.setTriangleTimeFactor(ONE_THIRD); startState = new State(v1, options); result = testStreet.traverse(startState); double averageWeight = result.getWeight(); assertTrue( Math.abs( safetyWeight * ONE_THIRD + slopeWeight * ONE_THIRD + timeWeight * ONE_THIRD - averageWeight) < 0.00000001); }